Compare commits

..

1 Commits

Author SHA1 Message Date
AJ ONeal
5bfc166f1b docs(caddy): a few more updates 2022-10-21 22:34:40 +00:00
232 changed files with 1038 additions and 6306 deletions

View File

@@ -1,5 +1,5 @@
{
"trailingComma": "all",
"trailingComma": "none",
"tabWidth": 2,
"singleQuote": true,
"proseWrap": "always"

View File

@@ -45,7 +45,7 @@
<https://gist.github.com/nicerobot/53cee11ee0abbdc997661e65b348f375>
- Common exceptions:
```text
```txt
# We make use of `.` (source) to import without exports
SC2034: foo appears unused. Verify it or export it.
SC2154: var is referenced but not assigned.
@@ -94,15 +94,15 @@ The general format is `<type>(<package>): <description>`, using these _types_:
Try to write your commit messages (in the present tense) like this:
```text
```txt
fix(node): update install.sh (fix #200)
```
```text
```txt
feat(delta): add cheat sheet and install.sh
```
```text
```txt
docs(ssh-adduser): document that foo does bar
```

View File

@@ -14,7 +14,7 @@ function getAllReleases(request, formula) {
return request({
url: 'https://formulae.brew.sh/api/formula/' + formula + '.json',
fail: true, // https://git.coolaj86.com/coolaj86/request.js/issues/2
json: true,
json: true
})
.then(failOnBadStatus)
.then(function (resp) {
@@ -26,16 +26,16 @@ function getAllReleases(request, formula) {
return [
{
version: ver,
download: dl.replace(/{{ v }}/g, ver),
},
download: dl.replace(/{{ v }}/g, ver)
}
].concat(
resp.body.versioned_formulae.map(function (f) {
var ver = f.replace(/.*@/, '');
return {
version: ver,
download: dl,
download: dl
};
}),
})
);
})
.catch(function (err) {

View File

@@ -16,7 +16,7 @@ function getAllReleases(request, owner, repo, baseurl) {
return Promise.reject('missing baseurl');
}
return ghRelease(request, owner, repo, baseurl + '/api/v1').then(function (
all,
all
) {
return all;
});
@@ -29,11 +29,11 @@ if (module === require.main) {
require('@root/request'),
'coolaj86',
'go-pathman',
'https://git.coolaj86.com',
'https://git.coolaj86.com'
).then(
//getAllReleases(require('@root/request'), 'root', 'serviceman', 'https://git.rootprojects.org').then(
function (all) {
console.info(JSON.stringify(all, null, 2));
},
}
);
}

View File

@@ -1,133 +0,0 @@
'use strict';
require('dotenv').config();
/**
* Gets the releases for 'ripgrep'. This function could be trimmed down and made
* for use with any github release.
*
* @param request
* @param {string} owner
* @param {string} repo
* @returns {PromiseLike<any> | Promise<any>}
*/
async function getAllReleases(
request,
owner,
repo,
oses,
arches,
baseurl = 'https://api.github.com',
) {
if (!owner) {
return Promise.reject('missing owner for repo');
}
if (!repo) {
return Promise.reject('missing repo name');
}
let req = {
url: `${baseurl}/repos/${owner}/${repo}/releases`,
json: true,
};
// TODO I really don't like global config, find a way to do better
if (process.env.GITHUB_USERNAME) {
req.auth = {
user: process.env.GITHUB_USERNAME,
pass: process.env.GITHUB_TOKEN,
};
}
let resp = await request(req);
let gHubResp = resp.body;
let all = {
releases: [],
// TODO make this ':baseurl' + ':releasename'
download: '',
};
for (let release of gHubResp) {
// TODO tags aren't always semver / sensical
let tag = release['tag_name'];
let lts = /(\b|_)(lts)(\b|_)/.test(release['tag_name']);
let channel = 'stable';
if (release['prerelease']) {
channel = 'beta';
}
let date = release['published_at'] || '';
date = date.replace(/T.*/, '');
let urls = [release.tarball_url, release.zipball_url];
for (let url of urls) {
let resp = await request({
method: 'HEAD',
followRedirect: true,
followAllRedirects: true,
followOriginalHttpMethod: true,
url: url,
stream: true,
});
// Workaround for bug where method changes to GET
resp.destroy();
// content-disposition: attachment; filename=BeyondCodeBootcamp-DuckDNS.sh-v1.0.1-0-ga2f4bde.zip
let name = resp.headers['content-disposition'].replace(
/.*filename=([^;]+)(;|$)/,
'$1',
);
all.releases.push({
name: name,
version: tag,
lts: lts,
channel: channel,
date: date,
os: '', // will be guessed by download filename
arch: '', // will be guessed by download filename
ext: '', // will be normalized
download: resp.request.uri.href,
});
}
}
if (oses) {
return combinate(all, oses, arches);
}
return all;
}
function combinate(all, oses, arches) {
let releases = all.releases;
// ex: arches = ['amd64', 'arm64', 'armv7l', 'armv6l', 'x86'];
// ex: oses = ['macos', 'linux', 'bsd', 'posix'];
let combos = [];
for (let release of releases) {
for (let arch of arches) {
for (let os of oses) {
let combo = {
arch: arch,
os: os,
};
let rel = Object.assign({}, release, combo);
combos.push(rel);
}
}
}
all.releases = combos;
return all;
}
module.exports = getAllReleases;
if (module === require.main) {
getAllReleases(
require('@root/request'),
'BeyondCodeBootcamp',
'DuckDNS.sh',
).then(function (all) {
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -11,73 +11,58 @@ require('dotenv').config();
* @param {string} repo
* @returns {PromiseLike<any> | Promise<any>}
*/
async function getAllReleases(
function getAllReleases(
request,
owner,
repo,
baseurl = 'https://api.github.com',
baseurl = 'https://api.github.com'
) {
if (!owner) {
throw new Error('missing owner for repo');
return Promise.reject('missing owner for repo');
}
if (!repo) {
throw new Error('missing repo name');
return Promise.reject('missing repo name');
}
var req = {
url: `${baseurl}/repos/${owner}/${repo}/releases`,
json: true,
json: true
};
// TODO I really don't like global config, find a way to do better
if (process.env.GITHUB_USERNAME) {
req.auth = {
user: process.env.GITHUB_USERNAME,
pass: process.env.GITHUB_TOKEN,
pass: process.env.GITHUB_TOKEN
};
}
let resp = await request(req);
if (!resp.ok) {
console.error('Bad Resp Headers:', resp.headers);
console.error('Bad Resp Body:', resp.body);
throw new Error('the elusive releases BOOGEYMAN strikes again');
}
return request(req).then((resp) => {
const gHubResp = resp.body;
const all = {
releases: [],
// todo make this ':baseurl' + ':releasename'
download: ''
};
let gHubResp = resp.body;
let all = {
releases: [],
// todo make this ':baseurl' + ':releasename'
download: '',
};
try {
gHubResp.forEach(transformReleases);
} catch (e) {
console.error(e.message);
console.error('Error Headers:', resp.headers);
console.error('Error Body:', resp.body);
throw e;
}
function transformReleases(release) {
release['assets'].forEach(function (asset) {
let name = asset['name'];
all.releases.push({
name: name,
version: release['tag_name'], // TODO tags aren't always semver / sensical
lts: /(\b|_)(lts)(\b|_)/.test(release['tag_name']),
channel: !release['prerelease'] ? 'stable' : 'beta',
date: (release['published_at'] || '').replace(/T.*/, ''),
os: '', // will be guessed by download filename
arch: '', // will be guessed by download filename
ext: '', // will be normalized
download: asset['browser_download_url'],
gHubResp.forEach((release) => {
release['assets'].forEach((asset) => {
const name = asset['name'];
all.releases.push({
name: name,
version: release['tag_name'], // TODO tags aren't always semver / sensical
lts: /(\b|_)(lts)(\b|_)/.test(release['tag_name']),
channel: !release['prerelease'] ? 'stable' : 'beta',
date: (release['published_at'] || '').replace(/T.*/, ''),
os: '', // will be guessed by download filename
arch: '', // will be guessed by download filename
ext: '', // will be normalized
download: asset['browser_download_url']
});
});
});
}
return all;
return all;
});
}
module.exports = getAllReleases;
@@ -86,6 +71,6 @@ if (module === require.main) {
getAllReleases(require('@root/request'), 'BurntSushi', 'ripgrep').then(
function (all) {
console.info(JSON.stringify(all, null, 2));
},
}
);
}

View File

@@ -20,7 +20,7 @@ etc).
These are the files / directories that are created and/or modified with this
install:
```text
```txt
~/.config/envman/PATH.env
~/.local/bin/foo
~/.local/opt/foo

View File

@@ -9,7 +9,7 @@ function spawner(args) {
return new Promise(function (resolve, reject) {
var bin = args.shift();
var runner = spawn(bin, args, {
windowsHide: true,
windowsHide: true
});
runner.stdout.on('data', function (chunk) {
console.info(chunk.toString('utf8'));

View File

@@ -19,7 +19,7 @@ if (/^win/i.test(os.platform())) {
return;
}
exec('curl -fsS https://webi.sh/webi | sh', function (err, stdout, stderr) {
exec('curl -fsS https://webi.sh/webi | sh', function(err, stdout, stderr) {
if (err) {
console.error(err);
}

View File

@@ -15,7 +15,7 @@ __install_webi() {
export WEBI_HOST
echo ""
printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[31m%s/%s\e[0m'.\n" "${WEBI_PKG-}" "$(uname -s)/$(uname -r)" "$(uname -m)"
printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[31m%s/%s\e[0m'.\n" "${WEBI_PKG:-}" "$(uname -s)" "$(uname -m)"
echo "Have a problem? Experience a bug? Please let us know:"
echo " https://github.com/webinstall/webi-installers/issues"
echo ""
@@ -92,40 +92,35 @@ __webi_main() {
export WEBI_WGET="\$(command -v wget)"
set -e
my_libc=''
if ldd /bin/ls 2> /dev/null | grep -q 'musl' 2> /dev/null; then
my_libc=' musl-native'
fi
export WEBI_HOST="\${WEBI_HOST:-https://webinstall.dev}"
export WEBI_UA="\$(uname -s)/\$(uname -r) \$(uname -m)/unknown\${my_libc}"
export WEBI_UA="\$(uname -a)"
webinstall() {
my_package="\${1:-}"
if [ -z "\$my_package" ]; then
echo >&2 "Usage: webi <package>@<version> ..."
echo >&2 "Example: webi node@lts rg"
>&2 echo "Usage: webi <package>@<version> ..."
>&2 echo "Example: webi node@lts rg"
exit 1
fi
export WEBI_BOOT="\$(mktemp -d -t "\$my_package-bootstrap.\$WEBI_TIMESTAMP.XXXXXXXX")"
my_installer_url="\$WEBI_HOST/api/installers/\$my_package.sh?formats=\$my_ext"
set +e
if [ -n "\$WEBI_CURL" ]; then
if ! curl -fsSL "\$my_installer_url" -H "User-Agent: curl \$WEBI_UA" \\
-o "\$WEBI_BOOT/\$my_package-bootstrap.sh"; then
echo >&2 "error fetching '\$my_installer_url'"
exit 1
fi
curl -fsSL "\$my_installer_url" -H "User-Agent: curl \$WEBI_UA" \\
-o "\$WEBI_BOOT/\$my_package-bootstrap.sh"
else
if ! wget -q "\$my_installer_url" --user-agent="wget \$WEBI_UA" \\
-O "\$WEBI_BOOT/\$my_package-bootstrap.sh"; then
echo >&2 "error fetching '\$my_installer_url'"
exit 1
fi
wget -q "\$my_installer_url" --user-agent="wget \$WEBI_UA" \\
-O "\$WEBI_BOOT/\$my_package-bootstrap.sh"
fi
if ! [ \$? -eq 0 ]; then
>&2 echo "error fetching '\$my_installer_url'"
exit 1
fi
set -e
(
cd "\$WEBI_BOOT"
@@ -138,10 +133,10 @@ __webi_main() {
show_path_updates() {
if test -z "\${_WEBI_CHILD}"; then
if test -f "\$_webi_tmp/.PATH.env"; then
my_paths=\$(sort -u < "\$_webi_tmp/.PATH.env")
if test -n "\$my_paths"; then
if ! [ -n "\${_WEBI_CHILD}" ]; then
if [ -f "\$_webi_tmp/.PATH.env" ]; then
my_paths=\$(cat "\$_webi_tmp/.PATH.env" | sort -u)
if [ -n "\$my_paths" ]; then
printf 'PATH.env updated with:\\n'
printf "%s\\n" "\$my_paths"
printf '\\n'
@@ -204,7 +199,8 @@ __webi_main() {
exit 0
fi
for pkgname in "\$@"; do
for pkgname in "\$@"
do
webinstall "\$pkgname"
done
@@ -218,13 +214,13 @@ EOF
chmod a+x "$HOME/.local/bin/webi"
if [ -n "${WEBI_PKG-}" ]; then
if [ -n "${WEBI_PKG:-}" ]; then
"$HOME/.local/bin/webi" "${WEBI_PKG}"
else
echo ""
echo "Hmm... no WEBI_PKG was specified. This is probably an error in the script."
echo ""
echo "Please open an issue with this information: Package '${WEBI_PKG-}' on '$(uname -s)/$(uname -r) $(uname -m)'"
echo "Please open an issue with this information: Package '${WEBI_PKG:-}' on '$(uname -s)/$(uname -m)'"
echo " https://github.com/webinstall/packages/issues"
echo ""
fi

View File

@@ -1,7 +1,7 @@
'use strict';
var fs = require('fs');
var marked = require('marked').marked;
var marked = require('marked');
var frontmatter = '---';
var keyValRe = /(\w+): (.*)/;
@@ -19,7 +19,7 @@ function parseYamlish(txt) {
}
function unblock() {
cfg[block] = marked.parse(cfg[block]);
cfg[block] = marked(cfg[block]);
block = false;
}
@@ -57,7 +57,7 @@ function parseYamlish(txt) {
var m = line.match(keyValRe);
if (!m) {
throw new Error(
'invalid key format for: ' + JSON.stringify(line) + ' ' + i,
'invalid key format for: ' + JSON.stringify(line) + ' ' + i
);
}
if ('|' === m[2]) {
@@ -68,9 +68,9 @@ function parseYamlish(txt) {
});
if (block) {
cfg[block] = marked.parse(cfg[block]);
cfg[block] = marked(cfg[block]);
}
cfg.examples = marked.parse(lines.slice(last).join('\n'));
cfg.examples = marked(lines.slice(last).join('\n'));
return cfg;
}
@@ -79,6 +79,6 @@ module.exports.parse = parseYamlish;
if (require.main === module) {
console.info(
parseYamlish(fs.readFileSync(__dirname + '/../node/README.md', 'utf8')),
parseYamlish(fs.readFileSync(__dirname + '/../node/README.md', 'utf8'))
);
}

View File

@@ -7,13 +7,13 @@ var osMap = {
freebsd: /(\b|_)(freebsd)/i,
windows: /(\b|_)(win|microsoft|msft)/i,
sunos: /(\b|_)(sun)/i,
aix: /(\b|_)(aix)/i,
aix: /(\b|_)(aix)/i
};
var maps = {
oses: {},
arches: {},
formats: {},
formats: {}
};
Object.keys(osMap).forEach(function (name) {
@@ -39,7 +39,7 @@ var arches = [
'x86',
'ppc64le',
'ppc64',
's390x',
's390x'
];
// Used for detecting system arch from package download url, for example:
//
@@ -59,7 +59,7 @@ var archMap = {
x86: /(\b|_|amd|(dar)?win(dows)?|mac(os)?|linux|osx|x)(86|32)([_\-]?bit)(\b|_)/i,
ppc64le: /(\b|_)(ppc64le)/i,
ppc64: /(\b|_)(ppc64)(\b|_)/i,
s390x: /(\b|_)(s390x)/i,
s390x: /(\b|_)(s390x)/i
};
arches.forEach(function (name) {
maps.arches[name] = true;
@@ -69,7 +69,7 @@ function normalize(all) {
var supported = {
oses: {},
arches: {},
formats: {},
formats: {}
};
all.releases.forEach(function (rel) {
@@ -85,11 +85,9 @@ function normalize(all) {
}
// Hacky-doo for musl
// TODO some sort of glibc vs musl tag?
if (!rel._musl_native) {
if (!rel._musl) {
if (/(\b|\.|_|-)(musl)(\b|\.|_|-)/.test(rel.download)) {
rel._musl = true;
}
if (!rel._musl) {
if (/(\b|\.|_|-)(musl)(\b|\.|_|-)/.test(rel.download)) {
rel._musl = true;
}
}
supported.oses[rel.os] = true;

View File

@@ -1,6 +1,7 @@
'use strict';
var frontmarker = require('./frontmarker.js');
var shmatter = require('shmatter');
var fs = require('fs');
var path = require('path');
@@ -39,6 +40,7 @@ pkgs.create = function (Pkgs, basepath) {
});
};
Pkgs._get = function (node) {
var yash = path.join(basepath, node, 'package.yash');
var curlbash = path.join(basepath, node, 'install.sh');
var readme = path.join(basepath, node, 'README.md');
var winstall = path.join(basepath, node, 'install.ps1');
@@ -55,14 +57,30 @@ pkgs.create = function (Pkgs, basepath) {
console.error(e);
}
}),
fs.promises.access(curlbash).catch(function (e) {
// no *nix installer
curlbash = '';
if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
console.error("failed to parse '" + node + "/install.sh'");
console.error(e);
}
}),
fs.promises
.readFile(yash, 'utf-8')
.then(function (txt) {
return shmatter.parse(txt);
})
.catch(function (e) {
// no yash package description
yash = '';
if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
console.error("failed to parse '" + node + "/package.yash'");
console.error(e);
}
return fs.promises.readFile(curlbash, 'utf-8').then(function (txt) {
return shmatter.parse(txt);
});
})
.catch(function (e) {
// no *nix installer
curlbash = '';
if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
console.error("failed to parse '" + node + "/install.sh'");
console.error(e);
}
}),
fs.promises.access(winstall).catch(function (e) {
// no winstaller
winstall = '';
@@ -70,7 +88,7 @@ pkgs.create = function (Pkgs, basepath) {
console.error("failed to read '" + node + "/install.ps1'");
console.error(e);
}
}),
})
]).then(function (items) {
var meta = items[0] || items[1];
if (!meta) {

View File

@@ -1,7 +1,7 @@
'use strict';
var fs = require('node:fs');
var path = require('node:path');
var fs = require('fs');
var path = require('path');
var request = require('@root/request');
var _normalize = require('../_webi/normalize.js');
@@ -9,28 +9,25 @@ var reInstallTpl = /\s*#?\s*{{ installer }}/;
var Releases = module.exports;
Releases.get = async function (pkgdir) {
let get;
var get;
try {
get = require(path.join(pkgdir, 'releases.js'));
} catch (e) {
let err = new Error('no releases.js for', pkgdir.split(/[\/\\]+/).pop());
err.code = 'E_NO_RELEASE';
throw err;
throw new Error('no releases.js for', pkgdir.split(/[\/\\]+/).pop());
}
let all = await get(request);
return _normalize(all);
return get(request).then(function (all) {
return _normalize(all);
});
};
function padScript(txt) {
return txt.replace(/^/g, ' ');
}
Releases.renderBash = async function (
Releases.renderBash = function (
pkgdir,
rel,
{ baseurl, pkg, tag, ver, os = '', arch = '', formats },
{ baseurl, pkg, tag, ver, os = '', arch = '', formats }
) {
if (!Array.isArray(formats)) {
formats = [];
@@ -50,7 +47,7 @@ Releases.renderBash = async function (
build: vers
.join('.')
.replace(/[^+\-]*/, '')
.replace(/^-/, ''),
.replace(/^-/, '')
};
var pkgFile = rel.filename || rel.name;
return fs.promises
@@ -84,7 +81,7 @@ Releases.renderBash = async function (
'&formats=' +
formats.join(',') +
'&pretty=true' +
"'",
"'"
)
.replace(
/^\s*#?WEBI_CSV=.*/m,
@@ -100,15 +97,15 @@ Releases.renderBash = async function (
'-',
rel.download,
rel.name,
rel.comment || '',
rel.comment || ''
]
.join(',')
.replace(/'/g, '') +
"'",
"'"
)
.replace(
/^\s*#?WEBI_VERSION=.*/m,
'WEBI_VERSION=' + JSON.stringify(rel.version),
'WEBI_VERSION=' + JSON.stringify(rel.version)
)
.replace(/^\s*#?WEBI_MAJOR=.*/m, 'WEBI_MAJOR=' + v.major)
.replace(/^\s*#?WEBI_MINOR=.*/m, 'WEBI_MINOR=' + v.minor)
@@ -118,33 +115,33 @@ Releases.renderBash = async function (
.replace(/^\s*#?WEBI_CHANNEL=.*/m, 'WEBI_CHANNEL=' + rel.channel)
.replace(
/^\s*#?WEBI_EXT=.*/m,
'WEBI_EXT=' + rel.ext.replace(/tar.*/, 'tar'),
'WEBI_EXT=' + rel.ext.replace(/tar.*/, 'tar')
)
.replace(
/^\s*#?WEBI_FORMATS=.*/m,
"WEBI_FORMATS='" + formats.join(',') + "'",
"WEBI_FORMATS='" + formats.join(',') + "'"
)
.replace(
/^\s*#?WEBI_PKG_URL=.*/m,
"WEBI_PKG_URL='" + rel.download + "'",
"WEBI_PKG_URL='" + rel.download + "'"
)
.replace(
/^\s*#?WEBI_PKG_FILE=.*/m,
"WEBI_PKG_FILE='" + pkgFile + "'",
"WEBI_PKG_FILE='" + pkgFile + "'"
)
// PKG details
.replace(/^\s*#?PKG_NAME=.*/m, "PKG_NAME='" + pkg + "'")
.replace(
/^\s*#?PKG_OSES=.*/m,
"PKG_OSES='" + ((rel && rel.oses) || []).join(',') + "'",
"PKG_OSES='" + ((rel && rel.oses) || []).join(',') + "'"
)
.replace(
/^\s*#?PKG_ARCHES=.*/m,
"PKG_ARCHES='" + ((rel && rel.arches) || []).join(',') + "'",
"PKG_ARCHES='" + ((rel && rel.arches) || []).join(',') + "'"
)
.replace(
/^\s*#?PKG_FORMATS=.*/m,
"PKG_FORMATS='" + ((rel && rel.formats) || []).join(',') + "'",
"PKG_FORMATS='" + ((rel && rel.formats) || []).join(',') + "'"
)
// $', $0, ... $9, $`, $&, and $_ all have special meaning
// (see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RegExp)
@@ -156,10 +153,10 @@ Releases.renderBash = async function (
});
};
Releases.renderBatch = async function (
Releases.renderBatch = function (
pkgdir,
rel,
{ baseurl, pkg, tag, ver, os, arch, formats },
{ baseurl, pkg, tag, ver, os, arch, formats }
) {
if (!Array.isArray(formats)) {
formats = [];
@@ -189,17 +186,17 @@ Releases.renderBatch = async function (
return tplTxt
.replace(
/^(REM )?WEBI_PKG=.*/im,
"WEBI_PKG='" + pkg + '@' + ver + "'",
"WEBI_PKG='" + pkg + '@' + ver + "'"
)
.replace(reInstallTpl, '\n' + installTxt);
});
});
};
Releases.renderPowerShell = async function (
Releases.renderPowerShell = function (
pkgdir,
rel,
{ baseurl, pkg, tag, ver, os, arch, formats },
{ baseurl, pkg, tag, ver, os, arch, formats }
) {
if (!Array.isArray(formats)) {
formats = [];
@@ -230,27 +227,27 @@ Releases.renderPowerShell = async function (
return tplTxt
.replace(
/^(#)?\$Env:WEBI_HOST\s*=.*/im,
"$Env:WEBI_HOST = '" + baseurl + "'",
"$Env:WEBI_HOST = '" + baseurl + "'"
)
.replace(
/^(#)?\$Env:WEBI_PKG\s*=.*/im,
"$Env:WEBI_PKG = '" + pkgver + "'",
"$Env:WEBI_PKG = '" + pkgver + "'"
)
.replace(
/^(#)?\$Env:PKG_NAME\s*=.*/im,
"$Env:PKG_NAME = '" + pkg + "'",
"$Env:PKG_NAME = '" + pkg + "'"
)
.replace(
/^(#)?\$Env:WEBI_VERSION\s*=.*/im,
"$Env:WEBI_VERSION = '" + rel.version + "'",
"$Env:WEBI_VERSION = '" + rel.version + "'"
)
.replace(
/^(#)?\$Env:WEBI_PKG_URL\s*=.*/im,
"$Env:WEBI_PKG_URL = '" + rel.download + "'",
"$Env:WEBI_PKG_URL = '" + rel.download + "'"
)
.replace(
/^(#)?\$Env:WEBI_PKG_FILE\s*=.*/im,
"$Env:WEBI_PKG_FILE = '" + rel.name + "'",
"$Env:WEBI_PKG_FILE = '" + rel.name + "'"
)
.replace(reInstallTpl, '\n' + installTxt);
});

View File

@@ -11,9 +11,14 @@ var getReleases = require('./transform-releases.js');
var installersDir = path.join(__dirname, '..');
serveInstaller.serveInstaller = serveInstaller;
module.exports = serveInstaller;
async function serveInstaller(baseurl, ua, pkg, tag, ext, formats) {
module.exports = async function serveInstaller(
baseurl,
ua,
pkg,
tag,
ext,
formats
) {
// TODO put some of this in a middleware? or common function?
var ver = tag.replace(/^v/, '');
@@ -47,43 +52,41 @@ async function serveInstaller(baseurl, ua, pkg, tag, ext, formats) {
// TODO maybe move package/version/lts/channel detection into getReleases
var myOs = uaDetect.os(ua);
var myArch = uaDetect.arch(ua);
var myLibc = uaDetect.libc(ua);
let cfg = await packages.get(pkg);
let rels = await getReleases({
pkg: cfg.alias || pkg,
ver,
os: myOs,
arch: myArch,
libc: myLibc,
lts,
channel,
formats,
limit: 1,
return packages.get(pkg).then(function (cfg) {
return getReleases({
pkg: cfg.alias || pkg,
ver,
os: myOs,
arch: myArch,
lts,
channel,
formats,
limit: 1
}).then(function (rels) {
var rel = rels.releases[0];
var pkgdir = path.join(installersDir, pkg);
var opts = {
baseurl,
pkg: cfg.alias || pkg,
ver,
tag,
os: myOs,
arch: myArch,
lts,
channel,
formats,
limit: 1
};
rel.oses = rels.oses;
rel.arches = rels.arches;
rel.formats = rels.formats;
if ('bat' === ext) {
return Releases.renderBatch(pkgdir, rel, opts);
} else if ('ps1' === ext) {
return Releases.renderPowerShell(pkgdir, rel, opts);
} else {
return Releases.renderBash(pkgdir, rel, opts);
}
});
});
var rel = rels.releases[0];
var pkgdir = path.join(installersDir, pkg);
var opts = {
baseurl,
pkg: cfg.alias || pkg,
ver,
tag,
os: myOs,
arch: myArch,
lts,
channel,
formats,
limit: 1,
};
rel.oses = rels.oses;
rel.arches = rels.arches;
rel.formats = rels.formats;
if ('bat' === ext) {
return Releases.renderBatch(pkgdir, rel, opts);
}
if ('ps1' === ext) {
return Releases.renderPowerShell(pkgdir, rel, opts);
}
return Releases.renderBash(pkgdir, rel, opts);
}
};

View File

@@ -42,87 +42,24 @@ New-Item -Path .local\opt -ItemType Directory -Force | out-null
# {{ baseurl }}
# {{ version }}
function webi_path_add($pathname)
function webi_add_path
{
# C:\Users\me => C:/Users/me
$my_home = $Env:UserProfile
$my_home = $my_home.replace('\\', '/')
$my_home_re = [regex]::escape($my_home)
# ~/bin => %USERPROFILE%/bin
$pathname = $pathname.replace('~/', "$Env:UserProfile/")
# C:\Users\me\bin => %USERPROFILE%/bin
$my_pathname = $pathname.replace('\\', '/')
$my_pathname = $my_pathname -ireplace $my_home_re, "%USERPROFILE%"
$all_user_paths = [Environment]::GetEnvironmentVariable("Path", "User")
$user_paths = $all_user_paths -Split(';')
$exists_in_path = $false
foreach ($user_path in $user_paths)
{
# C:\Users\me\bin => %USERPROFILE%/bin
$my_user_path = $user_path.replace('\\', '/')
$my_user_path = $my_user_path -ireplace $my_home_re, "%USERPROFILE%"
if ($my_user_path -ieq $my_pathname)
{
$exists_in_path = $true
}
}
if (-Not $exists_in_path)
{
$all_user_paths = $pathname + ";" + $all_user_paths
[Environment]::SetEnvironmentVariable("Path", $all_user_paths, "User")
}
$session_paths = $Env:Path -Split(';')
$in_session_path = $false
foreach ($session_path in $session_paths)
{
# C:\Users\me\bin => %USERPROFILE%/bin
$my_session_path = $session_path.replace('\\', '/')
$my_session_path = $my_session_path -ireplace $my_home_re, "%USERPROFILE%"
if ($my_session_path -ieq $my_pathname)
{
$in_session_path = $true
}
}
if (-Not $in_session_path)
{
$my_cmd = 'PATH ' + "$pathname" + ';%PATH%'
$my_pwsh = '$Env:Path = "' + "$pathname" + ';$Env:Path"'
Write-Host ''
Write-Host '**********************************' -ForegroundColor red -BackgroundColor white
Write-Host '* IMPORTANT -- READ ME *' -ForegroundColor red -BackgroundColor white
Write-Host '* (run the PATH command below) *' -ForegroundColor red -BackgroundColor white
Write-Host '**********************************' -ForegroundColor red -BackgroundColor white
Write-Host ''
echo ""
echo "Copy, paste, and run the appropriate command to update your PATH:"
echo "(or close and reopen the terminal, or reboot)"
echo ""
echo "cmd.exe:"
echo " $my_cmd"
echo ""
echo "PowerShell:"
echo " $my_pwsh"
echo ""
}
Write-Host ''
Write-Host '*****************************' -ForegroundColor red -BackgroundColor white
Write-Host '* IMPORTANT - READ ME *' -ForegroundColor red -BackgroundColor white
Write-Host '*****************************' -ForegroundColor red -BackgroundColor white
Write-Host ''
& "$Env:USERPROFILE\.local\bin\pathman.exe" add "$args[0]"
# Note: not all of these work as expected, so we use the unix-style, which is most consistent
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/bin
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add "$Env:USERPROFILE\.local\bin"
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add %USERPROFILE%\.local\bin
}
#$has_local_bin = echo "$Env:PATH" | Select-String -Pattern '\.local.bin'
#if (!$has_local_bin)
#{
webi_path_add ~/.local/bin
#}
# Run pathman to set up the folder
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/bin
{{ installer }}
webi_path_add ~/.local/bin
# Done
popd

View File

@@ -6,11 +6,6 @@ __bootstrap_webi() {
set -u
#set -x
my_libc=''
if ldd /bin/ls 2> /dev/null | grep -q 'musl' 2> /dev/null; then
my_libc=' musl-native'
fi
#WEBI_PKG=
#PKG_NAME=
# TODO should this be BASEURL instead?
@@ -35,25 +30,16 @@ __bootstrap_webi() {
#PKG_OSES=
#PKG_ARCHES=
#PKG_FORMATS=
WEBI_UA="$(uname -s)/$(uname -r) $(uname -m)/unknown${my_libc}"
WEBI_UA="$(uname -a)"
WEBI_PKG_DOWNLOAD=""
WEBI_DOWNLOAD_DIR="${HOME}/Downloads"
if command -v xdg-user-dir > /dev/null; then
WEBI_DOWNLOAD_DIR="$(xdg-user-dir DOWNLOAD)"
if [ "${WEBI_DOWNLOAD_DIR}" = "${HOME}" ]; then
WEBI_DOWNLOAD_DIR="${HOME}/Downloads"
fi
fi
WEBI_PKG_PATH="${WEBI_DOWNLOAD_DIR}/webi/${PKG_NAME:-error}/${WEBI_VERSION:-latest}"
WEBI_PKG_PATH="${HOME}/Downloads/webi/${PKG_NAME:-error}/${WEBI_VERSION:-latest}"
export WEBI_HOST
##
## Set up tmp, download, and install directories
##
WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-"${WEBI_PKG-}".XXXXXXXX)"}
WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-"${WEBI_PKG:-}".XXXXXXXX)"}
export _webi_tmp="${_webi_tmp:-"$HOME/.local/opt/webi-tmp.d"}"
mkdir -p "${WEBI_PKG_PATH}"
@@ -96,7 +82,7 @@ __bootstrap_webi() {
return 0
fi
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1-}" ]; then
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1:-}" ]; then
rm -rf "$pkg_dst_cmd"
ln -s "$pkg_src_cmd" "$pkg_dst_cmd"
else
@@ -164,20 +150,16 @@ __bootstrap_webi() {
# detect if file is downloaded, and how to download it
webi_download() {
# determine the url to download
if [ -n "${1-}" ]; then
my_url="${1}"
if [ -n "${1:-}" ]; then
my_url="$1"
else
if [ "error" = "$WEBI_CHANNEL" ]; then
# TODO pass back requested OS / Arch / Version
echo >&2 "Error: no '$PKG_NAME' release for '${WEBI_OS-}' on '$WEBI_ARCH' as one of '$WEBI_FORMATS' by the tag '${WEBI_TAG-}'"
echo >&2 "Error: no '$PKG_NAME' release for '${WEBI_OS:-}' on '$WEBI_ARCH' as one of '$WEBI_FORMATS' by the tag '${WEBI_TAG:-}'"
echo >&2 " '$PKG_NAME' is available for '$PKG_OSES' on '$PKG_ARCHES' as one of '$PKG_FORMATS'"
echo >&2 " (check that the package name and version are correct)"
echo >&2 ""
my_release_url="$(
echo "$WEBI_RELEASES" |
sed 's:\?.*::'
)"
echo >&2 " Double check at ${my_release_url}"
echo >&2 " Double check at $(echo "$WEBI_RELEASES" | sed 's:\?.*::')"
echo >&2 ""
exit 1
fi
@@ -185,18 +167,12 @@ __bootstrap_webi() {
fi
# determine the location to download to
if [ -n "${2-}" ]; then
my_dl="${2}"
if [ -n "${2:-}" ]; then
my_dl="$2"
else
my_dl="${WEBI_PKG_PATH}/$WEBI_PKG_FILE"
fi
if [ -n "${3-}" ]; then
my_dl_name="${3}"
else
my_dl_name="${PKG_NAME}"
fi
WEBI_PKG_DOWNLOAD="${my_dl}"
export WEBI_PKG_DOWNLOAD
@@ -205,7 +181,7 @@ __bootstrap_webi() {
return 0
fi
echo "Downloading ${my_dl_name} from"
echo "Downloading $PKG_NAME from"
echo "$my_url"
# It's only 2020, we can't expect to have reliable CLI tools
@@ -266,179 +242,25 @@ __bootstrap_webi() {
# use 'pathman' to update $HOME/.config/envman/PATH.env
webi_path_add() {
my_path="${1}"
# make sure that we don't recursively install pathman with webi
my_path="$PATH"
export PATH="$HOME/.local/bin:$PATH"
fn_envman_init
# \v was chosen as it is extremely unlikely for a filename
# \1 could be an even better choice, but needs more testing.
# (currently tested working on: linux & mac)
# "\0001" should also work
my_delim="$(
printf '\v'
)"
my_path_expanded="$(
echo "${my_path}" |
sed -e "s${my_delim}\$HOME${my_delim}$HOME${my_delim}g" \
-e "s${my_delim}\${HOME}${my_delim}$HOME${my_delim}g" \
-e "s${my_delim}^~/${my_delim}$HOME/${my_delim}g"
)"
# A gift for @adamcstephens.
# See https://github.com/webinstall/webi-installers/issues/322
case "${PATH}" in
# matches whether the first, a middle, the last, or the only PATH entry
"${my_path_expanded}":* | \
*:"${my_path_expanded}":* | \
*:"${my_path_expanded}" | \
"${my_path_expanded}")
if fn_is_defined_in_all_shells "${my_path}"; then
return 0
fi
;;
*) ;;
esac
my_path_export="$(
echo "${my_path}" |
sed -e "s${my_delim}${HOME}${my_delim}\$HOME${my_delim}g" \
-e "s${my_delim}\${HOME}${my_delim}\$HOME${my_delim}g" \
-e "s${my_delim}^~/${my_delim}\$HOME/${my_delim}g"
)"
my_export="export PATH=\"$my_path_export:\$PATH\""
if grep -q -F "${my_export}" ~/.config/envman/PATH.env; then
return 0
# install pathman if not already installed
if [ -z "$(command -v pathman)" ]; then
"$HOME/.local/bin/webi" pathman > /dev/null
fi
echo "${my_export}" >> ~/.config/envman/PATH.env
export PATH="$my_path"
# in case pathman was recently installed and the PATH not updated
mkdir -p "$_webi_tmp"
my_path_tilde="$(
echo "${my_path}" |
sed -e "s${my_delim}${HOME}${my_delim}~${my_delim}g"
)"
if ! test -f "$_webi_tmp/.PATH.env" ||
! grep -q -F "${my_path_tilde}" "$_webi_tmp/.PATH.env"; then
echo "${my_path_tilde}" >> "$_webi_tmp/.PATH.env"
fi
}
fn_envman_init() {
mkdir -p ~/.config/envman/
if ! test -e ~/.config/envman/PATH.env; then
touch ~/.config/envman/PATH.env
fi
if ! test -e ~/.config/envman/load.sh; then
# shellcheck disable=SC2016
{
echo '# Generated for envman. Do not edit.'
echo 'for x in ~/.config/envman/*.env; do'
echo ' my_basename="$(basename "${x}")"'
echo ' if [ "*.env" = "${my_basename}" ]; then'
echo ' continue'
echo ' fi'
echo ''
echo ' # shellcheck source=/dev/null'
echo ' . "${x}"'
echo 'done'
} > ~/.config/envman/load.sh
fi
if command -v sh > /dev/null; then
if test -e ~/.profile; then
if ! grep -q -F '/.config/envman/load.sh' ~/.profile; then
fn_echo_load_sh >> ~/.profile
fi
fi
fi
if command -v bash > /dev/null; then
if test -e ~/.bashrc; then
if ! grep -q -F '/.config/envman/load.sh' ~/.bashrc; then
fn_echo_load_sh >> ~/.bashrc
fi
fi
fi
if command -v zsh > /dev/null; then
if test -e ~/.zshrc; then
if ! grep -q -F '/.config/envman/load.sh' ~/.zshrc; then
fn_echo_load_sh >> ~/.zshrc
fi
fi
fi
if command -v fish > /dev/null; then
if test ! -e ~/.config/envman/load.fish; then
# shellcheck disable=SC2016
{
echo '# Generated for envman. Do not edit.'
echo 'for x in ~/.config/envman/*.env'
echo ' source "$x"'
echo 'end'
} > ~/.config/envman/load.fish
fi
mkdir -p ~/.config/fish
if test -e ~/.config/fish/config.fish; then
touch ~/.config/fish/config.fish
fi
if ! grep -q -F '/.config/envman/load.fish' ~/.config/fish/config.fish; then
fn_echo_load_fish >> ~/.config/fish/config.fish
fi
fi
}
fn_echo_load_fish() {
echo ''
echo '# Generated for envman. Do not edit.'
# shellcheck disable=SC2016
echo 'test -s "$HOME/.config/envman/load.fish"; and source "$HOME/.config/envman/load.fish"'
}
fn_echo_load_sh() {
echo ''
echo '# Generated for envman. Do not edit.'
# shellcheck disable=SC2016
echo '[ -s "$HOME/.config/envman/load.sh" ] && source "$HOME/.config/envman/load.sh"'
}
fn_is_defined_in_all_shells() {
my_path="${1}"
my_path_expanded="$(
echo "${my_path}" |
sed -e "s${my_delim}\$HOME|${my_delim}$HOME${my_delim}g" \
-e "s${my_delim}\${HOME}${my_delim}$HOME${my_delim}g" \
-e "s${my_delim}^~/${my_delim}$HOME/${my_delim}g"
)"
my_paths="$(
echo "${my_path_expanded}"
# $HOME/foo
echo "${my_path_expanded}" |
sed "s${my_delim}${HOME}${my_delim}\$HOME${my_delim}g"
# ${HOME}/foo
echo "${my_path_expanded}" |
sed "s${my_delim}${HOME}${my_delim}\${HOME}${my_delim}g"
echo "${my_path}"
)"
my_confs="$(
echo "${HOME}/.profile"
echo "${HOME}/.bashrc"
echo "${HOME}/.zshrc"
echo "${HOME}/.config/fish/config.fish"
)"
for my_conf in $my_confs; do
if test -e "${my_conf}"; then
if ! grep -q -F "${my_paths}" "${my_conf}"; then
return 1
fi
fi
done
# 'true' to prevent "too few arguments" output
# when there are 0 lines of stdout
"$HOME/.local/bin/pathman" add "$1" |
grep "export" 2> /dev/null \
>> "$_webi_tmp/.PATH.env" ||
true
}
# group common pre-install tasks as default
@@ -452,7 +274,7 @@ __bootstrap_webi() {
# shellcheck disable=2120
# webi_install may be sourced and used elsewhere
webi_install() {
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1-}" ]; then
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1:-}" ]; then
mkdir -p "$(dirname "$pkg_src_cmd")"
mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
else
@@ -506,9 +328,9 @@ __bootstrap_webi() {
WEBI_SINGLE=
if [ -z "${WEBI_WELCOME-}" ]; then
if [ -z "${WEBI_WELCOME:-}" ]; then
echo ""
printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[31m%s/%s\e[0m'.\n" "${WEBI_PKG-}" "$(uname -s)" "$(uname -m)"
printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[31m%s/%s\e[0m'.\n" "${WEBI_PKG:-}" "$(uname -s)" "$(uname -m)"
echo "Have a problem? Experience a bug? Please let us know:"
echo " https://github.com/webinstall/webi-installers/issues"
echo ""
@@ -540,14 +362,14 @@ __bootstrap_webi() {
command -v pkg_post_install > /dev/null ||
command -v pkg_done_message > /dev/null ||
command -v pkg_format_cmd_version > /dev/null ||
[ -n "${WEBI_SINGLE-}" ] ||
[ -n "${pkg_cmd_name-}" ] ||
[ -n "${pkg_dst_cmd-}" ] ||
[ -n "${pkg_dst_dir-}" ] ||
[ -n "${pkg_dst-}" ] ||
[ -n "${pkg_src_cmd-}" ] ||
[ -n "${pkg_src_dir-}" ] ||
[ -n "${pkg_src-}" ]; then
[ -n "${WEBI_SINGLE:-}" ] ||
[ -n "${pkg_cmd_name:-}" ] ||
[ -n "${pkg_dst_cmd:-}" ] ||
[ -n "${pkg_dst_dir:-}" ] ||
[ -n "${pkg_dst:-}" ] ||
[ -n "${pkg_src_cmd:-}" ] ||
[ -n "${pkg_src_dir:-}" ] ||
[ -n "${pkg_src:-}" ]; then
pkg_cmd_name="${pkg_cmd_name:-$PKG_NAME}"
@@ -598,12 +420,10 @@ __bootstrap_webi() {
fi
webi_path_add "$HOME/.local/bin"
if [ -z "${_WEBI_CHILD-}" ] && [ -f "$_webi_tmp/.PATH.env" ]; then
if [ -z "${_WEBI_CHILD:-}" ] && [ -f "$_webi_tmp/.PATH.env" ]; then
if [ -n "$(cat "$_webi_tmp/.PATH.env")" ]; then
printf 'PATH.env updated with:\n'
sort -u "$_webi_tmp/.PATH.env" | while read -r my_new_path; do
echo " ${my_new_path}"
done
sort -u "$_webi_tmp/.PATH.env"
printf "\n"
rm -f "$_webi_tmp/.PATH.env"

View File

@@ -5,7 +5,7 @@
//
var usage = [
'Usage: node _webi/test.js --debug <path-to-package>',
'Example: node _webi/test.js --debug ./node/',
'Example: node _webi/test.js --debug ./node/'
].join('\n');
var count = 3;
@@ -104,7 +104,7 @@ Releases.get(path.join(process.cwd(), pkgdir)).then(function (all) {
ver: '',
os: osrel,
arch,
formats: formats,
formats: formats
}).catch(function () {}),
Releases.renderPowerShell(pkgdir, rel, {
baseurl: 'https://webinstall.dev',
@@ -113,8 +113,8 @@ Releases.get(path.join(process.cwd(), pkgdir)).then(function (all) {
ver: '',
os: osrel,
arch,
formats: formats,
}).catch(function () {}),
formats: formats
}).catch(function () {})
]).then(function (scripts) {
var bashTxt = scripts[0];
var ps1Txt = scripts[1];
@@ -125,7 +125,7 @@ Releases.get(path.join(process.cwd(), pkgdir)).then(function (all) {
bashTxt = (bashTxt || 'echo ERROR').replace(/#set -x/g, 'set -x');
ps1Txt = (ps1Txt || 'echo ERROR').replace(
/REM REM todo debug/g,
'REM todo debug',
'REM todo debug'
);
}
console.info('Do the scripts actually work?');

View File

@@ -2,13 +2,9 @@
var path = require('path');
var Releases = require('./releases.js');
var uaDetect = require('./ua-detect.js');
var cache = {};
//var staleAge = 5 * 1000;
//var expiredAge = 15 * 1000;
var staleAge = 5 * 60 * 1000;
var expiredAge = 15 * 60 * 1000;
var staleAge = 5 * 1000;
var expiredAge = 15 * 1000;
let installerDir = path.join(__dirname, '..');
@@ -54,14 +50,6 @@ function createFormatsSorter(formats) {
return 1;
}
// Hacky-doo for musl-native: prefer non-musl
if (a._musl_native && !b._musl_native) {
return 1;
}
if (!a._musl_native && b._musl_native) {
return -1;
}
// Hacky-doo for linux: prefer musl
if (a._musl && !b._musl) {
return -1;
@@ -76,102 +64,64 @@ function createFormatsSorter(formats) {
async function getCachedReleases(pkg) {
// returns { download: '<template string>', releases: [{ version, date, os, arch, lts, channel, download}] }
async function chainCachePromise(fn) {
cache[pkg].promise = cache[pkg].promise.then(fn);
return cache[pkg].promise;
}
async function sleep(ms) {
return await new Promise(function (resolve, reject) {
setTimeout(resolve, ms);
});
}
async function putCache() {
var age = Date.now() - cache[pkg].updatedAt;
if (age < staleAge) {
//console.debug('NOT STALE ANYMORE - updated in previous promise');
return cache[pkg].all;
}
//console.debug('DOWNLOADING NEW "%s" releases', pkg);
var pkgdir = path.join(installerDir, pkg);
// workaround for request timeout seeming to not work
let complete = false;
await Promise.race([
Releases.get(pkgdir)
.catch(function (err) {
if ('E_NO_RELEASE' === err.code) {
let all = { _error: 'E_NO_RELEASE', download: '', releases: [] };
return all;
}
throw err;
})
.catch(function (err) {
let hasReleases = cache[pkg].all?.releases?.length > 1;
if (!hasReleases) {
throw err;
}
console.error(`Error: the BOOGEYMAN got us!`);
console.error(err.stack);
return cache[pkg].all;
})
function putCache() {
cache[pkg].promise = cache[pkg].promise.then(function () {
var age = Date.now() - cache[pkg].updatedAt;
if (age < staleAge) {
//console.debug('NOT STALE ANYMORE - updated in previous promise');
return cache[pkg].all;
}
//console.debug('DOWNLOADING NEW "%s" releases', pkg);
var pkgdir = path.join(installerDir, pkg);
return Releases.get(pkgdir)
.then(function (all) {
// Note: it is possible for slightly older data
// to replace slightly newer data, but this is better
// than being in a cycle where release updates _always_
// take longer than expected.
//console.debug('DOWNLOADED NEW "%s" releases', pkg);
cache[pkg].updatedAt = Date.now();
cache[pkg].all = all;
complete = true;
}),
sleep(5000).then(function () {
if (complete) {
return;
}
console.error(`request timeout waiting for '${pkg}' release info`);
}),
]);
return cache[pkg].all;
})
.catch(function (e) {
console.error(
'Error fetching releases for "%s": %s',
pkg,
e.toString()
);
cache[pkg].all = { download: '', releases: [] };
})
.then(function () {
return cache[pkg].all;
});
});
return cache[pkg].promise;
}
var p;
if (!cache[pkg]) {
cache[pkg] = {
updatedAt: 0,
all: { download: '', releases: [] },
promise: Promise.resolve(),
all: null,
promise: Promise.resolve()
};
}
var bgRenewal;
var age = Date.now() - cache[pkg].updatedAt;
var fresh = age < staleAge;
if (!fresh) {
bgRenewal = chainCachePromise(putCache);
if (age >= expiredAge) {
//console.debug("EXPIRED - waiting");
p = putCache();
} else if (age >= staleAge) {
//console.debug("STALE - background update");
putCache();
p = Promise.resolve(cache[pkg].all);
} else {
//console.debug("FRESH");
p = Promise.resolve(cache[pkg].all);
}
var tooStale = age > expiredAge;
if (!tooStale) {
return await cache[pkg].all;
}
return await Promise.race([
bgRenewal,
sleep(5000).then(function () {
return cache[pkg].all;
}),
]);
return p;
}
async function filterReleases(
all,
{ ver, os, arch, libc, lts, channel, formats, limit },
{ ver, os, arch, lts, channel, formats, limit }
) {
// When multiple formats are downloadable (i.e. .zip and .pkg)
// sort the most compatible format first
@@ -180,62 +130,27 @@ async function filterReleases(
var sortByVerExt = createFormatsSorter(rformats);
var reVer = new RegExp('^' + ver + '\\b');
function selectMatches(rel) {
if (os) {
if (rel.os !== os) {
var sortedRels = all.releases
.filter(function (rel) {
if (
(os && rel.os !== os) ||
// Hacky-doo for linux musl
(arch && rel.arch !== arch) ||
(lts && !rel.lts) ||
(channel && rel.channel !== channel) ||
// to match 'tar.gz' and 'tar.xz' with just 'tar'
(formats.length &&
!formats.some(function (ext) {
return rel.ext.match(ext);
})) ||
(ver && !rel.version.match(reVer))
) {
return false;
}
}
if (arch) {
if (rel.arch !== arch) {
return false;
}
}
// Hacky-doo for linux musl
if (libc === uaDetect.MUSL_NATIVE) {
if (!rel._musl && !rel._musl_native) {
return false;
}
} else if (rel._musl_native) {
return false;
}
if (lts) {
if (!rel.lts) {
return false;
}
}
if (channel) {
if (rel.channel !== channel) {
return false;
}
}
// to match 'tar.gz' and 'tar.xz' with just 'tar'
function hasExt(ext) {
return rel.ext.match(ext);
}
if (formats.length) {
if (!formats.some(hasExt)) {
return false;
}
}
if (ver) {
if (!rel.version.match(reVer)) {
return false;
}
}
return true;
}
var sortedRels = all.releases.filter(selectMatches).sort(sortByVerExt);
return true;
})
.sort(sortByVerExt);
//console.log(sortedRels.slice(0, 4));
return sortedRels.slice(0, limit || 1000);
}
@@ -245,11 +160,10 @@ module.exports = function getReleases({
ver,
os,
arch,
libc,
lts,
channel,
formats,
limit,
limit
}) {
if (!_count) {
_count = 0;
@@ -259,49 +173,33 @@ module.exports = function getReleases({
ver,
os,
arch,
libc,
lts,
channel,
formats,
limit,
limit
})
.catch(function (err) {
if ('MODULE_NOT_FOUND' === err.code) {
return null;
}
console.error(
'TODO: lib/release.js: check type of error, such as MODULE_NOT_FOUND',
'TODO: lib/release.js: check type of error, such as MODULE_NOT_FOUND'
);
console.error(err);
})
.then(function (releases) {
if (!releases.length) {
// Apple Silicon M1 hacky-do workaround fix
// Apple Silicon M1 hack-y do workaround fix
if ('macos' === os && 'arm64' === arch) {
return getReleases({
pkg,
ver,
os,
arch: 'amd64',
libc,
lts,
channel,
formats,
limit,
});
}
// Windows ARM hacky-do workaround fix
if ('windows' === os && 'arm64' === arch) {
return getReleases({
pkg,
ver,
os,
arch: 'amd64',
libc,
lts,
channel,
formats,
limit,
limit
});
}
// Raspberry Pi 3+ on Raspbian x86 (not Ubuntu arm64)
@@ -312,11 +210,10 @@ module.exports = function getReleases({
ver,
os,
arch: 'arm64',
libc,
lts,
channel,
formats,
limit,
limit
});
}
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?)
@@ -328,11 +225,10 @@ module.exports = function getReleases({
ver,
os,
arch: 'armv7l',
libc,
lts,
channel,
formats,
limit,
limit
});
}
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?)
@@ -343,11 +239,10 @@ module.exports = function getReleases({
ver,
os,
arch: 'armv6l',
libc,
lts,
channel,
formats,
limit,
limit
});
}
releases = [
@@ -360,21 +255,20 @@ module.exports = function getReleases({
os: os || '-',
arch: arch || '-',
_musl: undefined,
_musl_native: undefined,
ext: 'err',
download: 'https://example.com/doesntexist.ext',
comment:
'No matches found. Could be bad or missing version info' +
',' +
"Check query parameters. Should be something like '/api/releases/{package}@{version}.tab?os={macos|linux|windows|-}&arch={amd64|x86|aarch64|arm64|armv7l|-}&limit=100'",
},
"Check query parameters. Should be something like '/api/releases/{package}@{version}.tab?os={macos|linux|windows|-}&arch={amd64|x86|aarch64|arm64|armv7l|-}&limit=100'"
}
];
}
return {
oses: all.oses,
arches: all.arches,
formats: all.formats,
releases: releases,
releases: releases
};
});
});
@@ -388,10 +282,9 @@ if (require.main === module) {
os: 'macos',
arch: 'amd64',
lts: true,
libc: '',
channel: 'stable',
formats: ['tar', 'exe', 'zip', 'xz', 'dmg', 'pkg'],
limit: 10,
limit: 10
})
.then(function (all) {
console.info(JSON.stringify(all));

View File

@@ -2,10 +2,6 @@
var uaDetect = module.exports;
const MUSL_NATIVE = 'musl-native';
uaDetect.MUSL_NATIVE = MUSL_NATIVE;
function getRequest(req) {
var ua = req.headers['user-agent'] || '';
var os = req.query.os;
@@ -20,11 +16,11 @@ function getRequest(req) {
}
return {
unix: 'curl -fsSA "$(uname -srm)" ' + url,
unix: 'curl -fsSA "$(uname -a)" ' + url,
windows: 'curl.exe -fsSA "MS $Env:PROCESSOR_ARCHITECTURE" ' + url,
ua: ua,
os: uaDetect.os(ua),
arch: uaDetect.arch(ua),
arch: uaDetect.arch(ua)
};
}
@@ -60,15 +56,10 @@ function getArch(ua) {
return '-';
}
// Quick hack for Apple Silicon M1
//
// Note: we now use `uname -srm` which does not have the native arch
// info included with `uname -v` and `uname -a`.
//
// quick hack for Apple Silicon M1
// Native: Darwin boomer.local 20.2.0 Darwin Kernel Version 20.2.0: Wed Dec 2 20:40:21 PST 2020; root:xnu-7195.60.75~1/RELEASE_ARM64_T8101 arm64
// Resetta: Darwin boomer.local 20.2.0 Darwin Kernel Version 20.2.0: Wed Dec 2 20:40:21 PST 2020; root:xnu-7195.60.75~1/RELEASE_ARM64_T8101 x86_64
ua = ua.replace(/xnu-.*RELEASE_[^\s]*/, '');
if (/aarch64|arm64|arm8|armv8/i.test(ua)) {
return 'arm64';
} else if (/aarch|arm7|armv7/i.test(ua)) {
@@ -93,27 +84,6 @@ function getArch(ua) {
}
}
function getLibc(ua) {
if ('-' === ua) {
return '-';
}
// Use native 'libc' information, if provided
//
// Generally, we prefer 'musl' builds because they DO work on glibc systems (Ubuntu),
// but 'glibc' builds will NOT work on musl systems (Alpine / Docker).
//
// However, there are a few instances (ex: Node.js), where the 'musl' builds
// DO NOT work on glibc systems.
if (ua.match(MUSL_NATIVE)) {
return MUSL_NATIVE;
}
// TODO handle explicit invalid different
return '';
}
uaDetect.os = getOs;
uaDetect.arch = getArch;
uaDetect.libc = getLibc;
uaDetect.request = getRequest;

View File

@@ -17,17 +17,7 @@ IF ($my_arch -eq $null -or $my_arch -eq "") {
# This is the canonical CPU arch when the process is native
$my_arch = "$Env:PROCESSOR_ARCHITECTURE"
}
IF ($my_arch -eq "AMD64") {
# Because PowerShell isn't ARM yet.
# See https://oofhours.com/2020/02/04/powershell-on-windows-10-arm64/
$my_os_arch = wmic os get osarchitecture
# Using -clike because of the trailing newline
IF ($my_os_arch -clike "ARM 64*") {
$my_arch = "ARM64"
}
}
# TODO API should know to prefer x86 for windows when arm binary is not available
$Env:WEBI_UA = "Windows/10 $my_arch"
$exename = $args[0]
@@ -60,6 +50,27 @@ IF($Env:WEBI_HOST -eq $null -or $Env:WEBI_HOST -eq "")
$Env:WEBI_HOST = "https://webinstall.dev"
}
if (!(Test-Path -Path .local\bin\pathman.exe))
{
& curl.exe -fsSL -A "$Env:WEBI_UA" "$Env:WEBI_HOST/packages/pathman/install.ps1" -o .\.local\tmp\pathman-setup.ps1
powershell .\.local\tmp\pathman-setup.ps1
# TODO del .\.local\tmp\pathman-setup.bat
}
# Run pathman to set up the folder
# (using unix style path because... cmd vs powershell vs whatever)
$has_local_bin = echo "$Env:PATH" | Select-String -Pattern '\.local.bin'
if (!$has_local_bin)
{
Write-Host ''
Write-Host '**********************************' -ForegroundColor red -BackgroundColor white
Write-Host '* IMPORTANT -- READ ME *' -ForegroundColor red -BackgroundColor white
Write-Host '* (run the PATH command below) *' -ForegroundColor red -BackgroundColor white
Write-Host '**********************************' -ForegroundColor red -BackgroundColor white
Write-Host ''
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/bin
}
# {{ baseurl }}
# {{ version }}

View File

@@ -10,7 +10,18 @@ pushd "%userprofile%" || goto :error
mkdir .local\opt || goto :error
)
echo Downloading and installing %1
pushd .local\bin || goto :error
if NOT EXIST pathman.exe (
echo updating PATH management
powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/pathman/install.bat -OutFile pathman-setup.bat || goto :error
call .\pathman-setup.bat || goto :error
del pathman-setup.bat || goto :error
rem TODO there's rumor of a windows tool called 'pathman' that does the same thing?
)
popd || goto :error
.\.local\bin\pathman add ".local\bin" || goto :error
echo downloading and installing %1
powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/%1/install.ps1 -OutFile %1-webinstall.bat || goto :error
rem TODO only add if it's not in there already

View File

@@ -1,125 +0,0 @@
---
title: aliasman
homepage: https://github.com/BeyondCodeBootcamp/aliasman
tagline: |
aliasman: A cross-shell (POSIX-compliant) alias manager for bash, zsh, and fish
---
To update or switch versions, run `webi aliasman@stable` (or `@v1.0.0`, `@beta`,
etc).
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/.config/envman/PATH.env
~/.config/envman/alias.env
~/.local/bin/aliasman
```
## Cheat Sheet
> `aliasman` helps you love your *alias*es again! 🥸 \
> Set 'em once, use 'em everywhere! \
> (and all in just one dotfile, for an on-the-go friendly config)
```sh
aliasman <alias-name> <command-name> [args, pipes, redirs, etc]
```
### What are Aliases?
An _alias_ is just shorthand for a shell function.
Take a long command like this:
```sh
git commit -m "feat: new feature"
```
And turn it into a short command, like this:
```sh
gc "feat: new feature"
```
(that would be `aliasman gc 'git commit -m'`)
### Imagine the possibilities!
1. What if you could quickly create a _command_, `ll`, \
that does the work of `ls -lAhF`!?
2. Set an _alias_ to do just that!
```sh
aliasman ll 'ls -lAhF'
```
3. Reload your alias config (or open a _new terminal_)
```sh
source ~/.config/envman/alias.env
```
4. Use it!
```sh
ll
```
```text
drwxr-xr-x aj wheel 416 B Thu Feb 9 02:08:39 2023 📂 .git/
.rwxr-xr-x aj staff 6.2 KB Thu Feb 9 01:36:30 2023 💻 aliasman*
.rw-r--r-- aj wheel 16 KB Wed Feb 8 21:51:06 2023 🔑 LICENSE
.rw-r--r-- aj wheel 1.4 KB Thu Feb 9 01:47:13 2023 📄 README.md
```
### Common aliases
Use *alias*es to make other tools you find around webi even _more_ convenient
⚡️ (and powerful 💪).
```sh
aliasman curl 'curlie'
aliasman diffy 'diff -y --suppress-common-lines'
aliasman gc 'git commit -m'
aliasman gri 'git rebase -i'
aliasman la 'lsd -AF'
aliasman ll 'lsd -lAhF'
aliasman ls 'lsd -F'
aliasman rgi 'rg -i'
aliasman tree 'lsd -F --tree --group-dirs=last'
# random password generator
aliasman rnd 'xxd -l24 -ps /dev/urandom'
```
### How to replace an alias
Just run the command again!
```sh
aliasman ll 'lsd -l'
aliasman ll 'lsd -lAhF'
```
### How to delete an alias
With `--delete`!
```sh
aliasman --delete ll
```
### How to see an alias
Just supply the name!
```sh
aliasman rnd
```
```text
alias rnd='xxd -l24 -ps /dev/urandom'
```

View File

@@ -1,41 +0,0 @@
#!/bin/sh
set -e
set -u
__init_aliasman() {
######################
# Install aliasman #
######################
# Every package should define these 6 variables
pkg_cmd_name="aliasman"
pkg_dst_cmd="$HOME/.local/bin/aliasman"
pkg_dst="$pkg_dst_cmd"
pkg_src_cmd="$HOME/.local/opt/aliasman-v$WEBI_VERSION/bin/aliasman"
pkg_src_dir="$HOME/.local/opt/aliasman-v$WEBI_VERSION"
pkg_src="$pkg_src_cmd"
# pkg_install must be defined by every package
pkg_install() {
# ~/.local/opt/aliasman-v1.0.0/bin
mkdir -p "$(dirname "$pkg_src_cmd")"
# mv ./*aliasman*/aliasman ~/.local/opt/aliasman-v1.0.0/bin/aliasman
mv ./*aliasman*/aliasman "$pkg_src_cmd"
}
# pkg_get_current_version is recommended, but (soon) not required
pkg_get_current_version() {
# 'aliasman version' has output in this format:
# aliasman v1.0.0 (2023-01-15)
# Copyright 2023 AJ ONeal
# This trims it down to just the version number:
# 1.0.0
aliasman version | head -n 1 | cut -d ' ' -f 2 | sed 's:^v::'
}
}
__init_aliasman

View File

@@ -1,28 +0,0 @@
'use strict';
var githubSource = require('../_common/github-source.js');
var owner = 'BeyondCodeBootcamp';
var repo = 'aliasman';
module.exports = function (request) {
let arches = [
'amd64',
'arm64',
'armv6l',
'armv7l',
'ppc64le',
's390x',
'x86',
];
let oses = ['freebsd', 'linux', 'macos', 'posix'];
return githubSource(request, owner, repo, oses, arches).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports(require('@root/request')).then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -7,13 +7,6 @@ tagline: |
To update or switch versions, run `webi arc@stable` (or `@v3.5`, `@beta`, etc).
### Files
```text
~/.config/envman/PATH.env
~/.local/opt/archiver/
```
## Cheat Sheet
> Archiver (`arc`) is a powerful and flexible library meets an elegant CLI in
@@ -25,42 +18,42 @@ create a top-level directory if one does not exist.
### List
```text
```txt
# arc ls <archive file>
arc ls example.zip
```
### Unarchive (whole)
```text
```txt
# arc unarchive <archive file>
arc unarchive example.zip
```
### Extract (partial)
```text
```txt
# arc extract <archive file> <archived path> <extracted path>
arc extract example.zip example/foo ~/Downloads/foo
```
### Archive (recursive)
```text
```txt
# arc archive <archive file> <files or folders ...>
arc archive example.zip ./README.md ./bin ./src
```
### Compress (single file)
```text
```txt
# arc compress <single file> <format>
arc compress ./example.tar xz
```
### Decompress (single file)
```text
```txt
# arc decompress <archive file>
arc decompress ./example.tar.xz
```

View File

@@ -3,9 +3,9 @@ set -e
set -u
__redirect_alias_arc() {
echo "'archiver@${WEBI_TAG:-stable}' is an alias for 'arc@${WEBI_VERSION-}'"
echo "'archiver@${WEBI_TAG:-stable}' is an alias for 'arc@${WEBI_VERSION:-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/arc@${WEBI_VERSION-}" | sh
curl -fsSL "$WEBI_HOST/arc@${WEBI_VERSION:-}" | sh
}
__redirect_alias_arc

View File

@@ -7,14 +7,6 @@ tagline: |
To update or switch versions, run `webi bat@stable` (or `@v0.18`, `@beta`, etc).
### Files
```text
~/.config/envman/PATH.env
~/.config/bat/config
~/.local/opt/bat/
```
## Cheat Sheet
> `bat` is pretty much what `cat` would be if it were developed today's in the
@@ -31,16 +23,7 @@ You need to download and install the
### How to alias as `cat`
Use [aliasman](/aliasman):
```sh
aliasman cat 'bat --style=plain'
alias cat='bat --style=plain'
```
Or place this in `~/.config/envman/alias.env` and manually update your
`.bashrc`, `.zshrc`, `.profile`, and/or `~/.config/fish/config.fish` to source
it.
Update your `.bashrc`, `.zshrc`, or `.profile`
```sh
alias cat="bat --style=plain"
@@ -71,7 +54,7 @@ Edit the config file:
`~/.config/bat/config`:
```text
```txt
# no numbers or headers, just highlighting and such
--style="plain"
```

View File

@@ -27,11 +27,6 @@ __init_bat() {
# chmod a+x ~/.local/opt/bat-v0.15.4/bin/bat
chmod a+x "$pkg_src_cmd"
if ! [ -e ~/.config/bat/config ]; then
mkdir -p ~/.config/bat/
touch ~/.config/bat/config
fi
}
}

View File

@@ -1,83 +0,0 @@
---
title: beyond-shell
homepage: https://webinstall.dev/beyond-shell
tagline: |
meta package for Beyond Code workshops
---
To update, run the relevant installers individually. For example:
`webi node@lts`.
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/bin
~/.config/envman/alias.env
~/.config/envman/PATH.env
~/.iterm2/
~/.local/bin/
~/.local/opt/
~/.local/share/font/ (or ~/Library/Fonts)
~/.vim/pack/plugins/start/
~/.vim/plugins/
~/.vimrc
```
## Cheat Sheet
> Installs the format and linter tools and code you'll need for the Beyond Code
> Shell Scripting Workshop
This meta package will install the full set of plugins and settings we
recommended.
## Prerequisites for Windows
- https://webinstall.dev/wsl
- https://webinstall.dev/nerdfont
## Post Install for macOS
- https://webinstall.dev/iterm2-themes
- https://webinstall.dev/nerdfont
## What's installed?
- Formatters & Linters
- [`prettier`](/prettier)
- [`shellcheck`](/shellcheck)
- [`shfmt`](/shfmt)
- Vim Plugins & Config
- [vim-leader](/vim-leader)
- [vim-shell](/vim-shell)
- [vim-sensible](/vim-sensible)
- [vim-viminfo](/vim-viminfo)
- [vim-lastplace](/vim-lastplace)
- [vim-smartcase](/vim-smartcase)
- [vim-spell](/vim-spell)
- [vim-ale](/vim-ale)
- [vim-prettier](/vim-prettier)
- [vim-shfmt](/vim-shfmt)
- [vim-whitespace](/vim-whitespace)
- Commandline Tools
- [`aliasman`](/aliasman)
- [`bat`](/bat)
- [`curlie`](/curlie)
- [`jq`](/jq)
- [`pathman`](/pathman)
- [`ssh-pubkey`](/ssh-pubkey)
- [`webi`](/webi)
- Aliases
- `cat='bat --style=plain --pager=none'`
- `curl=curlie`
- `setalias='aliasman'`
- System
- [iterm2](/iterm2)
- [fish](/fish)
- [NerdFont](/nerdfont)
- git
- vim
- zip

View File

@@ -1,415 +0,0 @@
#!/bin/sh
set -e
set -u
webi_cmd="$HOME/.local/bin/webi"
aliasman_cmd="$HOME/.local/bin/aliasman"
pathman_cmd="$HOME/.local/bin/pathman"
my_date="$(
date -u '+%F_%H.%M.%S'
)"
my_log="${HOME}/.local/share/beyond-code/var/${my_date}.log"
fn_node_version() { (
my_node="${1:-}"
if test -n "${my_node}"; then
"${my_node}" --version | sed 's/v//'
fi
); }
fn_node_path() { (
if command -v node; then
return 0
fi
if test ! -e ~/.local/opt/node/bin/node; then
return 0
fi
echo ~/.local/opt/node/bin/node
); }
fn_node_install() { (
node_minimum="18"
my_path_actual="$(
fn_node_path
)"
my_node="$(
fn_node_path
)"
my_node_version="$(
fn_node_version "${my_node}"
)"
if test -n "${my_path_actual}"; then
my_bin_dir="$(
dirname "${my_node}"
)"
my_node_dir="$(
dirname "${my_bin_dir}"
)"
my_lib_dir="${my_node_dir}/lib/node_modules"
if test ! -w "${my_bin_dir}" ||
test ! -w "${my_node_dir}" ||
test ! -w "${my_lib_dir}"; then
printf "\e[31m[Warning]\e[0m \e[32mNode.js\e[0m at %s is not user-writable\n" "${my_path_actual}"
sleep 1
my_path_actual=""
fi
fi
if test -n "${my_path_actual}"; then
my_node_major="$(
echo "${my_node_version}" | cut -d'.' -f1
)"
if test -z "${my_node_major}"; then
my_path_actual=""
elif test "${my_node_major}" -lt "${node_minimum}"; then
printf "\e[31m[Warning]\e[0m \e[32mNode.js v%s\e[0m is too old\n" "${my_node_version}"
sleep 1
my_path_actual=""
fi
fi
if test -z "${my_path_actual}"; then
printf "\e[32m[Fixup]\e[0m Installing \e[32mNode.js\e[0m to \e[34m%s\e[0m\n" '~'/.local/opt/node/
sleep 1
"${webi_cmd}" node@lts >> "${my_log}"
if test -e ~/.local/opt/node/bin/node; then
"${pathman_cmd}" add ~/.local/opt/node/bin/ > /dev/null 2> /dev/null
fi
else
echo "[Info] Found ${my_path_actual}/node (v${my_node_version})"
fi
); }
fn_git_install() { (
if [ "Darwin" = "$(uname -s)" ]; then
needs_xcode="$(
/usr/bin/xcode-select -p > /dev/null 2> /dev/null || echo "true"
)"
if [ -n "${needs_xcode}" ]; then
echo ""
echo ""
printf "\e[31m[Error]\e[0m: Run this command to install XCode Command Line Tools first:\n"
echo ""
echo " xcode-select --install"
echo ""
echo "After the install, close this terminal, open a new one, and try again."
echo ""
exit 1
else
my_git="$(command -v git)"
echo "[Info] Found ${my_git}"
fi
return 0
fi
if ! command -v git > /dev/null; then
fn_apt_get git git
return 0
fi
my_git="$(command -v git)"
echo "[Info] Found ${my_git}"
); }
fn_apt_get() { (
my_cmd="${1:-}"
my_pkg="${2:-}"
printf "\e[31m[Warning]\e[0m \e[32m%s\e[0m not found\n" "${my_cmd}"
printf "\e[32m[Fixup]\e[0m install \e[34m%s\e[0m (may require password)\n" "${my_pkg}"
sleep 1
echo "sudo apt-get install ${my_pkg}"
# shellcheck disable=SC2030
export DEBIAN_FRONTEND=noninteractive
if ! sudo apt-get install -qq -y -o=Dpkg::Use-Pty=0 "${my_pkg}"; then
echo "failed to install ${my_cmd} on"
cat /etc/issue
fi
); }
fn_vim_install() { (
if command -v vim > /dev/null; then
my_vim="$(command -v vim)"
echo "[Info] Found ${my_vim}"
return 0
fi
fn_apt_get vim vim
); }
fn_zip_install() { (
if command -v zip > /dev/null; then
my_zip="$(command -v zip)"
echo "[Info] Found ${my_zip}"
return 0
fi
fn_apt_get zip zip
); }
fn_fish_install() { (
if ! command -v fish > /dev/null; then
if [ "Darwin" = "$(uname -s)" ]; then
printf "\e[31m[Warning]\e[0m \e[32mfish\e[0m not found\n"
printf "\e[32m[Fixup]\e[0m install \e[34mfish\e[0m\n"
sleep 1
"${webi_cmd}" fish > /dev/null
else
fn_apt_get fish fish
fi
fi
if ! test -f ~/.config/fish/config.fish; then
printf "\e[32m[Fixup]\e[0m create \e[34m%s\e[0m\n" '~'/.config/fish/config.fish
mkdir -p ~/.config/fish/
touch ~/.config/fish/config.fish
chmod 0600 ~/.config/fish/config.fish
fi
); }
fn_touch() { (
my_file_path="${1:-}"
my_file_name="${2:-}"
if test -f "${my_file_path}"; then
echo "[Info] Found ${my_file_name}"
return 0
fi
printf "\e[32m[Fixup]\e[0m create \e[34m%s\e[0m\n" "${my_file_name}"
my_base_path="$(
basename "${my_file_path}"
)"
if test ! -e "${my_base_path}"; then
mkdir -p "${my_base_path}"
chmod 0700 "${my_base_path}"
fi
touch "${my_file_path}"
chmod 0600 "${my_file_path}"
); }
fn_mkdir() { (
my_dir_name="${1:-}"
my_dir_path="${2:-}"
if test -d "${my_dir_path}"; then
echo "[Info] Found ${my_dir_name}"
return 0
fi
printf "\e[32m[Fixup]\e[0m create \e[34m%s\e[0m\n" "${my_dir_name}"
mkdir -p "${my_dir_path}"
chmod 0700 "${my_dir_path}"
); }
fn_path_bin() { (
if test -d ~/bin/; then
echo "[Info] Found ~/bin/"
return 0
fi
printf "\e[32m[Fixup]\e[0m create \e[34m%s\e[0m\n" '~'/bin/
mkdir -p ~/bin/
"${pathman_cmd}" add ~/bin/ > /dev/null 2> /dev/null
); }
fn_webi_bin() { (
my_cmd="$(
echo "${1:-}" | sed 's/@.*//'
)"
if test -e ~/.local/bin/"${my_cmd}"; then
echo "[Info] Found ~/.local/bin/${my_cmd}"
return 0
fi
printf "\e[32m[Fixup]\e[0m Installing \e[32m%s\e[0m to \e[34m%s\e[0m\n" "${my_cmd}" '~'"/.local/bin/${my_cmd}"
"${webi_cmd}" "${my_cmd}" > /dev/null 2> /dev/null
); }
fn_webi_opt() { (
my_cmd="${1:-}"
# shellcheck disable=SC2010
# we do want to use ls with grep
if ls ~/.local/opt/ | grep -q -E "^${my_cmd}(-|\$)"; then
return 0
fi
printf "\e[32m[Fixup]\e[0m Installing \e[32m%s\e[0m to \e[34m%s/\e[0m\n" "${my_cmd}" '~'"/.local/opt/${my_cmd}"
"${webi_cmd}" "${my_cmd}" > /dev/null
); }
fn_webi_vim_config() { (
my_cmd="${1:-}"
if test -e ~/.vim/plugins/"${my_cmd}.vim"; then
echo "[Info] Found ~/.vim/plugins/${my_cmd}.vim"
return 0
fi
printf "\e[32m[Fixup]\e[0m Installing \e[32m%s\e[0m to \e[34m%s.vim\e[0m\n" "vim-${my_cmd}" '~'"/.vim/plugins/${my_cmd}.vim"
"${webi_cmd}" "vim-${my_cmd}" > /dev/null
); }
fn_webi_vim_plugin_ale() { (
my_cmd="ale"
if test -e ~/.vim/pack/plugins/start/"${my_cmd}"; then
echo "[Info] Found ~/.vim/pack/plugins/start/${my_cmd}"
return 0
fi
printf "\e[32m[Fixup]\e[0m Installing \e[32m%s\e[0m to \e[34m%s\e[0m\n" "vim-${my_cmd}" '~'"/.vim/pack/plugins/start/${my_cmd}"
printf "\e[32m[Fixup]\e[0m and config at \e[34m%s.vim\e[0m\n" '~'"/.vim/plugins/${my_cmd}"
"${webi_cmd}" "vim-${my_cmd}" > /dev/null 2> /dev/null
); }
fn_webi_vim_plugin() { (
my_cmd="${1:-}"
if test -e ~/.vim/pack/plugins/start/"vim-${my_cmd}"; then
echo "[Info] Found ~/.vim/pack/plugins/start/vim-${my_cmd}"
return 0
fi
printf "\e[32m[Fixup]\e[0m Installing \e[32m%s\e[0m to \e[34m%s\e[0m\n" "vim-${my_cmd}" '~'"/.vim/pack/plugins/start/vim-${my_cmd}"
printf "\e[32m[Fixup]\e[0m and config at \e[34m%s.vim\e[0m\n" '~'"/.vim/plugins/${my_cmd}"
"${webi_cmd}" "vim-${my_cmd}" > /dev/null 2> /dev/null
); }
fn_webi_vimrc() { (
my_cmd="${1:-}"
if grep -q "${my_cmd}" ~/.vimrc; then
echo "[Info] Found vim-${my_cmd} config in ~/.vimrc"
return 0
fi
printf "\e[32m[Fixup]\e[0m Installing \e[32m%s\e[0m to \e[34m%s\e[0m\n" "vim-${my_cmd}" '~'/.vimrc
"${webi_cmd}" "vim-${my_cmd}" > /dev/null
); }
fn_setalias() { (
my_name="${1:-}"
my_cmd="${2:-}"
if grep -q "${my_name}" ~/.config/envman/alias.env; then
echo "[Info] Found '${my_name}' alias"
return 0
fi
printf "\e[32m%s\e[0m aliased to '\e[34m%s\e[0m'\n" "${my_name}" "${my_cmd}"
"${aliasman_cmd}" "${my_name}" "${my_cmd}" > /dev/null
); }
__install() {
#printf "\e[31mRED\e[0m\n"
#printf "\e[32mYELLOW\e[0m\n"
#printf "\e[34mBLUE\e[0m\n"
echo ""
printf "\e[34mLog\e[0m will be written to \e[32m%s\e[0m\n" '~'/.local/share/beyond-code/var/
sleep 2
echo ""
mkdir -p ~/.local/share/beyond-code/var/
mkdir -p ~/.local/opt/
{
printf "\e[32mwebi\e[0m at \e[32m%s\e[0m\n" '~'/.local/bin/webi
echo ""
if [ "Darwin" = "$(uname -s)" ]; then
if test -e /Applications/iTerm.app; then
echo "[Info] Found iTerm.app in /Applications/"
else
printf "\e[32m[Fixup]\e[0m Installing \e[32m%s\e[0m into \e[34m%s\e[0m\n" "iTerm.app" "/Applications/"
"${webi_cmd}" iterm2 > /dev/null
fi
fi
fn_git_install
fn_fish_install
fn_zip_install
if test -e ~/.local/share/fonts/'Droid Sans Mono for Powerline Nerd Font Complete.otf'; then
echo "[Info] Found NerdFont in ~/.local/share/fonts"
elif test -e ~/Library/Fonts/'Droid Sans Mono for Powerline Nerd Font Complete.otf'; then
echo "[Info] Found NerdFont in ~/Library/Fonts"
else
"${webi_cmd}" nerdfont | tail -n 1
fi
if test -e ~/.iterm2/; then
echo "[Info] Found iTerm2 utils ~/.iterm2/"
else
printf "\e[32m[Fixup]\e[0m Installing \e[32m%s\e[0m into \e[34m%s\e[0m\n" "iterm2-utils" '~'"/.iterm2/"
"${webi_cmd}" iterm2-utils > /dev/null
fi
echo ""
echo "[Info] PATH updates in ~/.config/envman/PATH.env"
fn_path_bin
fn_touch ~/.config/envman/alias.env '~'/.config/envman/alias.env
fn_touch ~/.config/envman/PATH.env '~'/.config/envman/PATH.env
echo ""
fn_node_install
for my_cmd in aliasman bat curlie jq pathman ssh-pubkey; do
fn_webi_bin "${my_cmd}"
done
echo ""
echo "[Info] Aliases in ~/.config/envman/alias.env"
fn_setalias setalias 'aliasman'
fn_setalias cat 'bat --style=plain --pager=none'
fn_setalias curl 'curlie'
# vim config and plugins
echo ""
fn_vim_install
fn_touch ~/.vimrc '~'/.vimrc
for my_plugin in leader shell; do
fn_webi_vimrc "${my_plugin}"
done
fn_webi_vim_plugin sensible
for my_plugin in viminfo smartcase spell whitespace; do
fn_webi_vim_config "${my_plugin}"
done
fn_webi_vim_plugin_ale
for my_plugin in commentary lastplace shfmt prettier; do
fn_webi_vim_plugin "${my_plugin}"
done
for my_cmd in shfmt@3.5 shellcheck; do
fn_webi_bin "${my_cmd}"
done
} | tee -a "${my_log}"
echo ""
printf "\e[34mLog\e[0m written to \e[32m%s\e[0m\n" "${my_log}"
echo ""
}
__install

View File

@@ -1,47 +0,0 @@
#!/bin/sh
set -e
set -u
main() { (
sed '1,/^#~\/.local\/bin\/brew-updater/d' "${0}" > ~/.local/bin/brew-update-hourly
chmod a+x ~/.local/bin/brew-update-hourly
env PATH="$PATH" serviceman add --user \
--name sh.brew.updater -- \
~/.local/bin/brew-update-hourly
); }
if main; then
exit 0
fi
#~/.local/bin/brew-updater
#!/bin/sh
#set -e
set -u
if test -e ~/.config/envman/PATH.env; then
# shellcheck disable=SC1090
. ~/.config/envman/PATH.env
fi
while true; do
my_start="$(date '+%s')"
my_date="$(date '+%F %T')"
echo "[$my_date] Updating brew..."
brew update
echo ''
my_end="$(date '+%s')"
my_elapsed="$((my_end - my_start))"
my_date="$(date '+%F %T')"
echo "[$my_date] Updated in ${my_elapsed}s."
echo "[$my_date] Cleaning up..."
brew cleanup
echo "[$my_date] Waiting 24 hours..."
my_wait="$((24 * 60 * 60))"
sleep "$my_wait"
done

View File

@@ -7,9 +7,9 @@ _install_brew() {
# Straight from https://brew.sh
#/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
if test "Darwin" = "$(uname -s)"; then
if uname -a | grep -q -i darwin; then
needs_xcode="$(/usr/bin/xcode-select -p > /dev/null 2> /dev/null || echo "true")"
if test -n "${needs_xcode}"; then
if [ -n "${needs_xcode}" ]; then
echo ""
echo ""
echo "ERROR: Run this command to install XCode Command Line Tools first:"
@@ -20,11 +20,11 @@ _install_brew() {
echo ""
fi
else
if ! command -v gcc > /dev/null; then
if [ -z "$(command -v gcc)" ]; then
echo >&2 "Warning: to install 'gcc' et al on Linux use the built-in package manager."
echo >&2 " For example, try: sudo apt install -y build-essential"
fi
if ! command -v git > /dev/null; then
if [ -z "$(command -v git)" ]; then
echo >&2 "Error: to install 'git' on Linux use the built-in package manager."
echo >&2 " For example, try: sudo apt install -y git"
exit 1
@@ -32,7 +32,7 @@ _install_brew() {
fi
# From Straight from https://brew.sh
if ! test -d "$HOME/.local/opt/brew"; then
if ! [ -d "$HOME/.local/opt/brew" ]; then
echo "Installing to '$HOME/.local/opt/brew'"
echo ""
echo "If you prefer to have brew installed to '/usr/local' cancel now and do the following:"
@@ -44,13 +44,6 @@ _install_brew() {
git clone --depth=1 https://github.com/Homebrew/brew "$HOME/.local/opt/brew"
fi
rm -rf "$HOME/.local/bin/brew-update-service-install"
webi_download \
"$WEBI_HOST/packages/brew/brew-update-service-install" \
"$HOME/.local/bin/brew-update-service-install" \
brew-update-service-install
chmod a+x "$HOME/.local/bin/brew-update-service-install"
webi_path_add "$HOME/.local/opt/brew/bin"
export PATH="$HOME/.local/opt/brew/bin:$PATH"
@@ -67,10 +60,6 @@ _install_brew() {
# shellcheck disable=2016
echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"'
echo ""
echo "To register 'brew update' as a hourly system service:"
echo " brew-update-service-install"
echo ""
}
_install_brew

View File

@@ -1,160 +0,0 @@
---
title: Bun
homepage: https://bun.sh
tagline: |
Bun is a fast all-in-one JavaScript runtime
---
To update or switch versions, run `webi bun@<tag>`. \
(you can use `@beta` for pre-releases, or `@x.y.z` for a specific version)
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/.config/envman/PATH.env
~/.local/opt/bun/
~/.local/opt/bun-<VERSION>/
```
## Cheat Sheet
> Bun is a wicked-fast JavaScript runtime for developer tooling, API servers,
> and edge computing.
>
> It's built in Zig and provides a more curated, "batteries-included" approach
> to developing with JavaScript and JavaScript-ish languages - such as
> TypeScript, JSX, and TSX.
Run some <strong><em>x</em></strong>Script:
```sh
bun run ./hello.js
bun run ./hello.jsx
bun run ./hello.ts
bun run ./hello.tsx
```
Run a package from `npm`:
```sh
bun x jswt
```
More goodies:
```
bun help
```
(there's also a built-in **development server** and lots of stuff)
### bun<span>.</span>sh/install vs webi
Bun has an official installer:
```sh
export BUN_INSTALL="$HOME/.bun"
curl -fsSL https://bun.sh/install | bash
```
You might want to still use webi if you want to be able to switch between
versions.
### How to install command line completions
```sh
bun completions
```
### How to create a bun executable
1. Create your script
```sh
vim ./hello
```
```js
#!/usr/bin/env bun
console.log('hello');
```
2. Make it executable
```sh
chmod a+x ./hello
```
3. Run it
```sh
./hello
```
### How to publish bun packages
At the time of this writing (bun v0.5.1), you'll still need to publish with
`npm`.
`npm` is installed with [node](/node).
See
[Getting Started with NPM (as a developer)](https://gist.github.com/coolaj86/1318304).
### How to install bun packages
You can run it with `bun x`:
```sh
bun x <whatever>
```
Or you can put the `#!/usr/bin/env bun` shebang before publishing, and install
from npm:
```sh
bun install -g <whatever>
<whatever>
```
### How to run a Bun program as a service
As a system service on Linux:
(**note**: swap 'my-project' and './my-project' for the name of your project and
file)
1. Install serviceman (compatible with systemd)
```sh
webi serviceman
source ~/.config/envman/PATH.env
```
2. Go into your program's directory
```sh
pushd ./my-project/
```
3. Add your project to the system launcher, running as the current user
```sh
sudo env PATH="$PATH" \
serviceman add --path="$PATH" --system \
--username "$(whoami)" --name my-project -- \
bun run ./my-project.js
```
4. Restart the logging service
```sh
sudo systemctl restart systemd-journald
```
For **macOS**:
1. Install serviceman (compatible with `launchctl`)
```sh
webi serviceman
source ~/.config/envman/PATH.env
```
2. Go into your program's directory
```sh
pushd ./my-project/
```
3. Add your project to the system launcher, running as the current user
```sh
serviceman add --path="$PATH" --user --name my-project -- \
bun run ./my-project.js
```

View File

@@ -1,39 +0,0 @@
#!/bin/sh
set -e
set -u
# NOTE: pkg_* variables can be defined here
# pkg_cmd_name
# pkg_src, pkg_src_bin, pkg_src_cmd
# pkg_dst, pkg_dst_bin, pkg_dst_cmd
#
# Their defaults are defined in _webi/template.sh at https://github.com/webinstall/packages
# Every package should define these 6 variables
pkg_cmd_name="bun"
pkg_dst_cmd="$HOME/.local/opt/bun/bin/bun"
pkg_dst_dir="$HOME/.local/opt/bun"
pkg_dst="$pkg_dst_dir"
pkg_src_cmd="$HOME/.local/opt/bun-v$WEBI_VERSION/bin/bun"
pkg_src_dir="$HOME/.local/opt/bun-v$WEBI_VERSION"
pkg_src="$pkg_src_dir"
pkg_get_current_version() {
# 'bun --version' only outputs the version:
# 0.5.1
# But we future-proof it a little anyway
# 0.5.1
bun --version 2> /dev/null | head -n 1 | cut -d' ' -f1
}
# pkg_install must be defined by every package
pkg_install() {
# ~/.local/opt/bun-v0.5.1/bin
mkdir -p "$(dirname "$pkg_src_cmd")"
# mv ./bun-*/bun ~/.local/opt/bun-v0.5.1/bin/bun
mv ./bun-*/bun* "$pkg_src_cmd"
}

View File

@@ -1,32 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'oven-sh';
var repo = 'bun';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all.releases = all.releases
.filter(function (r) {
let isDebug = /-profile/.test(r.name);
if (!isDebug) {
return true;
}
})
.map(function (r) {
// bun-v0.5.1 => v0.5.1
r.version = r.version.replace(/bun-/g, '');
return r;
});
return all;
});
};
if (module === require.main) {
module.exports(require('@root/request')).then(function (all) {
all = require('../_webi/normalize.js')(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -26,9 +26,18 @@ Here's the things we find most useful:
### How to serve a directory
```sh
caddy file-server --browse --listen :4040
caddy file-server --browse --listen :443
```
### How to serve via Caddyfile
```sh
caddy run --config ./Caddyfile
```
Note: `run` runs in the foreground, `start` starts a background service (daemon)
in the background.
### How to serve HTTPS on localhost
Caddy can be used to test with https on localhost.
@@ -37,20 +46,50 @@ Caddy can be used to test with https on localhost.
```Caddyfile
localhost {
handle /api/* {
reverse_proxy localhost:3000
}
handle /* {
root * ./public/
file_server
}
handle /api/* {
reverse_proxy localhost:3000
}
}
```
```sh
caddyfile run --config ./Caddyfile
```
### How to serve on Linux/VPS (systemd)
1. Create a generic `Caddyfile`
```sh
mkdir -p ~/srv/caddy
echo '
# Generically vhost all domains pointed at this server
https:// {
tls {
on_demand
}
handle /* {
file_server
root * /home/app/srv/www/{host}/public/
}
}
' > ~/srv/caddy/Caddyfile
```
2. Install serviceman
```sh
webi serviceman
source ~/.config/envman/PATH.env
```
3. Install caddy as a system service
```sh
sudo env PATH="$PATH" \
serviceman add --system --username "$(whoami)" --name caddy -- \
caddy run --config ~/srv/caddy/Caddyfile
```
Note: In this example any host that points to the server and has files in
`~/srv/www/{host}/public` can be served without additional changes.
Note: More on using `systemctl` below.
### How to redirect and reverse proxy
@@ -146,15 +185,6 @@ example.com {
}
```
### How to run caddy
```sh
caddy run --config ./Caddyfile
```
Note: `run` runs in the foreground, `start` starts a service (daemon) in the
background.
### How to start Caddy as a Linux service
Here are the 3 things you need to do to start Caddy as a system service:
@@ -168,10 +198,11 @@ Using a user named `app` to run your services is common industry convention.
**port-binding privileges**
You can use `setcap` to allow Caddy to use privileged ports.
You can use `setcap` or [`setcap-netbind`](/setcap-netbind) to allow Caddy to
use privileged ports.
```sh
sudo setcap cap_net_bind_service=+ep $(readlink -f $(command -v caddy))
sudo setcap cap_net_bind_service=+ep "$(readlink -f "$(command -v caddy)")"
```
**systemd config**

View File

@@ -33,7 +33,7 @@ sudo apt --fix-broken install -y
You may get an error like this:
```text
```txt
chromedriver: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory
```

View File

@@ -6,20 +6,20 @@ var matchers = {
metaGeneration: /.*MetaGeneration>(.*)<\/MetaGeneration.*/,
lastModified: /.*LastModified>(.*)<\/LastModified.*/,
etag: /.*ETag>(.*)<\/ETag.*/,
size: /.*Size>(.*)<\/Size.*/,
size: /.*Size>(.*)<\/Size.*/
};
var baseUrl = 'https://chromedriver.storage.googleapis.com';
module.exports = function (request) {
var all = {
download: '',
releases: [],
releases: []
};
// XML
return request({
url: 'https://chromedriver.storage.googleapis.com/',
json: false,
json: false
})
.then(function (resp) {
var body = resp.body;
@@ -32,7 +32,7 @@ module.exports = function (request) {
key: group.replace(matchers.key, '$1'),
//generation: group.replace(matchers.generation, '$1'),
//metaGeneration: group.replace(matchers.metaGeneration, '$1'),
lastModified: group.replace(matchers.lastModified, '$1'),
lastModified: group.replace(matchers.lastModified, '$1')
//etag: group.replace(matchers.etag, '$1'),
//size: group.replace(matchers.size, '$1')
};
@@ -66,7 +66,7 @@ module.exports = function (request) {
os: osname,
arch: arch,
hash: '-', // not sure about including etag as hash yet
download: asset.key,
download: asset.key
});
});
})

View File

@@ -1,83 +0,0 @@
---
title: CMake
homepage: https://github.com/Kitware/CMake
tagline: |
CMake is a cross-platform, open-source build system generator
---
To update or switch versions, run `webi cmake@stable` (or `@v2`, `@beta`, etc).
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/.config/envman/PATH.env
~/.local/bin/cmake
~/.local/opt/cmake
```
## Cheat Sheet
> CMake is a cross-platform alternative to autoconf that works on Windows, Mac,
> and Linux
A project structure looks like this:
```text
my-project/
├── build/
├── CMakeLists.txt
├── hello-world*
└── hello-world.cpp
```
And can be built my running `cmake` from the `build` directory:
```sh
pushd ./build/
cmake ../
make
```
### How to create a Hello World with CMake
Lets create a hello world program in C++ and build it with CMake.
1. Create a project directory
```sh
mkdir ./my-project/
pushd ./my-project/
```
2. Create a Hello World C++ file named `hello-world.cpp` `hello-world.cpp`:
```cpp
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Hello World!" << std::endl;
return 0;
}
```
3. Create a `CMakeLists.txt` to compile our code `CMakeLists.txt`:
```cmake
project{hello-world}
cmake_minimum_required(VERSION 3.10)
add_executable(hello-world hello-world.cpp)
```
4. Create a build directory and build the binary
```sh
mkdir ./build/
pushd ./build/
cmake ../
make
```
5. Test the built binary:
```sh
./hello-world
```

View File

@@ -1,56 +0,0 @@
#!/usr/bin/env pwsh
#################
# Install cmake #
#################
# Every package should define these variables
$pkg_cmd_name = "cmake"
$pkg_dst_cmd = "$Env:USERPROFILE\.local\opt\cmake\bin\cmake.exe"
$pkg_dst_dir = "$Env:USERPROFILE\.local\opt\cmake"
$pkg_dst = "$pkg_dst_cmd"
$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\cmake-v$Env:WEBI_VERSION\bin\cmake.exe"
$pkg_src_bin = "$Env:USERPROFILE\.local\opt\cmake-v$Env:WEBI_VERSION\bin"
$pkg_src_dir = "$Env:USERPROFILE\.local\opt\cmake-v$Env:WEBI_VERSION"
$pkg_src = "$pkg_src_cmd"
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | out-null
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"
# Fetch archive
IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"))
{
echo "Downloading cmake from $Env:WEBI_PKG_URL to $pkg_download"
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part"
& move "$pkg_download.part" "$pkg_download"
}
IF (!(Test-Path -Path "$pkg_src_dir"))
{
echo "Installing cmake"
# TODO: create package-specific temp directory
# Enter tmp
pushd .local\tmp
# Remove any leftover tmp cruft
Remove-Item -Path ".\cmake*" -Recurse -ErrorAction Ignore
# Unpack archive file into this temporary directory
# Windows BSD-tar handles zip. Imagine that.
echo "Unpacking $pkg_download"
& tar xf "$pkg_download"
# Settle unpacked archive into place
echo "Install Location: $pkg_src_cmd"
Move-Item -Path ".\cmake*" -Destination "$pkg_src_dir"
# Exit tmp
popd
}
echo "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'"
Remove-Item -Path "$pkg_dst_cmd" -Recurse -ErrorAction Ignore | out-null
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse

View File

@@ -1,47 +0,0 @@
#!/bin/sh
# shellcheck disable=SC2034
# "'pkg_cmd_name' appears unused. Verify it or export it."
__init_cmake() {
set -e
set -u
##################
# Install cmake #
##################
# Every package should define these 6 variables
pkg_cmd_name="cmake"
pkg_dst_cmd="$HOME/.local/opt/cmake/bin/cmake"
pkg_dst_dir="$HOME/.local/opt/cmake"
pkg_dst="$pkg_dst_dir"
pkg_src_cmd="$HOME/.local/opt/cmake-v$WEBI_VERSION/bin/cmake"
pkg_src_dir="$HOME/.local/opt/cmake-v$WEBI_VERSION"
pkg_src="$pkg_src_dir"
# pkg_install must be defined by every package
pkg_install() {
# ~/.local/opt/cmake-v3.27.0/
mkdir -p "$(dirname "${pkg_src_dir}")"
# mv ./cmake-*/ ~/.local/opt/cmake-v3.27.0/
mv ./cmake-*/ "${pkg_src_dir}"
}
# pkg_get_current_version is recommended, but not required
pkg_get_current_version() {
# 'cmake --version' has output in this format:
# cmake 3.27.0 (rev abcdef0123)
# This trims it down to just the version number:
# 3.27.0
cmake --version 2> /dev/null |
head -n 1 |
cut -d ' ' -f 3
}
}
__init_cmake

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'Kitware';
var repo = 'CMake';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports(require('@root/request')).then(function (all) {
all = require('../_webi/normalize.js')(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -20,17 +20,6 @@ etc).
**JSON** (`=`) is the default encoding for `key=value` pairs.
### How to alias as `curl`
Use [aliasman](/aliasman):
```sh
aliasman curl 'curlie'
alias curl='curlie'
```
This will affect the interactive shell, but not scripts.
### Simple GET
```sh

View File

@@ -1,112 +0,0 @@
---
title: Dash Core Desktop Wallet
homepage: https://webinstall.dev/dashcore-utils/
tagline: |
Utilities for Dash Core (DASH / Digital Cash)
---
To update, run `webi dashcore-utils`.
### Files
These are the files / directories that are created and/or modified with this
install:
```txt
~/.config/envman/PATH.env
~/.local/opt/dashcore/
~/.local/bin/dash-qt-hd
~/.local/bin/dashd-hd
~/.local/bin/dashd-hd-service-install
```
[`dashcore`](../dashcore/) will also be installed if not present.
## Cheat Sheet
> Convenience scripts for running the Dash Daemon or the Dash Core Desktop
> Wallet.
- `dash-qt-hd`
- `dash-qt-testnet`
- `dashd-hd`
- `dashd-hd-service-install`
- `dashd-testnet`
- `dashd-testnet-service-install`
For historical reasons [`dashd`](../dashd/) (System Daemon) and
[`dash-qt`](../dashcore/) (Desktop Wallet) use _lossy_ keys (non-HD wallets) by
default, and the storage options options are not intuitive.
These scripts run them with safer options that are easier to configure for
server and desktop deployment, respectively.
### How to run the DASH System Daemon
1. Mount or otherwise designate a user-owned folder on a storage volume with
60g+ free space, such as
```sh
/mnt/slc1_vol_100g/dashcore/
```
2. Generally you'll want to install the Dash Daemon as a system service
```sh
dashd-hd-install-service /mnt/vol_slc1_100g/dashcore/
```
To accomplish the same manually you would:
1. Create `~/.dashcore/dash.conf` with reasonable defaults
```ini
```
Which is essentially the same as:
```sh
my_user="$(id -u -n)"
sudo mkdir /mnt/slc1_vol_100g/dashcore/
chown -R "$my_user" /mnt/slc1_vol_100g/dashcore/
mkdir -p ~/.dashcore/wallets/
mkdir -p /mnt/slc1_vol_100g/dashcore/_data
mkdir -p /mnt/slc1_vol_100g/dashcore/_caches
sudo env PATH="$PATH" serviceman add \
--system --user "$my_user" --path "$PATH" --name dashd --force -- \
dashd \
-usehd \
-conf="$HOME/.dashcore/dash.conf" \
-walletdir="$HOME/.dashcore/wallets/" \
-datadir=/mnt/slc1_vol_100g/dashcore/_data \
-blocksdir=/mnt/slc1_vol_100g/dashcore/_caches
```
See also:
- [The `dashd` Cheat Sheet](../dashd/).
### How to run the DASH Desktop Wallet
To open an existing (or create a new) Dash Desktop Wallet:
```sh
dash-qt-hd
```
Which is essentially the same as:
```sh
dash-qt \
-usehd \
-walletdir="$HOME/.config/dashcore/wallets/" \
-settings="$HOME/.config/dashcore/settings.json" \
-datadir="$HOME/.dashcore/_data/" \
-blocksdir="$HOME/.dashcore/_caches/"
```
Or pass `-testnet` to use with _TestNet_.
See also:
- [The `dash-qt` Cheat Sheet](../dashcore/).

View File

@@ -1,21 +0,0 @@
#!/bin/sh
set -e
set -u
# I don't have the gall to change the defaults (Webi values),
# but I would *strongly* recommend that you do!
#
# Instance-specific data should be separate from global caches:
#
# -settings="$HOME/.config/dashcore/settings.json" \
# -walletdir="$HOME/.config/dashcore/wallets/" \
# -datadir="$HOME/.dashcore/_data/" \
# -blocksdir="$HOME/.dashcore/_caches/" \
dash-qt \
-usehd \
-enablecoinjoin=1 \
-coinjoinautostart=1 \
-coinjoinrounds=16 \
-coinjoindenomsgoal=10 \
-coinjoindenomshardcap=25

View File

@@ -1,22 +0,0 @@
#!/bin/sh
set -e
set -u
# I don't have the gall to change the defaults (Webi values),
# but I would *strongly* recommend that you do!
#
# Instance-specific data should be separate from global caches:
#
# -settings="$HOME/.config/dashcore/settings.json" \
# -walletdir="$HOME/.config/dashcore/wallets/" \
# -datadir="$HOME/.dashcore/_data/" \
# -blocksdir="$HOME/.dashcore/_caches/" \
dash-qt \
-testnet \
-usehd \
-enablecoinjoin=1 \
-coinjoinautostart=1 \
-coinjoinrounds=16 \
-coinjoindenomsgoal=10 \
-coinjoindenomshardcap=25

View File

@@ -1,44 +0,0 @@
txindex=1
addressindex=1
timestampindex=1
spentindex=1
[main]
rpcuser=RPCUSER_MAIN
rpcpassword=RPCPASS_MAIN
# to run on multiple interfaces, use multiple config lines
# ex: bind=127.0.0.1:9999 and bind=10.0.0.100:9999)
bind=127.0.0.1:9999
rpcbind=127.0.0.1:9998
rpcconnect=127.0.0.1:9998
rpcallowip=127.0.0.1/16
# zmq* can only be bound to a single interface
# See https://github.com/dashpay/dash/issues/5461
zmqpubrawtx=tcp://127.0.0.1:28332
zmqpubrawtxlock=tcp://127.0.0.1:28332
zmqpubrawchainlock=tcp://127.0.0.1:28332
zmqpubhashchainlock=tcp://127.0.0.1:28332
[test]
rpcuser=RPCUSER_TEST
rpcpassword=RPCPASS_TEST
bind=127.0.0.1:19999
rpcbind=127.0.0.1:19998
rpcconnect=127.0.0.1:19998
rpcallowip=127.0.0.1/16
zmqpubrawtx=tcp://127.0.0.1:18009
zmqpubrawtxlock=tcp://127.0.0.1:18009
zmqpubrawchainlock=tcp://127.0.0.1:18009
zmqpubhashchainlock=tcp://127.0.0.1:18009
[regtest]
rpcuser=RPCUSER_REGTEST
rpcpassword=RPCPASS_REGTEST
bind=127.0.0.1:19899
rpcbind=127.0.0.1:19898
rpcconnect=127.0.0.1:19898
rpcallowip=127.0.0.1/16
zmqpubrawtx=tcp://127.0.0.1:18809
zmqpubrawtxlock=tcp://127.0.0.1:18809
zmqpubrawchainlock=tcp://127.0.0.1:18809
zmqpubhashchainlock=tcp://127.0.0.1:18809

View File

@@ -1,46 +0,0 @@
#!/bin/sh
set -e
set -u
# Unfortunately we can't know that datadir won't be used
# for other non-cache files, but we can at least protect
# the ones we're aware of.
my_netname="${1:-}"
if test -n "${my_netname}"; then
if test "${my_netname}" != mainnet &&
test "${my_netname}" != testnet &&
test "${my_netname}" != regnet &&
test "${my_netname}" != devnet; then
echo ""
echo "ERROR"
echo " '${my_netname}' is not one of 'testnet', 'regnet', 'devnet'"
echo ""
echo ""
fi
if test "${my_netname}" != mainnet; then
my_netname=''
fi
fi
my_net_arg=''
if test -n "${my_netname}"; then
my_net_arg="-${my_netname}"
fi
# shellcheck disable=2086
dashd \
-usehd \
${my_net_arg} \
-conf="$HOME/.dashcore/dash.conf" \
-settings="$HOME/.dashcore/settings.json" \
-walletdir="$HOME/.dashcore/wallets/" \
-datadir="$HOME/.dashcore/_data/" \
-blocksdir="$HOME/.dashcore/_data/"
# -enablecoinjoin=1 \
# -coinjoinautostart=1 \
# -coinjoinrounds=16 \
# -coinjoindenomsgoal=10 \
# -coinjoindenomshardcap=25

View File

@@ -1,176 +0,0 @@
#!/bin/sh
set -e
set -u
fn_usage() { (
echo >&2 ""
echo >&2 "USAGE"
echo >&2 " dashd-hd-service-install [datadir] ['testnet']"
echo >&2 ""
echo >&2 "EXAMPLE"
echo >&2 " dashd-hd-service-install /mnt/vol_slc1_100g/dashcore/"
echo >&2 ""
echo >&2 "NOTE"
echo >&2 " If a directory matching '/mnt/*/dashcore/' is found,"
echo >&2 " it will be used automatically."
echo >&2 ""
); }
fn_datadir_help() { (
my_vol="${1:-}"
my_user="$(
id -n -u
)"
my_group="$(
id -n -g
)"
echo >&2 ""
echo >&2 "ERROR"
echo >&2 " '${my_vol}' is not writable"
echo >&2 ""
echo >&2 "SOLUTION"
echo >&2 " 1. Mount a large (50gb+) volume"
echo >&2 ""
echo >&2 " sudo mkdir -p /mnt/EXAMPLE"
echo >&2 " sudo mount /dev/sdx1 /mnt/EXAMPLE"
echo >&2 ""
echo >&2 " 2. Create a 'dashcore' inside of it"
echo >&2 ""
echo >&2 " sudo mkdir -p '${my_vol}'"
echo >&2 ""
echo >&2 " 3. Make it writable to this user"
echo >&2 ""
echo >&2 " sudo chown -R '${my_user}':'${my_group}' '${my_vol}'"
echo >&2 ""
echo >&2 ""
); }
fn_srv_install() { (
my_vol="${1:-}"
my_netname="${2:-}"
my_name='dashd'
# both of these will get '/testnet3' suffixes with -testnet
my_datadir="${my_vol}/_data"
my_blocksdir="${my_vol}/_caches"
if test -n "${my_netname}"; then
if test "mainnet" = "${my_netname}"; then
my_netname=""
elif test "testnet" != "${my_netname}"; then
fn_usage
return 1
fi
fi
if ! test -d "${my_datadir}"; then
mkdir "${my_datadir}"
chmod 0700 "${my_datadir}"
fi
if ! test -d "${my_blocksdir}"; then
mkdir -p "${my_blocksdir}"
chmod 0700 "${my_blocksdir}"
fi
my_net_flag=''
if test -n "${my_netname}"; then
# ex: -testnet
my_net_flag="-${my_netname}"
# ex: dashd-testnet
my_name="dashd-${my_netname}"
fi
my_system_args=""
my_kernel="$(
uname -s
)"
if test "Darwin" != "${my_kernel}"; then
my_user="$(
id -u -n
)"
my_system_args="--system --username ${my_user}"
fi
# shellcheck disable=SC2016,SC1090
echo 'sudo env PATH="$PATH"' \
"serviceman add ${my_system_args} --path \"\$PATH\" --name \"${my_name}\" --force --" \
"dashd " \
"${my_net_flag}" \
-usehd \
'-conf="$HOME/.dashcore/dash.conf"' \
'-settings="$HOME/.dashcore/settings.json"' \
'-walletdir="$HOME/.dashcore/wallets/"' \
"-datadir=\"${my_datadir}\"" \
"-blocksdir=\"${my_blocksdir}\""
if ! command -v serviceman > /dev/null; then
echo ""
echo "Installing 'serviceman'..."
echo ""
{
curl -fsSL "${WEBI_HOST}/serviceman" | sh
} > /dev/null
# shellcheck disable=SC1090
. ~/.config/envman/PATH.env || true
fi
mkdir -p "$HOME/.dashcore/wallets/"
chmod 0700 "$HOME/.dashcore/wallets/"
mkdir -p "${my_datadir}"
chmod 0700 "${my_datadir}"
mkdir -p "${my_blocksdir}"
chmod 0700 "${my_blocksdir}"
cd "${my_vol}" || return 1
# leave options unquoted so they're interpreted separately
# shellcheck disable=SC2086
sudo env PATH="${PATH}" \
serviceman add ${my_system_args} --path "${PATH}" --name "${my_name}" --force -- \
dashd \
${my_net_flag} \
-usehd \
-conf="${HOME}/.dashcore/dash.conf" \
-settings="${HOME}/.dashcore/settings.json" \
-walletdir="${HOME}/.dashcore/wallets/" \
-datadir="${my_datadir}" \
-blocksdir="${my_blocksdir}"
); }
main() { (
my_vol="${1:-}"
my_netname="${2:-}"
if test -z "${my_vol}"; then
my_vol="$(
ls -d /mnt/*/dashcore/ 2> /dev/null || true
)"
fi
if test "help" = "${my_vol}" ||
test "--help" = "${my_vol}"; then
fn_usage
return 0
fi
if test -z "${my_vol}"; then
fn_usage
return 1
fi
if ! test -d "${my_vol}" ||
! test -w "${my_vol}"; then
fn_datadir_help "${my_vol}"
return 1
fi
fn_srv_install "${my_vol}" "${my_netname}"
); }
main "${@:-}"

View File

@@ -1,13 +0,0 @@
#!/bin/sh
set -e
set -u
# NOTE:
# The '-testnet' flag will always cause a './testnet3/' folder
# to be created under '-datadir' (it won't the 'datadir' directly)
#
# Example:
# dashd -testnet -datadir="$HOME/.dashcore/"
# will save to ~/.dashcore/testnet3/, NOT ~/.dashcore/
dashd-hd testnet

View File

@@ -1,5 +0,0 @@
#!/bin/sh
set -e
set -u
dashd-hd-service-install "${1:-}" "testnet"

View File

@@ -1,91 +0,0 @@
#!/bin/sh
set -e
set -u
__install_dashcore_utils() {
webi_download \
"$WEBI_HOST/packages/dashcore-utils/dash-qt-hd" \
"$HOME/.local/bin/dash-qt-hd"
chmod a+x "$HOME/.local/bin/dash-qt-hd"
webi_download \
"$WEBI_HOST/packages/dashcore-utils/dash-qt-testnet" \
"$HOME/.local/bin/dash-qt-testnet"
chmod a+x "$HOME/.local/bin/dash-qt-testnet"
webi_download \
"$WEBI_HOST/packages/dashcore-utils/dashd-hd" \
"$HOME/.local/bin/dashd-hd"
chmod a+x "$HOME/.local/bin/dashd-hd"
webi_download \
"$WEBI_HOST/packages/dashcore-utils/dashd-testnet" \
"$HOME/.local/bin/dashd-testnet"
chmod a+x "$HOME/.local/bin/dashd-testnet"
webi_download \
"$WEBI_HOST/packages/dashcore-utils/dashd-hd-service-install" \
"$HOME/.local/bin/dashd-hd-service-install"
chmod a+x "$HOME/.local/bin/dashd-hd-service-install"
webi_download \
"$WEBI_HOST/packages/dashcore-utils/dashd-testnet-service-install" \
"$HOME/.local/bin/dashd-testnet-service-install"
chmod a+x "$HOME/.local/bin/dashd-testnet-service-install"
if ! test -e "${HOME}/.dashcore"; then
mkdir -p "${HOME}/.dashcore"
chmod 0700 "${HOME}/.dashcore"
fi
if ! test -e "${HOME}/.dashcore/dash.conf"; then
touch "${HOME}/.dashcore/dash.conf"
chmod 0600 "${HOME}/.dashcore/dash.conf"
fi
webi_download \
"$WEBI_HOST/packages/dashcore-utils/dash.example.conf" \
"$HOME/.dashcore/dash.example.conf"
if ! grep -q rpcuser ~/.dashcore/dash.conf; then
cat ~/.dashcore/dash.example.conf >> ~/.dashcore/dash.conf
cmd_sed="sed -i -E"
my_bsd_sed=''
if ! sed -V 2>&1 | grep -q 'GNU'; then
cmd_sed="sed -i .dascore-utils-bak -E"
my_bsd_sed='true'
fi
my_user="$(
id -u -n
)"
my_main_pass="$(xxd -l16 -ps /dev/urandom)"
my_test_pass="$(xxd -l16 -ps /dev/urandom)"
my_regtest_pass="$(xxd -l16 -ps /dev/urandom)"
$cmd_sed "s/RPCUSER_MAIN/${my_user}/" ~/.dashcore/dash.conf
$cmd_sed "s/RPCPASS_MAIN/${my_main_pass}/" ~/.dashcore/dash.conf
$cmd_sed "s/RPCUSER_TEST/${my_user}-test/" ~/.dashcore/dash.conf
$cmd_sed "s/RPCPASS_TEST/${my_test_pass}/" ~/.dashcore/dash.conf
$cmd_sed "s/RPCUSER_REGTEST/${my_user}-regtest/" ~/.dashcore/dash.conf
$cmd_sed "s/RPCPASS_REGTEST/${my_regtest_pass}/" ~/.dashcore/dash.conf
if test -n "${my_bsd_sed}"; then
rm -f ~/.dashcore/dash.conf.dascore-utils-bak
fi
fi
export PATH="$HOME/.local/opt/dashcore/bin:$PATH"
if ! command -v dashd > /dev/null ||
! command -v dash-qt > /dev/null; then
"$HOME/.local/bin/webi" dashcore
fi
# Always try to correct the permissions due to
# https://github.com/dashpay/dash/issues/5420
chmod -R og-rwx "${HOME}/.dashcore/" || true
}
__install_dashcore_utils

View File

@@ -1,189 +0,0 @@
---
title: Dash Core Desktop Wallet
homepage: https://github.com/dashpay/dash
tagline: |
Dash Core is the Desktop Wallet for Digital Cash (DASH)
---
To update or switch versions, run `webi dashcore@stable` (or `@v19`, `@beta`,
etc).
### System Requirements
- 50GB Free Storage (100GB recommended)
- 4GB RAM (8GB recommended)
- 4 hours for initial sync
### Files
These are the files / directories that are created and/or modified with this
install:
```txt
~/.config/envman/PATH.env
~/.local/opt/dashcore/
# For convenience
~/.local/bin/dash-qt-hd
~/.local/bin/dash-qt-testnet
# Linux
~/.dashcore/settings.json
~/.dashcore/testnet3/
# macOS
~/Library/Application Support/DashCore/settings.json
~/Library/Application Support/DashCore/testnet3/
~/Library/Saved Application State/org.dash.Dash-Qt.savedState
~/Library/Preferences/org.dash.Dash-Qt.plist
```
[`dashcore-utils`](../dashcore-utils/) will also be installed if not present.
## Cheat Sheet
> _DASH_ (portmanteau of _Digital Cash_) is an international currency. _Dash
> Core_ is the original suite of tools for _Dash_, maintained by DCG.
The original tools include:
- `dash-qt` - a _Desktop Wallet_ for sending and receiving money
- [`dashd`](../dashd/) - the [_Full Node_](../dashd/) server daemon \
(for APIs, servers, and such)
- `dash-cli` - send RPC commands (same as the dash-qt command console)
- `dash-tx` - create and debug raw (hex) transactions
- `dash-wallet` - interact with wallet files offline
The webi installer also includes two convenience wrapper scripts:
- `dash-qt-hd`
- `dash-qt-testnet`
To open an existing (or create a new) Dash Desktop Wallet:
```sh
dash-qt \
-usehd \
-walletdir="$HOME/.config/dashcore/wallets/" \
-settings="$HOME/.config/dashcore/settings.json" \
-datadir="$HOME/.dashcore/_data/" \
-blocksdir="$HOME/.dashcore/_caches/"
```
Or pass `-testnet` to use with _TestNet_:
```sh
dash-qt \
-testnet \
-usehd \
-walletdir="$HOME/.config/dashcore/wallets/" \
-settings="$HOME/.config/dashcore/settings.json" \
-datadir="$HOME/.dashcore/_data/" \
-blocksdir="$HOME/.dashcore/_caches/"
```
### IMPORTANT: How to NOT Lose Money!
`dash-qt-hd` should be preferred to `dash-qt`.
For historical reasons, `dash-qt` uses **lossy keys** by default!
This is very dangerous - without a Wallet Phrase to recover HD Keys, file
corruption (or losing the device) can lead to losing money permanently.
To avoid this you may use `dash-qt-hd`, or create your wallet with `-usehd`
(optionally with `-mnemonic=<wallet phrase>` if you'd like to recover an
existing wallet), or `upgradetohd`.
### How to Convert from Lossy to HD
If you used `dash-qt` without `-usehd` and already created a wallet, you can fix
it from the command console, which can be found in _Window => Console_.
```text
# Usage
# upgradetohd [wallet phrase] [legacy salt] <wallet encryption phrase>
# Example
upgradetohd "" "" "correct horse battery staple"
# Example with the "zoomonic" and a legacy salt
upgradetohd "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong" \
"TREZOR" "correct horse battery staple"
```
It's a good idea to back up your wallet before running the conversion.
For more detail see:
<https://docs.dash.org/en/stable/docs/user/wallets/dashcore/advanced.html>
### How to Separate Caches from Data
You can make your data much safer by separating it from the caches you may need
to delete by setting:
- `-walletdir=` your money!!
- `-settings=` desktop app settings!
- `-conf=` server settings
- `-datadir=` miscellaneous
- `-blocksdir=` generic caches
```sh
dash-qt \
-usehd \
-settings="$HOME/.config/dashcore/settings.json" \
-walletdir="$HOME/.config/dashcore/wallets/" \
-datadir="$HOME/.dashcore/_data/" \
-blocksdir="$HOME/.dashcore/_caches/" \
-enablecoinjoin=1 \
-coinjoinautostart=1 \
-coinjoinrounds=16 \
-coinjoindenomsgoal=10 \
-coinjoindenomshardcap=25
```
### How to Mix with CoinJoin
CoinJoin aids in preventing some bad actors and malicious observers being able
to easily reconstruct details about your transactions from the publicly
available data by creating many excess transactions. \
(be aware, however, that dedicated bad actors can use sophisticated software that
will reveal much of the same information over time)
`dash-qt` does not enable CoinJoin mixing by default.
`dash-qt-hd` does. It runs the following:
```sh
dash-qt \
-usehd \
-enablecoinjoin=1 \
-coinjoinautostart=1 \
-coinjoinrounds=16 \
-coinjoindenomsgoal=10 \
-coinjoindenomshardcap=25
```
The `coinjoindenomsgoal` and `coinjoindenomshardcap` prevent CoinJoin from
splitting coins down into hundreds of small, unusable coins.
### Other Tools
- [`dashphrase`](https://github.com/dashhive/dashphrase-cli) for generating
secure Wallet Phrases
- [`dashsight`](https://github.com/dashhive/dashphrase-cli) for inspecting
balances, transactions, etc via API (without downloading the indexes)
### More Documentation
All of the **command line flags and options** for the Dash Core Desktop Wallet
are documented between these two pages:
- https://docs.dash.org/projects/core/en/stable/docs/dashcore/wallet-arguments-and-commands-dash-qt.html
- https://docs.dash.org/projects/core/en/stable/docs/dashcore/wallet-arguments-and-commands-dashd.html
The **config files** `dash.conf` (mainly for _Full Nodes_) and `settings.json`
(mainly for Desktop Wallets) are documented at:
- <https://github.com/dashpay/dash/blob/master/contrib/debian/examples/dash.conf>
- <https://docs.dash.org/projects/core/en/stable/docs/dashcore/wallet-configuration-file.html>

View File

@@ -1,56 +0,0 @@
#!/usr/bin/env pwsh
####################
# Install dashcore #
####################
# Every package should define these variables
$pkg_cmd_name = "dash-qt"
$pkg_dst_cmd = "$Env:USERPROFILE\.local\opt\dashcore\bin\dash-qt.exe"
$pkg_dst_dir = "$Env:USERPROFILE\.local\opt\dashcore"
$pkg_dst = "$pkg_dst_cmd"
$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\dashcore-v$Env:WEBI_VERSION\bin\dash-qt.exe"
$pkg_src_bin = "$Env:USERPROFILE\.local\opt\dashcore-v$Env:WEBI_VERSION\bin"
$pkg_src_dir = "$Env:USERPROFILE\.local\opt\dashcore-v$Env:WEBI_VERSION"
$pkg_src = "$pkg_src_cmd"
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | out-null
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"
# Fetch archive
IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"))
{
echo "Downloading dashcore from $Env:WEBI_PKG_URL to $pkg_download"
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part"
& move "$pkg_download.part" "$pkg_download"
}
IF (!(Test-Path -Path "$pkg_src_dir"))
{
echo "Installing dashcore"
# TODO: create package-specific temp directory
# Enter tmp
pushd .local\tmp
# Remove any leftover tmp cruft
Remove-Item -Path ".\dashcore*" -Recurse -ErrorAction Ignore
# Unpack archive file into this temporary directory
# Windows BSD-tar handles zip. Imagine that.
echo "Unpacking $pkg_download"
& tar xf "$pkg_download"
# Settle unpacked archive into place
echo "Install Location: $pkg_src_cmd"
Move-Item -Path ".\dashcore*" -Destination "$pkg_src_dir"
# Exit tmp
popd
}
echo "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'"
Remove-Item -Path "$pkg_dst_cmd" -Recurse -ErrorAction Ignore | out-null
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse

View File

@@ -1,81 +0,0 @@
#!/bin/sh
# shellcheck disable=SC2034
# "'pkg_cmd_name' appears unused. Verify it or export it."
__init_dashcore() {
set -e
set -u
####################
# Install dashcore #
####################
# Every package should define these 6 variables
pkg_cmd_name="dash-qt"
pkg_dst_cmd="$HOME/.local/opt/dashcore/bin/dash-qt"
pkg_dst_dir="$HOME/.local/opt/dashcore"
pkg_dst="$pkg_dst_dir"
pkg_src_cmd="$HOME/.local/opt/dashcore-v$WEBI_VERSION/bin/dash-qt"
pkg_src_dir="$HOME/.local/opt/dashcore-v$WEBI_VERSION"
pkg_src="$pkg_src_dir"
# pkg_install must be defined by every package
pkg_install() {
# mv ./dashcore-* ~/.local/opt/dashcore-v0.19.1
mv ./dashcore-* "${pkg_src_dir}"
if ! test -e "${HOME}/.dashcore"; then
mkdir -p "${HOME}/.dashcore"
chmod 0700 "${HOME}/.dashcore" || true
fi
# if ! test -e "${HOME}/.dashcore/dash.conf"; then
# my_main_pass="$(xxd -l16 -ps /dev/urandom)"
# my_test_pass="$(xxd -l16 -ps /dev/urandom)"
# {
# echo '[main]'
# echo "rpcuser=$(id -u -n)"
# echo "rpcpassword=${my_main_pass}"
# echo ''
# echo '[test]'
# echo "rpcuser=$(id -u -n)-test"
# echo "rpcpassword=${my_test_pass}"
# echo ''
# } >> "${HOME}/.dashcore/dash.conf"
# chmod 0600 "${HOME}/.dashcore/dash.conf" || true
# fi
# if ! test -e "${HOME}/.dashcore/settings.json"; then
# echo '{}' >> "${HOME}/.dashcore/settings.json"
# chmod 0600 "${HOME}/.dashcore/settings.json" || true
# fi
if ! test -e "$HOME/.local/bin/dash-qt-hd" ||
! test -e "$HOME/.local/bin/dash-qt-testnet"; then
"$HOME/.local/bin/webi" dashcore-utils
fi
# Always try to correct the permissions due to
# https://github.com/dashpay/dash/issues/5420
chmod -R og-rwx "${HOME}/.dashcore/" || true
}
# pkg_get_current_version is recommended, but not required
pkg_get_current_version() {
# 'dash-qt' doesn't have version info, so we use 'dashd'
# 'dashd --version' has output in this format:
# Dash Core Daemon version v19.1.0
# This trims it down to just the version number:
# 19.1.0
dashd --version 2> /dev/null |
head -n 1 |
cut -d ' ' -f 5 |
sed 's:^v::'
}
}
__init_dashcore

View File

@@ -1,28 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'dashpay';
var repo = 'dash';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all.releases = all.releases.filter(function (rel) {
return !rel.name.endsWith('.asc');
});
all.releases.forEach(function (rel) {
if (rel.name.includes('osx64')) {
rel.os = 'macos';
}
});
return all;
});
};
if (module === require.main) {
module.exports(require('@root/request')).then(function (all) {
all = require('../_webi/normalize.js')(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,310 +0,0 @@
---
title: Dash Core Full Node Daemon
homepage: https://github.com/dashpay/dash
tagline: |
dashd is the Full Node service for Digital Cash (DASH)
---
To update or switch versions, run `webi dashd@stable` (or `@v0.19`, `@beta`,
etc).
### Recommended Hardware
- 100GB+ Block Storage
- 8GB RAM
- 4 vCPUs
- **30 hours** for initial indexing
### Files
These are the files / directories that are created and/or modified with this
install:
```txt
~/.config/envman/PATH.env
~/.dashcore/dash.conf
~/.dashcore/wallets/
~/.local/bin/bin/dashd-hd-service-install
~/.local/opt/dashcore/
/mnt/<BLK_VOL>/dashcore/
```
[`dashcore-utils`](../dashcore-utils/) will also be installed if not present.
## Cheat Sheet
> A DASH _Full Node_ syncs and indexes the DASH blockchain and can be used to
> broadcast transactions (sending money) and retrieve information about
> transactions, balances, etc. This "Dash Core" implementation is maintained by
> DCG.
To install as **a system service** with reasonable defaults, \
you can use these convenience scripts provided by Webi:
```sh
# USAGE
# dashd-hd-service-install [storage-volume] [testnet]
#
# EXAMPLE
dashd-hd-service-install
```
### QuickStart
0. Check that you have enough Storage and RAM
- mainnet: 100GB+ Storage, 8GB RAM
- testnet: 20GB+ Storage, 2GB RAM
1. Create a mount for your storage volume
```sh
sudo mkdir -p /mnt/100gb-vol/
sudo mount /dev/vda1 /mnt/100gb-vol/
```
2. Create a correctly permissioned `dashcore` directory
```sh
sudo mkdir -p /mnt/100g-vol/dashcore/
sudo chown -R "$(id -u -n):$(id -g -n)" /mnt/100gb-vol/dashcore/
```
3. Register `dashd` with the system launcher
```sh
dashd-hd-service-install
```
4. Wait **about 30 hours** for initial sync and indexing to complete
5. Test with the DashCore CLI
```sh
dash-cli getaddresstxids '{
"addresses": ["XchrTJFPGFiror4zjXQRR7XTSN25YtLYhC"],
"start": 0,
"end":1000000000
}'
```
### How to use DashCore CLI
After it completes the initial sync (about 4 hours), \
you can query address information:
```sh
# Balances
dash-cli getaddressbalance '{"addresses": ["XchrTJFPGFiror4zjXQRR7XTSN25YtLYhC"]}'
# UTXOs
dash-cli getaddressutxos '{"addresses": ["XpLVjhDd6vNJamtcJXcrpQYA1sE6fmxVDa"]}'
# TXes
dash-cli getaddresstxids '{
"addresses": ["XchrTJFPGFiror4zjXQRR7XTSN25YtLYhC"],
"start": 0,
"end":1000000000
}'
# Broadcast TX
dash-cli -testnet sendrawtransaction 01000000...0c0226b428a488ac00000000
```
### How to Run dashd Manually
To run **in the foreground**: \
(add `-testnet` to run on testnet)
```sh
dashd \
-usehd \
-conf="$HOME/.dashcore/dash.conf" \
-settings="$HOME/.dashcore/settings.json" \
-walletdir="$HOME/.dashcore/wallets/" \
-datadir="/mnt/100gb/dashcore/_data/" \
-blocksdir="/mnt/100gb/dashcore/_caches/" \
-addressindex=1 \
-timestampindex=1 \
-txindex=1 \
-spentindex=1
```
**Warning**: killing the process with ctrl+c before the first full sync may
corrupt the data and require starting over (see below)
### Server Requirements
150MB for Applications on OS Storage
For **mainnet**:
- 100GB Block Storage Volume \
- minimum of 40GB (blockchain) + 50GB (indexes) as of 2023
- plus 4-8GB per year
- 8GB RAM \
(min 4GB RAM + 4GB swap, otherwise it crashes during indexing)
- 4 vCPUs \
(min 2x 2.0GHz vCPUs, higher clock speed is better than more cors)
- 100 megabit network
- 28-30 hours to sync and index in ideal conditions
- minimum of 4 hours to sync
- approximately 28 hours to index regardless of sync time
For **testnet**:
- 20GB Block Storage Volume \
- min 4GB (blockchain) + 5 GB (indexes) as of 2022
- plus 0.5-1GB/year
- 2GB RAM
- 1 vCPU
- 4 hours to sync and index in ideal conditions
- 1 hour to sync
- about 4 hours to index regardless of sync time
### How to configure `dash.conf`
You can set options for `main`, `test`, and `regtest`.
If you intend to use the various RPCs you must enable indexes.
```ini
txindex=1
addressindex=1
timestampindex=1
spentindex=1
[main]
rpcuser=alice
rpcpassword=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
bind=127.0.0.1:9999
rpcbind=127.0.0.1:9998
rpcconnect=127.0.0.1:9998
rpcallowip=127.0.0.1/16
zmqpubrawtx=tcp://127.0.0.1:28332
zmqpubrawtxlock=tcp://127.0.0.1:28332
zmqpubrawchainlock=tcp://127.0.0.1:28332
zmqpubhashchainlock=tcp://127.0.0.1:28332
[test]
rpcuser=alice-test
rpcpassword=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
bind=127.0.0.1:19999
rpcbind=127.0.0.1:19998
rpcconnect=127.0.0.1:19998
rpcallowip=127.0.0.1/16
zmqpubrawtx=tcp://127.0.0.1:18009
zmqpubrawtxlock=tcp://127.0.0.1:18009
zmqpubrawchainlock=tcp://127.0.0.1:18009
zmqpubhashchainlock=tcp://127.0.0.1:18009
```
See also:
- [dash: examples/dash.conf](https://github.com/dashpay/dash/blob/549e347b742cb4dc63807a292729e658218d7d0f/contrib/debian/examples/dash.conf#L2)
- [dashd: Indexing Options](https://docs.dash.org/projects/core/en/19.0.0/docs/dashcore/wallet-arguments-and-commands-dashd.html#indexing-options)
### How to Separate Caches from Data
You can make your data much safer by separating it from the caches you may need
to delete by setting:
- `-walletdir=` your money!!
- `-settings=` desktop app settings!
- `-conf=` server settings
- `-datadir=` generic caches
```sh
dashd \
-usehd \
-conf="$HOME/.config/dashcore/dash.conf" \
-walletdir="$HOME/.config/dashcore/wallets/" \
-datadir="/mnt/dashcore/dashcore/"
```
### How to Run as a System Service
You can use [`serviceman`](../serviceman/):
**Linux**
```sh
sudo env PATH="$PATH" \
serviceman add \
--system \
--username "$(id -n -u)" \
--path "$PATH" \
--name dashd \
--force \
-- \
dashd \
-usehd \
-conf="$HOME/.dashcore/dash.conf" \
-settings="$HOME/.dashcore/settings.json" \
-walletdir="$HOME/.dashcore/wallets/" \
-datadir="/mnt/100gb/dashcore/_data/" \
-blocksdir="/mnt/100gb/dashcore/_caches/"
```
**Mac**
```sh
serviceman add \
--path "$PATH" \
--name dashd \
--force \
-- \
dashd \
-usehd \
-conf="$HOME/.dashcore/dash.conf" \
-settings="$HOME/.dashcore/settings.json" \
-walletdir="$HOME/.dashcore/wallets/" \
-datadir="/Volumes/100gb/dashcore/_data/" \
-blocksdir="/Volumes/100gb/dashcore/_caches/"
```
**Windows**
(be sure modify variables appropriately for `cmd.exe` or `powershell`)
```sh
& serviceman add \
--name dashd \
--force \
-- \
dashd \
-usehd \
-conf="$Env:UserProfile/.dashcore/dash.conf" \
-settings="$Env:UserProfile/.dashcore/settings.json" \
-walletdir="$Env:UserProfile/.dashcore/wallets/" \
-datadir="D:/100gb/dashcore/_data/" \
-blocksdir="D:/100gb/dashcore/_caches/"
```
### How to Trim Excessive Storage
If the service **crashes** during the initial syncing and indexing (such as when
using less than 4GB RAM + 4GB Swap) it **will not resume** (typically).
Instead it will create duplicate new data, and not clean up the old data.
You may need to **delete /mnt/<BLK_VOL>/dashcore/** and start from scratch
(being careful not to delete any wallet information, if you have any).
Generally I wouldn't recommend storing money on a Full Node -since it's
primarily used for creating APIs for transactions and validations - but if you
do, please always make sure to use `-usehd` and print out your Wallet Phrase as
a failsafe.
### More Tools
In particular, you may find these useful:
- [`dashphrase`](https://github.com/dashhive/dashphrase-cli) for generating
secure Wallet Phrases
- [`dashsight`](https://github.com/dashhive/dashphrase-cli) for inspecting
balances, transactions, etc via API (without downloading the indexes)
### More Documentation
All of the **command line flags and options** for the Dash Core Desktop Wallet
are documented between these two pages:
- https://docs.dash.org/projects/core/en/stable/docs/dashcore/wallet-arguments-and-commands-dash-qt.html
- https://docs.dash.org/projects/core/en/stable/docs/dashcore/wallet-arguments-and-commands-dashd.html
The **config files** `dash.conf` (mainly for _Full Nodes_) and `settings.json`
(mainly for Desktop Wallets) are documented at:
- <https://github.com/dashpay/dash/blob/master/contrib/debian/examples/dash.conf>
- <https://docs.dash.org/projects/core/en/stable/docs/dashcore/wallet-configuration-file.html>

View File

@@ -1,56 +0,0 @@
#!/usr/bin/env pwsh
#################
# Install dashd #
#################
# Every package should define these variables
$pkg_cmd_name = "dashd"
$pkg_dst_cmd = "$Env:USERPROFILE\.local\opt\dashcore\bin\dashd.exe"
$pkg_dst_dir = "$Env:USERPROFILE\.local\opt\dashcore"
$pkg_dst = "$pkg_dst_cmd"
$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\dashcore-v$Env:WEBI_VERSION\bin\dashd.exe"
$pkg_src_bin = "$Env:USERPROFILE\.local\opt\dashcore-v$Env:WEBI_VERSION\bin"
$pkg_src_dir = "$Env:USERPROFILE\.local\opt\dashcore-v$Env:WEBI_VERSION"
$pkg_src = "$pkg_src_cmd"
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | out-null
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"
# Fetch archive
IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"))
{
echo "Downloading dashd from $Env:WEBI_PKG_URL to $pkg_download"
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part"
& move "$pkg_download.part" "$pkg_download"
}
IF (!(Test-Path -Path "$pkg_src_dir"))
{
echo "Installing dashd"
# TODO: create package-specific temp directory
# Enter tmp
pushd .local\tmp
# Remove any leftover tmp cruft
Remove-Item -Path ".\dashcore*" -Recurse -ErrorAction Ignore
# Unpack archive file into this temporary directory
# Windows BSD-tar handles zip. Imagine that.
echo "Unpacking $pkg_download"
& tar xf "$pkg_download"
# Settle unpacked archive into place
echo "Install Location: $pkg_src_cmd"
Move-Item -Path ".\dashcore*" -Destination "$pkg_src_dir"
# Exit tmp
popd
}
echo "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'"
Remove-Item -Path "$pkg_dst_cmd" -Recurse -ErrorAction Ignore | out-null
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse

View File

@@ -1,74 +0,0 @@
#!/bin/sh
# shellcheck disable=SC2034,2317
# "'pkg_cmd_name' appears unused. Verify it or export it."
# "Command appears to be unreachable."
__init_dashd() {
set -e
set -u
#################
# Install dashd #
#################
# Every package should define these 6 variables
pkg_cmd_name="dashd"
pkg_dst_cmd="$HOME/.local/opt/dashcore/bin/dashd"
pkg_dst_dir="$HOME/.local/opt/dashcore"
pkg_dst="$pkg_dst_dir"
pkg_src_cmd="$HOME/.local/opt/dashcore-v$WEBI_VERSION/bin/dashd"
pkg_src_dir="$HOME/.local/opt/dashcore-v$WEBI_VERSION"
pkg_src="$pkg_src_dir"
# pkg_install must be defined by every package
pkg_install() {
# mv ./dashcore-* ~/.local/opt/dashcore-v0.19.1
mv ./dashcore-* "${pkg_src_dir}"
if ! test -e "${HOME}/.dashcore"; then
mkdir -p "${HOME}/.dashcore"
chmod 0700 "${HOME}/.dashcore"
fi
if ! test -e "$HOME/.local/bin/dashd-hd-service-install" ||
! test -e "$HOME/.local/bin/dashd-testnet-service-install"; then
"$HOME/.local/bin/webi" dashcore-utils
fi
# Always try to correct the permissions due to
# https://github.com/dashpay/dash/issues/5420
chmod -R og-rwx "${HOME}/.dashcore/" || true
}
pkg_done_message() {
echo "Installed 'dashd@v$WEBI_VERSION' to ~/.local/opt/dashcore/"
echo ""
echo "TO START THE DAEMON"
echo ""
echo " # mainnet"
echo " dashd-hd-service-install"
echo ""
echo ""
echo " # testnet"
echo " dashd-testnet-service-install"
echo ""
}
# pkg_get_current_version is recommended, but not required
pkg_get_current_version() {
# 'dashd --version' has output in this format:
# Dash Core Daemon version v19.1.0
# This trims it down to just the version number:
# 19.1.0
dashd --version 2> /dev/null |
head -n 1 |
cut -d ' ' -f 5 |
sed 's:^v::'
}
}
__init_dashd

View File

@@ -1,3 +0,0 @@
'use strict';
module.exports = require('../dashcore/releases.js');

View File

@@ -34,7 +34,7 @@ dashmsg gen > pirv.wif
dashmsg sign ./priv.wif 'vote2022-alice|bob|charlie'
```
```text
```txt
H2Opy9NX72iPZRcDVEHrFn2qmVwWMgc+DKILdVxl1yfmcL2qcpu9esw9wcD7RH0/dJHnIISe5j39EYahorWQM7I=
```
@@ -58,7 +58,7 @@ Addresses:
dashmsg inspect 'XK5DHnAiSj6HQNsNcDkawd9qdp8UFMdYftdVZFuRreTMJtbJhk8i'
```
```text
```txt
PrivateKey (hex): cc (coin type)
: e84f59fec1c8cc7feb9ce1c829849ae336f73e56437301eb5db945c8e0dd2683
: 01 (compressed)
@@ -76,7 +76,7 @@ Address (b58c): Xn4A2vv5fb7LvmiiXPPMexYbSbiQ29rzDu
dashmsg inspect 'IFLv0JVRM70bTZCTmzMfNX3NVkSULmnAR/3PSWpgC5GXBD7rRi5g4QsK968ITE3dfKdzhX7fAIXwhpnsP0WvQOc='
```
```text
```txt
I (0): 1 (quadrant)
R (1-32): 52efd0955133bd1b4d90939b331f357dcd5644942e69c047fdcf496a600b9197
S (33-64): 043eeb462e60e10b0af7af084c4ddd7ca773857edf0085f08699ec3f45af40e7
@@ -88,7 +88,7 @@ S (33-64): 043eeb462e60e10b0af7af084c4ddd7ca773857edf0085f08699ec3f45af40e7
dashmsg inspect 'Xn4A2vv5fb7LvmiiXPPMexYbSbiQ29rzDu'
```
```text
```txt
Address (hex): 4c (coin type)
: 7cb1500163c8d413314dc238f9268b6c723a48f0
```

View File

@@ -9,17 +9,6 @@ To update or switch versions, run `webi delta` (or `@0.9.1`, `@0.9.0`, etc).
**Note**: You should install [git](./git) before installing `delta`.
### Files
These are the files that are created and/or modified with this installer:
```text
~/.config/envman/PATH.env
~/.gitconfig
~/.local/bin/delta
~/.local/opt/delta-VERSION/bin/delta
```
## Cheat Sheet
> `delta` gives you GitHub-style diffs, with word-level diff coloring, right in
@@ -37,6 +26,17 @@ Here we'll cover:
For the full set of options, be sure to check out the helpful
[README](https://github.com/dandavison/delta).
## Files
These are the files that are created and/or modified with this installer:
```txt
~/.config/envman/PATH.env
~/.gitconfig
~/.local/bin/delta
~/.local/opt/delta-VERSION/bin/delta
```
## How to set delta's color scheme
Delta uses `~/.gitconfig` for most of its options.
@@ -73,7 +73,7 @@ Here's the current list, for convenience:
### Dark Syntax Themes
```text
```txt
1337
Coldark-Cold
Coldark-Dark
@@ -97,7 +97,7 @@ zenburn
### Light Syntax Themes
```text
```txt
GitHub
Monokai Extended Light
OneHalfLight

View File

@@ -38,3 +38,6 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERS
echo "Copying into '$Env:USERPROFILE\.local\bin\$Env:PKG_NAME.exe' from '$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERSION.exe'"
Remove-Item -Path "$Env:USERPROFILE\.local\bin\$Env:PKG_NAME.exe" -Recurse -ErrorAction Ignore
Copy-Item -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERSION.exe" -Destination "$Env:USERPROFILE\.local\bin\$Env:PKG_NAME.exe" -Recurse
# Add to path
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/bin

View File

@@ -67,7 +67,7 @@ dotenv-linter --skip QuoteCharacter --skip UnorderedKey
You can see the full list of linter rules with `dotenv-linter --show-checks`:
```text
```txt
DuplicatedKey
EndingBlankLine
ExtraBlankLine

View File

@@ -31,7 +31,7 @@ dotenv -f .env -- node server.js --debug
## ENV syntax
```text
```txt
# comments and blank lines are ignored
# you can use quotes of either style

View File

@@ -1,98 +0,0 @@
---
title: DuckDNS.sh
homepage: https://github.com/BeyondCodeBootcamp/DuckDNS.sh
tagline: |
DuckDNS.sh: Dynamic DNS updater for https://duckdns.org. Works on all POSIX*ish* systems (Mac, Linux, Docker, BSD, etc).
---
To update or switch versions, run `webi duckdns.sh@stable` (or `@v1.0.3`,
`@beta`, etc).
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/.config/envman/PATH.env
~/.local/bin/duckdns.sh
~/.config/duckdns.sh/
```
## Cheat Sheet
> DuckDNS.sh (`duckdns.sh`) is the best Dynamic DNS client to date. Not only
> does it have some nice sub commands and work on all Posix systems, but it can
> also register itself with your system launcher - `systemd` on Linux and
> `launchctl` on macOS.
Paste your token from [duckdns.org](https://duckdns.org) to start.
```sh
# duckdns.sh auth <subdomain>
# duckdns.sh auth foobar # do NOT include '.duckdns.org'
```
Set to launch on login (Mac) or on boot (Linux)
```sh
# duckdns.sh enable <subdomain>
duckdns.sh enable foobar
```
### Usage
Use `-v` to filter out all matches so that only non-matches are left.
```sh
USAGE
duckdns.sh <subcommand> [arguments...]
SUBCOMMANDS
myip - show this device's ip(s)
ip <subdomain> - show subdomain's ip(s)
list - show subdomains
auth <subdomain> - add Duck DNS token
update <subdomain> - update subdomain to device ip
set <subdomain> <ip> [ipv6] - set ipv4 and/or ipv6 explicitly
clear <subdomain> - unset ip(s)
run <subdomain> - check ip and update every 5m
enable <subdomain> - enable on boot (Linux) or login (macOS)
disable <subdomain> - disable on boot or login
help - show this menu
version - show version and exit
```
### How to check your current IP address
```sh
duckdns.sh myip
```
This is the same as
```sh
curl -fsSL 'https://api.ipify.org?format=text'
curl -fsSL 'https://api64.ipify.org?format=text'
```
### How to check your domain's current DNS records
```sh
duckdns.sh ip foobar
```
This is the same as
```sh
dig +short A foobar.duckdns.org
dig +short AAAA foobar.duckdns.org
```
### How to manually set your domain's DNS records
```sh
duckdns.sh set foobar 127.0.0.1 ::1
```

View File

@@ -1,41 +0,0 @@
#!/bin/sh
set -e
set -u
__init_duckdns_sh() {
######################
# Install duckdns.sh #
######################
# Every package should define these 6 variables
pkg_cmd_name="duckdns.sh"
pkg_dst_cmd="$HOME/.local/bin/duckdns.sh"
pkg_dst="$pkg_dst_cmd"
pkg_src_cmd="$HOME/.local/opt/duckdns.sh-v$WEBI_VERSION/bin/duckdns.sh"
pkg_src_dir="$HOME/.local/opt/duckdns.sh-v$WEBI_VERSION"
pkg_src="$pkg_src_cmd"
# pkg_install must be defined by every package
pkg_install() {
# ~/.local/opt/duckdns.sh-v1.0.3/bin
mkdir -p "$(dirname "$pkg_src_cmd")"
# mv ./*DuckDNS.sh*/duckdns.sh ~/.local/opt/duckdns.sh-v1.0.3/bin/duckdns.sh
mv ./*DuckDNS.sh*/duckdns.sh "$pkg_src_cmd"
}
# pkg_get_current_version is recommended, but (soon) not required
pkg_get_current_version() {
# 'duckdns.sh version' has output in this format:
# DuckDNS.sh v1.0.3 (2023-01-15 00:49:52 +0000)
# Copyright 2023 AJ ONeal
# This trims it down to just the version number:
# 1.0.3
duckdns.sh version | head -n 1 | cut -d ' ' -f 2 | sed 's:^v::'
}
}
__init_duckdns_sh

View File

@@ -1,28 +0,0 @@
'use strict';
var githubSource = require('../_common/github-source.js');
var owner = 'BeyondCodeBootcamp';
var repo = 'DuckDNS.sh';
module.exports = function (request) {
let arches = [
'amd64',
'arm64',
'armv6l',
'armv7l',
'ppc64le',
's390x',
'x86',
];
let oses = ['freebsd', 'linux', 'macos', 'posix'];
return githubSource(request, owner, repo, oses, arches).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports(require('@root/request')).then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,15 +0,0 @@
---
title: DuckDNS (DuckDNS.sh alias)
homepage: https://webinstall.dev/duckdns.sh
tagline: |
Alias for https://webinstall.dev/duckdns.sh
alias: duckdns.sh
description: |
See https://webinstall.dev/duckdns.sh
---
`duckdns` is a reserved installer name.
Currently an alias for <https://webinstall.dev/duckdns.sh>.
That may change in the future.

View File

@@ -1,11 +0,0 @@
#!/bin/sh
set -e
set -u
echo "'duckdns@${WEBI_TAG:-stable}' is reserved for future use."
echo
echo "Did you mean 'duckdns.sh@${WEBI_VERSION-}'?"
WEBI_HOST=${WEBI_HOST:-"https://webi.sh"}
echo ""
echo " curl -fsSL '$WEBI_HOST/duckdns.sh@${WEBI_VERSION-}' | sh"
exit 1

View File

@@ -49,5 +49,5 @@ fd -e md -e mkdn -e js -e mjs
For options see:
```sh
fd --help
hexyl --help
```

View File

@@ -19,16 +19,3 @@ that produce the most similar quality by default.
```sh
ffmpeg -i input.m4a output.mp3
```
Important information per https://johnvansickle.com/ffmpeg/release-readme.txt
> Notes: A limitation of statically linking `glibc` is the loss of DNS resolution. Installing `nscd` through your package manager will fix this.
*This is relevant if using ffmpeg to relay to an RTMP server via domain name.*
```sh
# for example, this will not work without `nscd` installed.
ffmpeg -re -stream_loop -1 -i "FooBar.m4v" -c copy -f flv rtmp://stream.example.com/foo/bar
```

View File

@@ -121,7 +121,7 @@ command -v fish
Then update the Terminal preferences:
```text
```txt
Terminal > Preferences > General > Shells open with:
/Users/YOUR_USER/.local/bin/fish
```
@@ -175,8 +175,8 @@ Hyper is configured with JavaScript.
module.exports = {
config: {
// ...
shell: process.env.HOME + '/.local/bin/fish',
},
shell: process.env.HOME + '/.local/bin/fish'
}
};
```

View File

@@ -2,15 +2,7 @@
set -e
set -u
if command -v fish > /dev/null; then
if [ ! -e ~/.config/fish/config.fish ]; then
mkdir -p ~/.config/fish
touch ~/.config/fish/config.fish
chmod 0600 ~/.config/fish/config.fish
fi
fi
if [ "Darwin" != "$(uname -s)" ]; then
if ! (uname -a | grep -i "darwin" > /dev/null); then
echo "No fish installer for Linux yet. Try this instead:"
echo " sudo apt install -y fish"
exit 1
@@ -85,12 +77,6 @@ pkg_post_install() {
# try again to update default shells, now that all files should exist
_macos_post_install
if [ ! -e ~/.config/fish/config.fish ]; then
mkdir -p ~/.config/fish
touch ~/.config/fish/config.fish
chmod 0600 ~/.config/fish/config.fish
fi
}
# pkg_get_current_version is recommended, but (soon) not required

View File

@@ -5,7 +5,7 @@ var map = {};
module.exports = function (request) {
var all = {
download: '',
releases: [],
releases: []
};
return Promise.all(
['macos', 'linux', 'windows'].map(function (osname) {
@@ -14,7 +14,7 @@ module.exports = function (request) {
'https://storage.googleapis.com/flutter_infra/releases/releases_' +
osname +
'.json',
json: true,
json: true
}).then(function (resp) {
var body = resp.body;
all.download = body.base_url + '/{{ download }}';
@@ -31,11 +31,11 @@ module.exports = function (request) {
os: osname,
arch: 'amd64',
hash: '-', // not sure about including hash / sha256 yet
download: asset.archive,
download: asset.archive
});
});
});
}),
})
).then(function () {
all.releases.sort(function (a, b) {
if ('stable' === a.channel && a.channel !== b.channel) {

View File

@@ -29,6 +29,6 @@ sudo journalctl -u my-app-name --since '2020-01-01' | fzf
### Use space-delimited regular expressions to search
```text
```txt
^README | .md$ | .txt$
```

View File

@@ -29,7 +29,7 @@ git-config-gpg
Example output:
```text
```txt
GnuPG Public Key ID: CA025BC42F00BBBE
-----BEGIN PGP PUBLIC KEY BLOCK-----
@@ -55,7 +55,7 @@ How to verify signed commits on GitHub:
These are the files / directories that are created and/or modified with this
install:
```text
```txt
~/.config/envman/PATH.env
~/.local/bin/git-config-gpg
~/Downloads/YOU.KEY_ID.gpg.asc
@@ -75,7 +75,7 @@ set it to 400 days and call it good.
`~/.gnupg/gpg-agent.conf`:
```text
```txt
default-cache-ttl 34560000
max-cache-ttl 34560000
```
@@ -137,7 +137,7 @@ Or, if you prefer to edit the text file directly:
`~/.gitconfig`
```text
```txt
[user]
signingkey = CA025BC42F00BBBE
[commit]
@@ -153,7 +153,7 @@ versions of gpg, like so:
git config --global gpg.program ~/.local/opt/gnupg/bin/gpg
```
```text
```txt
[gpg]
program = /Users/me/.local/opt/gnupg/bin/gpg
```
@@ -163,7 +163,7 @@ git config --global gpg.program ~/.local/opt/gnupg/bin/gpg
`gpg` is generally expected to be used with a Desktop client. On Linux servers
you may get this error:
```text
```txt
error: gpg failed to sign the data
fatal: failed to write commit object
```

View File

@@ -29,7 +29,7 @@ git commit -m "my summary for this commit"
In your project repository create a `.gitignore` file with patterns of fies to
ignore
```text
```txt
.env*
*.bak
*.tmp

View File

@@ -53,4 +53,6 @@ Remove-Item -Path "$pkg_dst" -Recurse -ErrorAction Ignore
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse
# Add to path
webi_path_add ~/.local/opt/git/cmd
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/opt/git/cmd
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add "$Env:USERPROFILE\.local\opt\git\cmd"
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add %USERPROFILE%\.local\opt\git\cmd

View File

@@ -5,7 +5,7 @@ set -u
__init_git() {
if [ -z "$(command -v git)" ]; then
if [ "Darwin" = "$(uname -s)" ]; then
if uname -a | grep -q -i darwin; then
echo >&2 "Error: 'git' not found. You may have to re-install 'git' on Mac after every major update."
echo >&2 " for example, try: xcode-select --install"
# sudo xcodebuild -license accept

View File

@@ -59,7 +59,7 @@ repository's URL, like this:
The deploy scripts should exist in your `scripts/` directory, named after the
repo's name.
```text
```txt
scripts/github.com/YOUR_ORG/YOUR_PROJECT/deploy.sh
```

View File

@@ -3,9 +3,9 @@ set -e
set -u
__redirect_alias_gpg() {
echo "'gnupg@${WEBI_TAG:-stable}' is an alias for 'gpg@${WEBI_VERSION-}'"
echo "'gnupg@${WEBI_TAG:-stable}' is an alias for 'gpg@${WEBI_VERSION:-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/gpg@${WEBI_VERSION-}" | sh
curl -fsSL "$WEBI_HOST/gpg@${WEBI_VERSION:-}" | sh
}
__redirect_alias_gpg

View File

@@ -1,66 +1,5 @@
#!/usr/bin/env pwsh
#!/bin/pwsh
if (!(Get-Command "go.exe" -ErrorAction SilentlyContinue))
{
& "$Env:USERPROFILE\.local\bin\webi-pwsh.ps1" go
# because we need git.exe to be available to golang immediately
$Env:PATH = "$Env:USERPROFILE\go\bin;$Env:USERPROFILE\.local\opt\go\bin;$Env:PATH"
}
# Special to go: re-run all go tooling builds
echo "Building go language tools..."
echo ""
echo godoc
& go install golang.org/x/tools/cmd/godoc@latest
echo ""
echo gopls
& go install golang.org/x/tools/gopls@latest
echo ""
echo guru
& go install golang.org/x/tools/guru@latest
echo ""
echo golint
& go install golang.org/x/lint/golint@latest
#echo ""
#echo errcheck
#& go install github.com/kisielk/errcheck
#echo ""
#echo gotags
#& go install github.com/jstemmer/gotags
echo ""
echo goimports
& go install golang.org/x/tools/cmd/goimports@latest
echo ""
echo gomvpkg
& go install golang.org/x/tools/cmd/gomvpkg@latest
echo ""
echo gorename
& go install golang.org/x/tools/cmd/gorename
echo ""
echo gotype
& go install golang.org/x/tools/cmd/gotype
echo ""
echo stringer
& go install golang.org/x/tools/cmd/stringer
echo ""
# literal %USERPROFILE% on purpose
echo 'Installed go "x" tools to GOBIN=%USERPROFILE%/go/bin'
echo ""
echo "Suggestion: Also check out these great productivity multipliers:"
echo ""
echo " - vim-essentials (sensible defaults for vim)"
echo " - vim-go (golang linting, etc)"
echo ""
echo "'go@$Env:WEBI_TAG' is an alias for 'golang@$Env:WEBI_VERSION'"
IF ($Env:WEBI_HOST -eq $null -or $Env:WEBI_HOST -eq "") { $Env:WEBI_HOST = "https://webinstall.dev" }
curl.exe -fsSL "$Env:WEBI_HOST/golang@$Env:WEBI_VERSION" | powershell

View File

@@ -3,7 +3,9 @@ set -e
set -u
__run_go_essentials() {
if command -v go 2> /dev/null; then
WEBI__GO_ESSENTIALS='true'
export WEBI__GO_ESSENTIALS
if [ -z "${WEBI__GO_INSTALL:-}" ]; then
"$HOME/.local/bin/webi" "golang@${WEBI_TAG}"
fi
@@ -73,9 +75,6 @@ __run_go_essentials() {
go "${my_install}" golang.org/x/tools/cmd/stringer@latest > /dev/null #2>/dev/null
echo ""
# literal $HOME on purpose
# shellcheck disable=SC2016
echo 'Installed go "x" tools to GOBIN=$HOME/go/bin'
printf '\n'
printf 'Suggestion: Also check out these great productivity multipliers:\n'

View File

@@ -1,89 +1,11 @@
---
title: Go
homepage: https://golang.org
title: Go (golang alias)
homepage: https://webinstall.dev/golang
tagline: |
Go makes it easy to build simple, reliable, and efficient software.
Alias for https://webinstall.dev/golang
alias: golang
description: |
See https://webinstall.dev/golang
---
To update or switch versions, run `webi go@stable` (or `@v1.21`, `@beta`, etc).
### Files
```text
~/.config/envman/PATH.env
~/.local/opt/go/
~/go/
```
## Cheat Sheet
> Go is designed, through and through, to make Software Engineering easy. It's
> fast, efficient, reliable, and something you can learn in a weekend.
>
> If you subscribe to
> [_The Zen of Python_](https://www.python.org/dev/peps/pep-0020/), you'll
> [love](https://go-proverbs.github.io/) >
> [Go](https://www.youtube.com/watch?v=PAAkCSZUG1c).
You may also want to install the Go IDE tooling:
[go-essentials](/go-essentials).
### Hello World
1. Make and enter your project directory
```sh
mkdir -p ./hello/cmd/hello
pushd ./hello/
```
2. Initialize your `go.mod` to your _git repository_ url:
```sh
go mod init github.com/example/hello
```
3. Create a `hello.go`
```sh
cat << EOF >> ./cmd/hello/hello.go
package main
import (
"fmt"
)
func main () {
fmt.Println("Hello, World!")
}
EOF
```
4. Format, build, and run your `./hello`
```sh
go fmt ./...
go build -o hello ./cmd/hello/
./hello
```
You should see your output:
```text
> Hello, World!
```
### How to run a Go program as a service
On Linux:
```sh
# Install serviceman (compatible with systemd)
webi serviceman
```
```sh
# go into your programs 'opt' directory
pushd ./hello/
# swap 'hello' and './hello' for the name of your project and binary
sudo env PATH="$PATH" \
serviceman add --system --username "$(whoami)" --name hello -- \
./hello
# Restart the logging service
sudo systemctl restart systemd-journald
```
Alias for https://webinstall.dev/golang

View File

@@ -1,63 +1,5 @@
#!/usr/bin/env pwsh
#!/bin/pwsh
$pkg_cmd_name = "go"
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | out-null
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"
$pkg_src = "$Env:USERPROFILE\.local\opt\$pkg_cmd_name-v$Env:WEBI_VERSION"
$pkg_dst = "$Env:USERPROFILE\.local\opt\$pkg_cmd_name"
$pkg_dst_cmd = "$pkg_dst\bin\$pkg_cmd_name"
$pkg_dst_bin = "$pkg_dst\bin"
if (!(Get-Command "git.exe" -ErrorAction SilentlyContinue))
{
& "$Env:USERPROFILE\.local\bin\webi-pwsh.ps1" git
# because we need git.exe to be available to golang immediately
$Env:PATH = "$Env:USERPROFILE\.local\opt\git\cmd;$Env:PATH"
}
# Fetch archive
IF (!(Test-Path -Path "$pkg_download"))
{
echo "Downloading $Env:PKG_NAME from $Env:WEBI_PKG_URL to $pkg_download"
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part"
& move "$pkg_download.part" "$pkg_download"
}
IF (!(Test-Path -Path "$pkg_src"))
{
echo "Installing $pkg_cmd_name"
# TODO: temp directory
# Enter opt
pushd .local\tmp
# Remove any leftover tmp cruft
Remove-Item -Path "$pkg_cmd_name*" -Recurse -ErrorAction Ignore
# Unpack archive
# Windows BSD-tar handles zip. Imagine that.
echo "Unpacking $pkg_download"
& tar xf "$pkg_download"
# Settle unpacked archive into place
echo "New Name: $pkg_cmd_name-v$Env:WEBI_VERSION"
Get-ChildItem "$pkg_cmd_name*" | Select -f 1 | Rename-Item -NewName "$pkg_cmd_name-v$Env:WEBI_VERSION"
echo "New Location: $pkg_src"
Move-Item -Path "$pkg_cmd_name-v$Env:WEBI_VERSION" -Destination "$Env:USERPROFILE\.local\opt"
# Exit tmp
popd
}
echo "Copying into '$pkg_dst' from '$pkg_src'"
Remove-Item -Path "$pkg_dst" -Recurse -ErrorAction Ignore
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse
IF (!(Test-Path -Path go\bin)) { New-Item -Path go\bin -ItemType Directory -Force | out-null }
# Add to path
webi_path_add ~/.local/opt/go/bin
# Special to go: add default GOBIN to PATH
webi_path_add ~/go/bin
echo "'go@$Env:WEBI_TAG' is an alias for 'golang@$Env:WEBI_VERSION'"
IF ($Env:WEBI_HOST -eq $null -or $Env:WEBI_HOST -eq "") { $Env:WEBI_HOST = "https://webinstall.dev" }
curl.exe -fsSL "$Env:WEBI_HOST/golang@$Env:WEBI_VERSION" | powershell

View File

@@ -2,61 +2,10 @@
set -e
set -u
GOBIN="${HOME}/go"
GOBIN_REAL="${HOME}/.local/opt/go-bin-v${WEBI_VERSION}"
# The package is 'golang', but the command is 'go'
pkg_cmd_name="go"
# NOTE: pkg_* variables can be defined here
# pkg_cmd_name
# pkg_src, pkg_src_bin, pkg_src_cmd
# pkg_dst, pkg_dst_bin, pkg_dst_cmd
#
# Their defaults are defined in _webi/template.sh at https://github.com/webinstall/packages
pkg_get_current_version() {
# 'go version' has output in this format:
# go version go1.14.2 darwin/amd64
# This trims it down to just the version number:
# 1.14.2
go version 2> /dev/null |
head -n 1 |
cut -d' ' -f3 |
sed 's:go::'
__redirect_alias_golang() {
echo "'go@${WEBI_TAG:-stable}' is an alias for 'golang@${WEBI_VERSION:-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/golang@${WEBI_VERSION:-}" | sh
}
pkg_format_cmd_version() {
# 'go v1.14.0' will be 'go1.14'
my_version=$(echo "$1" | sed 's:\.0::g')
echo "${pkg_cmd_name}${my_version}"
}
pkg_link() {
# 'pkg_dst' will default to $HOME/.local/opt/go
# 'pkg_src' will be the installed version, such as to $HOME/.local/opt/go-v1.14.2
rm -rf "$pkg_dst"
ln -s "$pkg_src" "$pkg_dst"
# Go has a special $GOBIN
# 'GOBIN' is set above to "${HOME}/go"
# 'GOBIN_REAL' will be "${HOME}/.local/opt/go-bin-v${WEBI_VERSION}"
rm -rf "$GOBIN"
mkdir -p "$GOBIN_REAL/bin"
ln -s "$GOBIN_REAL" "$GOBIN"
}
pkg_post_install() {
pkg_link
# web_path_add is defined in _webi/template.sh at https://github.com/webinstall/packages
# Updates PATH with
# "$HOME/.local/opt/go"
webi_path_add "$pkg_dst_bin"
webi_path_add "$GOBIN/bin"
}
pkg_done_message() {
echo "Installed 'go v$WEBI_VERSION' to ~/.local/opt/go"
}
__redirect_alias_golang

View File

@@ -1,11 +0,0 @@
---
title: Golang Essentials (go-essentials alias)
homepage: https://webinstall.dev/go-essentials
tagline: |
Alias for https://webinstall.dev/go-essentials
alias: go-essentials
description: |
See https://webinstall.dev/go-essentials
---
Alias for https://webinstall.dev/go-essentials

View File

@@ -1,5 +0,0 @@
#!/bin/pwsh
echo "'go@$Env:WEBI_TAG' is an alias for 'golang@$Env:WEBI_VERSION'"
IF ($Env:WEBI_HOST -eq $null -or $Env:WEBI_HOST -eq "") { $Env:WEBI_HOST = "https://webinstall.dev" }
curl.exe -fsSL "$Env:WEBI_HOST/golang@$Env:WEBI_VERSION" | powershell

View File

@@ -1,11 +0,0 @@
#!/bin/sh
set -e
set -u
__redirect_alias_golang() {
echo "'go@${WEBI_TAG:-stable}' is an alias for 'golang@${WEBI_VERSION-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/golang@${WEBI_VERSION-}" | sh
}
__redirect_alias_golang

View File

@@ -3,24 +3,11 @@ title: Go
homepage: https://golang.org
tagline: |
Go makes it easy to build simple, reliable, and efficient software.
alias: go
description: |
See https://webinstall.dev/go
---
Alias for <https://webinstall.dev/go>.
To update or switch versions, run `webi go@stable` (or `@v1.21`, `@beta`,
To update or switch versions, run `webi golang@stable` (or `@v1.19`, `@beta`,
etc).
### Files
```text
~/.config/envman/PATH.env
~/.local/opt/go/
~/go/
```
## Cheat Sheet
> Go is designed, through and through, to make Software Engineering easy. It's
@@ -68,7 +55,7 @@ You may also want to install the Go IDE tooling:
./hello
```
You should see your output:
```text
```txt
> Hello, World!
```

View File

@@ -17,6 +17,15 @@ if (!(Get-Command "git.exe" -ErrorAction SilentlyContinue))
$Env:PATH = "$Env:USERPROFILE\.local\opt\git\cmd;$Env:PATH"
}
Write-Host '' -ForegroundColor red -BackgroundColor white
Write-Host '*********************' -ForegroundColor red -BackgroundColor white
Write-Host '* BREAKING CHANGE *' -ForegroundColor red -BackgroundColor white
Write-Host '*********************' -ForegroundColor red -BackgroundColor white
Write-Host '' -ForegroundColor red -BackgroundColor white
Write-Host ' ''webi golang'' will NOT install go tooling starting with go1.21+' -ForegroundColor red -BackgroundColor white
Write-Host ' use ''webi go-essentials'' to preserve the previous behavior' -ForegroundColor red -BackgroundColor white
Write-Host '' -ForegroundColor red -BackgroundColor white
# Fetch archive
IF (!(Test-Path -Path "$pkg_download"))
{
@@ -56,8 +65,31 @@ Remove-Item -Path "$pkg_dst" -Recurse -ErrorAction Ignore
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse
IF (!(Test-Path -Path go\bin)) { New-Item -Path go\bin -ItemType Directory -Force | out-null }
# Special to go: re-run all go tooling builds
echo "Building go language tools..."
echo gopls
& "$pkg_dst_cmd" install golang.org/x/tools/gopls
echo golint
& "$pkg_dst_cmd" install golang.org/x/lint/golint
echo errcheck
& "$pkg_dst_cmd" install github.com/kisielk/errcheck
echo gotags
& "$pkg_dst_cmd" install github.com/jstemmer/gotags
echo goimports
& "$pkg_dst_cmd" install golang.org/x/tools/cmd/goimports
echo gorename
& "$pkg_dst_cmd" install golang.org/x/tools/cmd/gorename
echo gotype
& "$pkg_dst_cmd" install golang.org/x/tools/cmd/gotype
echo stringer
& "$pkg_dst_cmd" install golang.org/x/tools/cmd/stringer
# Add to path
webi_path_add ~/.local/opt/go/bin
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/opt/go/bin
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add "$Env:USERPROFILE\.local\opt\go\bin"
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add %USERPROFILE%\.local\opt\go\bin
# Special to go: add default GOBIN to PATH
webi_path_add ~/go/bin
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/go/bin
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add "$Env:USERPROFILE\go\bin"
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add %USERPROFILE%\go\bin

View File

@@ -15,6 +15,19 @@ pkg_cmd_name="go"
#
# Their defaults are defined in _webi/template.sh at https://github.com/webinstall/packages
if [ -z "${WEBI__GO_ESSENTIALS:-}" ]; then
# TODO nix for go1.21+
echo >&2 ""
printf >&2 '\e[31m%s:\e[0m\n' '#####################'
printf >&2 '\e[31m%s:\e[0m\n' '# BREAKING CHANGE #'
printf >&2 '\e[31m%s:\e[0m\n' '#####################'
echo >&2 ""
printf >&2 "\e[31m 'webi golang' will NOT install go tooling starting with go1.21+\e[0m\n"
printf >&2 "\e[31m use 'webi go-essentials' to preserve the previous behavior\e[0m\n"
echo >&2 ""
sleep 4
fi
pkg_get_current_version() {
# 'go version' has output in this format:
# go version go1.14.2 darwin/amd64
@@ -55,8 +68,18 @@ pkg_post_install() {
# "$HOME/.local/opt/go"
webi_path_add "$pkg_dst_bin"
webi_path_add "$GOBIN/bin"
if [ -z "${WEBI__GO_ESSENTIALS:-}" ]; then
# TODO nix for go1.21+
WEBI__GO_INSTALL='true'
export WEBI__GO_INSTALL
"$HOME/.local/bin/webi" "go-essentials@${WEBI_TAG}"
fi
}
pkg_done_message() {
echo "Installed 'go v$WEBI_VERSION' to ~/.local/opt/go"
# note: literal $HOME on purpose
#shellcheck disable=SC2016
echo 'Installed go "x" tools to GOBIN=$HOME/go/bin'
}

View File

@@ -1,10 +1,10 @@
'use strict';
var osMap = {
darwin: 'macos',
darwin: 'macos'
};
var archMap = {
386: 'x86',
386: 'x86'
};
function getAllReleases(request) {
@@ -28,12 +28,12 @@ function getAllReleases(request) {
*/
return request({
url: 'https://golang.org/dl/?mode=json&include=all',
json: true,
json: true
}).then((resp) => {
var goReleases = resp.body;
var all = {
releases: [],
download: 'https://dl.google.com/go/{{ download }}',
download: 'https://dl.google.com/go/{{ download }}'
};
goReleases.forEach((release) => {
@@ -58,7 +58,7 @@ function getAllReleases(request) {
arch: arch,
ext: '', // let normalize run the split/test/join
hash: '-', // not ready to standardize this yet
download: filename,
download: filename
});
});
});

View File

@@ -27,7 +27,7 @@ curl https://webi.sh/gpg-pubkey | sh
This is what the output of `gpg-pubkey` looks like (except much longer):
```text
```txt
GnuPG Public Key ID: CA025BC42F00BBBE
~/Downloads/john@example.com.gpg.asc:
@@ -49,7 +49,7 @@ Note: Your public key is the _entire_ section starting with and including
These are the files / directories that are created and/or modified with this
install:
```text
```txt
~/.config/envman/PATH.env
~/.local/bin/gpg-pubkey
~/.local/bin/gpg-pubkey-id
@@ -143,7 +143,7 @@ format:
gpg --list-secret-keys --keyid-format LONG
```
```text
```txt
/Users/me/.gnupg/pubring.kbx
----------------------------
sec rsa3072/CA025BC42F00BBBE 2021-11-10 [SCEA]
@@ -154,7 +154,7 @@ ssb rsa3072/674124162BF19A32 2021-11-10 [SEA]
The line with the Public Key ID is the one that starts with `sec`:
```text
```txt
sec rsa3072/CA025BC42F00BBBE 2021-11-10 [SCEA]
```

View File

@@ -31,7 +31,7 @@ Here we'll cover:
These are the files / directories that are created and/or modified with this
install:
```text
```txt
~/.config/envman/PATH.env
~/.local/opt/gnupg/bin/gpg
~/.local/opt/gnupg/bin/gpg-agent
@@ -123,7 +123,7 @@ launchctl load -w ~/Library/LaunchAgents/gpg-agent.plist
`gpg` is generally expected to be used with a Desktop client. On Linux servers
you may get this error:
```text
```txt
error: gpg failed to sign the data
fatal: failed to write commit object
```

View File

@@ -4,7 +4,7 @@ set -e
set -u
_install_gpg() {
if [ "Darwin" != "$(uname -s)" ]; then
if ! (uname -a | grep -i "darwin" > /dev/null); then
echo "No gpg installer for Linux yet. Try this instead:"
echo " sudo apt install -y gpg gnupg"
exit 1

View File

@@ -5,14 +5,14 @@ let ltsRe = /GnuPG-(2\.2\.[\d\.]+)/;
function createRssMatcher() {
return new RegExp(
'<link>(https://sourceforge\\.net/projects/gpgosx/files/GnuPG-([\\d\\.]+)\\.dmg/download)</link>',
'g',
'g'
);
}
function createUrlMatcher() {
return new RegExp(
'https://sourceforge\\.net/projects/gpgosx/files/(GnuPG-([\\d\\.]+)\\.dmg)/download',
'',
''
);
}
@@ -20,7 +20,7 @@ async function getRawReleases(request) {
let matcher = createRssMatcher();
let resp = await request({
url: 'https://sourceforge.net/projects/gpgosx/rss?path=/',
url: 'https://sourceforge.net/projects/gpgosx/rss?path=/'
});
let links = [];
for (;;) {
@@ -64,13 +64,13 @@ function transformReleases(links) {
os: 'macos',
arch: 'amd64',
ext: 'dmg',
download: link,
download: link
};
})
.filter(Boolean);
return {
releases: releases,
releases: releases
};
}

View File

@@ -3,9 +3,9 @@ set -e
set -u
__redirect_alias_iterm2_themes() {
echo "'iterm-color-schemes@${WEBI_TAG:-stable}' is an alias for 'iterm2-themes@${WEBI_VERSION-}'"
echo "'iterm-color-schemes@${WEBI_TAG:-stable}' is an alias for 'iterm2-themes@${WEBI_VERSION:-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/iterm2-themes@${WEBI_VERSION-}" | sh
curl -fsSL "$WEBI_HOST/iterm2-themes@${WEBI_VERSION:-}" | sh
}
__redirect_alias_iterm2_themes

Some files were not shown because too many files have changed in this diff Show More