Compare commits

..

79 Commits

Author SHA1 Message Date
AJ ONeal
557ef7fde5 WIP: docs(dashd): add stuff 2023-06-16 07:32:48 +00:00
AJ ONeal
c141ceb6fe feat: add dashcore (dash-cli, dashd, dash-qt) 2023-06-16 07:32:47 +00:00
AJ ONeal
b944352e1b ref(ssh-utils): alphabetize, fix typos 2023-06-11 08:40:09 +00:00
AJ ONeal
12de674f54 feat(ssh-utils): add ssh-authorize 2023-06-11 08:27:52 +00:00
AJ ONeal
a3d62393c7 feat: add ssh-authorize 2023-06-11 08:27:13 +00:00
AJ ONeal
aefba90af9 ref!(ssh-adduser): move sshd-prohibit-password to own command 2023-06-10 00:04:56 +00:00
AJ ONeal
3a574392f0 feat: add sshd-prohibit-password 2023-06-09 23:38:50 +00:00
AJ ONeal
6baa78f95d doc(vim-airline): add Files section, update format and wording 2023-06-01 06:13:11 +00:00
Ryan Burnette
54d41336c4 add vim-airline-themes installer 2023-06-01 06:03:04 +00:00
Ryan Burnette
b406af83a6 add vim-airline installer 2023-06-01 06:03:04 +00:00
AJ ONeal
7c717d994f fix(vim-italics): rewrite 2023-06-01 05:59:28 +00:00
Aritra Mallick
3383c1e322 feat: add vim-italics 2023-06-01 05:32:35 +00:00
alexravenna
522ebaddd0 docs(nerdfont): Update Windows Terminal settings to 1.16.10262.0 2023-06-01 05:20:29 +00:00
alexravenna
fd69b0b57a docs(fd): Fix typo in fd readme 2023-06-01 05:20:25 +00:00
AJ ONeal
160e13ccaa ref!: replace 'pathman' with POSIX 'webi_path_add' 2023-05-31 17:36:04 +00:00
AJ ONeal
9e523f0c0e fix(windows): detect Windows ARM64, with AMD64 fallback 2023-05-28 23:46:36 +00:00
AJ ONeal
ffd757edd6 ref(webi): shfmt 2023-05-28 05:02:01 +00:00
AJ ONeal
3ab9eee352 fix(nerdfont): pin version to tag 'v2.3.3' rather than 'master' (now v3.x) 2023-05-25 20:29:09 +00:00
AJ ONeal
efb67109fb ref!: replace pathman with PowerShell [Environment]::SetEnvironmentVariable 2023-05-09 00:04:59 +00:00
AJ ONeal
ba4571ec35 fix(windows): correctly bootstrap pathman install 2023-05-08 20:57:00 +00:00
AJ ONeal
d6757752d5 feat: add beyond-shell (for Workshops) 2023-03-07 12:09:43 +00:00
AJ ONeal
2a081b527b fix(node): remove deprecated 'scripts-prepend-node-path' option 2023-03-07 11:26:15 +00:00
Abhimanyu Sharma
51c7c20c59 feat: add sttr 2023-03-07 11:17:41 +00:00
AJ ONeal
6025fb3b8e fix(vim-prettier): add back explicit file extension detection 2023-03-07 00:58:30 +00:00
AJ ONeal
89c46b728b docs: update Files section for (vim-)prettier, shellcheck, and (vim-)shfmt 2023-03-06 23:21:45 +00:00
AJ ONeal
480a102f64 fix(vim-prettier): run when 'filetype' is javascript, remove outdated
config
2023-03-06 20:21:09 +00:00
AJ ONeal
1b37080425 fix(vim-shfmt): remove duplicate autocmd (now exists upstream) 2023-03-06 20:21:08 +00:00
AJ ONeal
e5ffc8a931 feat(ssh-adduser): allow authorized_keys url 2023-03-04 01:04:18 +00:00
AJ ONeal
af3658e240 doc(vim-essentials): mention vim-commentary, update vim-nerdtree description 2023-03-04 01:03:49 +00:00
AJ ONeal
a53fbe5f36 fix(smartcase): add powershell install for windows 2023-03-04 01:03:49 +00:00
AJ ONeal
fea715f9bd fix(vim-essentials): install bins last in case they fail (looking at you sudo'd npm) 2023-03-04 00:56:45 +00:00
AJ ONeal
30f9fd6271 doc(lsd): update alias section 2023-02-26 06:32:26 +00:00
AJ ONeal
3602972090 doc(curlie): add alias section 2023-02-26 06:26:30 +00:00
AJ ONeal
6cf153de8c doc(bat): update alias 2023-02-26 06:21:16 +00:00
AJ ONeal
410bb1c3e3 feat(bat): upsert config file 2023-02-26 06:17:42 +00:00
AJ ONeal
9f7ce9842c feat(rg): upsert config file 2023-02-26 06:17:35 +00:00
HacDan
1984d10878 doc(rg): add Files section 2023-02-26 06:15:22 +00:00
HacDan
bbaeb0dd38 doc(arc): add Files section 2023-02-26 06:12:45 +00:00
HacDan
811d5c7d63 doc(bat): add Files section 2023-02-26 06:08:47 +00:00
AJ ONeal
817e71a8f5 ref(vim-sensible): use common vim install scripts 2023-02-26 06:03:14 +00:00
AJ ONeal
0024f69109 doc: replace ``txt blocks with ``text blocks 2023-02-26 05:57:14 +00:00
Ryan Burnette
f84a4c5b69 feat: add vim-commentary 2023-02-26 05:57:14 +00:00
AJ ONeal
b25da4cae8 doc(bat): show aliasman usage too 2023-02-23 01:00:43 +00:00
AJ ONeal
a2b68dbca8 doc(delta): move Files section to standard location 2023-02-23 00:57:07 +00:00
AJ ONeal
991592e88a fix(fish): ensure the config file always exists (otherwise pathman detection goes sadways) 2023-02-23 00:39:30 +00:00
AJ ONeal
0782aa6eb8 feat(postgres): install to macOS /Applications/ rather than ~/Applications/ (works better) 2023-02-22 08:10:16 +00:00
AJ ONeal
482027b880 doc(node): update the Files description 2023-02-22 08:10:15 +00:00
AJ ONeal
4678e04654 feat(iterm2): install to macOS /Applications/ rather than ~/Applications/ (works better) 2023-02-22 08:10:15 +00:00
AJ ONeal
a782c32d59 doc(golang): add Files section 2023-02-21 08:04:05 +00:00
AJ ONeal
a1be2e4aa7 doc(node): add Files section 2023-02-21 08:04:04 +00:00
AJ ONeal
56cb856357 doc(vim-spell): add Files section 2023-02-21 08:04:04 +00:00
AJ ONeal
f73a284569 doc(vim-shell): fix typo, update Files section 2023-02-21 08:04:04 +00:00
AJ ONeal
7f4f9afaaa doc(vim-essentials): add Files section 2023-02-21 08:04:03 +00:00
AJ ONeal
9199531bf5 feat(vim-essentials): add vim-smartcase 2023-02-21 08:04:03 +00:00
AJ ONeal
061f9b643e feat: add vim-smartcase 2023-02-21 08:03:28 +00:00
AJ ONeal
9feca1c7af fix(vim-ale): update config for v3.2.0 + unicode fix 2023-02-21 08:03:12 +00:00
AJ ONeal
e5685b9025 ref: make fresh/stale/expires cache access more readable 2023-02-13 19:23:14 +00:00
AJ ONeal
6c76ff728c hotfix: never hard fail when usable data is available 2023-02-13 19:08:54 +00:00
AJ ONeal
f663bb7822 hotfix: more specific bad response errors 2023-02-13 19:03:35 +00:00
AJ ONeal
2bcc903f80 hotfix: don't use debug stale times values in production, DUH! 2023-02-13 18:44:15 +00:00
AJ ONeal
5b6b700943 fix: replace 'uname -a' with 'uname -srm' for OS/Arch detection 2023-02-11 21:57:39 +00:00
AJ ONeal
b5fc4d742b chore: update shfmt 2023-02-11 21:39:07 +00:00
AJ ONeal
5fc3d0e174 doc(aliasman): supercharge the cheat sheet 2023-02-09 09:30:58 +00:00
AJ ONeal
c26c67662b feat: add aliasman 2023-02-09 09:13:08 +00:00
AJ ONeal
e2702eea08 hotfix: log headers and body on GitHub API error 2023-02-03 20:34:26 +00:00
AJ ONeal
c2f1882de5 feat: add bun 2023-01-30 09:17:30 +00:00
AJ ONeal
90a919736b fix: allow installers without releases 2023-01-30 07:16:00 +00:00
AJ ONeal
bab564bdeb fix(k9s): add release update timeout 2023-01-24 18:02:53 +00:00
AJ ONeal
21c668b4b7 chore(fmt): set .prettierrc.json.trailingComma = "all" 2023-01-24 17:54:39 +00:00
AJ ONeal
2149eeb7f8 chore(fmt): mv .prettierrc .prettierrc.json 2023-01-24 17:54:39 +00:00
AJ ONeal
9c1be4bc3a chore(fmt): npm run prettier 2023-01-24 17:54:39 +00:00
David McClellan
967eff256a Missing word - VIM Leader Cheatsheet
Updated VIM Leader cheatsheet - added missing word. 

-- Sorry @coolaj86 it bothered me for too long, had to submit
2023-01-18 22:51:26 +00:00
AJ ONeal
eddef3c24b ref: simplify download folder check 2023-01-15 07:26:54 +00:00
Vladimir Siritsa
4723810e2b feat: set Downloads dir from xdg-user-dir DOWNLOAD when available 2023-01-15 07:13:41 +00:00
AJ ONeal
40f37cb916 feat: add duckdns -> DuckDNS.sh alias 2023-01-15 03:25:02 +00:00
AJ ONeal
25b003996a feat: add DuckDNS.sh 2023-01-15 03:23:45 +00:00
AJ ONeal
22aa8ba596 feat(releases): add github source releases (no assets) 2023-01-15 02:22:33 +00:00
AJ ONeal
2f618384cc fix: update @root/request for hanging error bugfix 2022-11-14 17:39:50 +00:00
AJ ONeal
75284b2a93 ref!: remove 'shmatter' and update 'marked' 2022-10-20 20:48:41 +00:00
215 changed files with 4467 additions and 831 deletions

View File

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

View File

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

View File

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

View File

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

133
_common/github-source.js Normal file
View File

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

View File

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

View File

@@ -19,7 +19,7 @@ if (/^win/i.test(os.platform())) {
return; 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) { if (err) {
console.error(err); console.error(err);
} }

View File

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

View File

@@ -1,7 +1,7 @@
'use strict'; 'use strict';
var fs = require('fs'); var fs = require('fs');
var marked = require('marked'); var marked = require('marked').marked;
var frontmatter = '---'; var frontmatter = '---';
var keyValRe = /(\w+): (.*)/; var keyValRe = /(\w+): (.*)/;
@@ -19,7 +19,7 @@ function parseYamlish(txt) {
} }
function unblock() { function unblock() {
cfg[block] = marked(cfg[block]); cfg[block] = marked.parse(cfg[block]);
block = false; block = false;
} }
@@ -57,7 +57,7 @@ function parseYamlish(txt) {
var m = line.match(keyValRe); var m = line.match(keyValRe);
if (!m) { if (!m) {
throw new Error( throw new Error(
'invalid key format for: ' + JSON.stringify(line) + ' ' + i 'invalid key format for: ' + JSON.stringify(line) + ' ' + i,
); );
} }
if ('|' === m[2]) { if ('|' === m[2]) {
@@ -68,9 +68,9 @@ function parseYamlish(txt) {
}); });
if (block) { if (block) {
cfg[block] = marked(cfg[block]); cfg[block] = marked.parse(cfg[block]);
} }
cfg.examples = marked(lines.slice(last).join('\n')); cfg.examples = marked.parse(lines.slice(last).join('\n'));
return cfg; return cfg;
} }
@@ -79,6 +79,6 @@ module.exports.parse = parseYamlish;
if (require.main === module) { if (require.main === module) {
console.info( 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, freebsd: /(\b|_)(freebsd)/i,
windows: /(\b|_)(win|microsoft|msft)/i, windows: /(\b|_)(win|microsoft|msft)/i,
sunos: /(\b|_)(sun)/i, sunos: /(\b|_)(sun)/i,
aix: /(\b|_)(aix)/i aix: /(\b|_)(aix)/i,
}; };
var maps = { var maps = {
oses: {}, oses: {},
arches: {}, arches: {},
formats: {} formats: {},
}; };
Object.keys(osMap).forEach(function (name) { Object.keys(osMap).forEach(function (name) {
@@ -39,7 +39,7 @@ var arches = [
'x86', 'x86',
'ppc64le', 'ppc64le',
'ppc64', 'ppc64',
's390x' 's390x',
]; ];
// Used for detecting system arch from package download url, for example: // 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, x86: /(\b|_|amd|(dar)?win(dows)?|mac(os)?|linux|osx|x)(86|32)([_\-]?bit)(\b|_)/i,
ppc64le: /(\b|_)(ppc64le)/i, ppc64le: /(\b|_)(ppc64le)/i,
ppc64: /(\b|_)(ppc64)(\b|_)/i, ppc64: /(\b|_)(ppc64)(\b|_)/i,
s390x: /(\b|_)(s390x)/i s390x: /(\b|_)(s390x)/i,
}; };
arches.forEach(function (name) { arches.forEach(function (name) {
maps.arches[name] = true; maps.arches[name] = true;
@@ -69,7 +69,7 @@ function normalize(all) {
var supported = { var supported = {
oses: {}, oses: {},
arches: {}, arches: {},
formats: {} formats: {},
}; };
all.releases.forEach(function (rel) { all.releases.forEach(function (rel) {

View File

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

View File

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

View File

@@ -11,14 +11,9 @@ var getReleases = require('./transform-releases.js');
var installersDir = path.join(__dirname, '..'); var installersDir = path.join(__dirname, '..');
module.exports = async function serveInstaller( serveInstaller.serveInstaller = serveInstaller;
baseurl, module.exports = serveInstaller;
ua, async function serveInstaller(baseurl, ua, pkg, tag, ext, formats) {
pkg,
tag,
ext,
formats
) {
// TODO put some of this in a middleware? or common function? // TODO put some of this in a middleware? or common function?
var ver = tag.replace(/^v/, ''); var ver = tag.replace(/^v/, '');
@@ -52,41 +47,41 @@ module.exports = async function serveInstaller(
// TODO maybe move package/version/lts/channel detection into getReleases // TODO maybe move package/version/lts/channel detection into getReleases
var myOs = uaDetect.os(ua); var myOs = uaDetect.os(ua);
var myArch = uaDetect.arch(ua); var myArch = uaDetect.arch(ua);
return packages.get(pkg).then(function (cfg) { let cfg = await packages.get(pkg);
return getReleases({ let rels = await getReleases({
pkg: cfg.alias || pkg, pkg: cfg.alias || pkg,
ver, ver,
os: myOs, os: myOs,
arch: myArch, arch: myArch,
lts, lts,
channel, channel,
formats, formats,
limit: 1 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,24 +42,87 @@ New-Item -Path .local\opt -ItemType Directory -Force | out-null
# {{ baseurl }} # {{ baseurl }}
# {{ version }} # {{ version }}
function webi_add_path function webi_path_add($pathname)
{ {
Write-Host '' # C:\Users\me => C:/Users/me
Write-Host '*****************************' -ForegroundColor red -BackgroundColor white $my_home = $Env:UserProfile
Write-Host '* IMPORTANT - READ ME *' -ForegroundColor red -BackgroundColor white $my_home = $my_home.replace('\\', '/')
Write-Host '*****************************' -ForegroundColor red -BackgroundColor white $my_home_re = [regex]::escape($my_home)
Write-Host ''
& "$Env:USERPROFILE\.local\bin\pathman.exe" add "$args[0]" # ~/bin => %USERPROFILE%/bin
# Note: not all of these work as expected, so we use the unix-style, which is most consistent $pathname = $pathname.replace('~/', "$Env:UserProfile/")
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/bin
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add "$Env:USERPROFILE\.local\bin" # C:\Users\me\bin => %USERPROFILE%/bin
#& "$Env:USERPROFILE\.local\bin\pathman.exe" add %USERPROFILE%\.local\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 ""
}
} }
# Run pathman to set up the folder #$has_local_bin = echo "$Env:PATH" | Select-String -Pattern '\.local.bin'
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/bin #if (!$has_local_bin)
#{
webi_path_add ~/.local/bin
#}
{{ installer }} {{ installer }}
webi_path_add ~/.local/bin
# Done # Done
popd popd

View File

@@ -30,16 +30,25 @@ __bootstrap_webi() {
#PKG_OSES= #PKG_OSES=
#PKG_ARCHES= #PKG_ARCHES=
#PKG_FORMATS= #PKG_FORMATS=
WEBI_UA="$(uname -a)" WEBI_UA="$(uname -s)/$(uname -r) $(uname -m)/unknown"
WEBI_PKG_DOWNLOAD="" WEBI_PKG_DOWNLOAD=""
WEBI_PKG_PATH="${HOME}/Downloads/webi/${PKG_NAME:-error}/${WEBI_VERSION:-latest}" 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}"
export WEBI_HOST export WEBI_HOST
## ##
## Set up tmp, download, and install directories ## 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"}" export _webi_tmp="${_webi_tmp:-"$HOME/.local/opt/webi-tmp.d"}"
mkdir -p "${WEBI_PKG_PATH}" mkdir -p "${WEBI_PKG_PATH}"
@@ -82,7 +91,7 @@ __bootstrap_webi() {
return 0 return 0
fi fi
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1:-}" ]; then if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1-}" ]; then
rm -rf "$pkg_dst_cmd" rm -rf "$pkg_dst_cmd"
ln -s "$pkg_src_cmd" "$pkg_dst_cmd" ln -s "$pkg_src_cmd" "$pkg_dst_cmd"
else else
@@ -150,12 +159,12 @@ __bootstrap_webi() {
# detect if file is downloaded, and how to download it # detect if file is downloaded, and how to download it
webi_download() { webi_download() {
# determine the url to download # determine the url to download
if [ -n "${1:-}" ]; then if [ -n "${1-}" ]; then
my_url="$1" my_url="$1"
else else
if [ "error" = "$WEBI_CHANNEL" ]; then if [ "error" = "$WEBI_CHANNEL" ]; then
# TODO pass back requested OS / Arch / Version # 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 " '$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 " (check that the package name and version are correct)"
echo >&2 "" echo >&2 ""
@@ -167,7 +176,7 @@ __bootstrap_webi() {
fi fi
# determine the location to download to # determine the location to download to
if [ -n "${2:-}" ]; then if [ -n "${2-}" ]; then
my_dl="$2" my_dl="$2"
else else
my_dl="${WEBI_PKG_PATH}/$WEBI_PKG_FILE" my_dl="${WEBI_PKG_PATH}/$WEBI_PKG_FILE"
@@ -242,25 +251,179 @@ __bootstrap_webi() {
# use 'pathman' to update $HOME/.config/envman/PATH.env # use 'pathman' to update $HOME/.config/envman/PATH.env
webi_path_add() { webi_path_add() {
# make sure that we don't recursively install pathman with webi my_path="${1}"
my_path="$PATH"
export PATH="$HOME/.local/bin:$PATH"
# install pathman if not already installed fn_envman_init
if [ -z "$(command -v pathman)" ]; then
"$HOME/.local/bin/webi" pathman > /dev/null # \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
fi fi
export PATH="$my_path" echo "${my_export}" >> ~/.config/envman/PATH.env
# in case pathman was recently installed and the PATH not updated
mkdir -p "$_webi_tmp" mkdir -p "$_webi_tmp"
# 'true' to prevent "too few arguments" output my_path_tilde="$(
# when there are 0 lines of stdout echo "${my_path}" |
"$HOME/.local/bin/pathman" add "$1" | sed -e "s${my_delim}${HOME}${my_delim}~${my_delim}g"
grep "export" 2> /dev/null \ )"
>> "$_webi_tmp/.PATH.env" ||
true 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
} }
# group common pre-install tasks as default # group common pre-install tasks as default
@@ -274,7 +437,7 @@ __bootstrap_webi() {
# shellcheck disable=2120 # shellcheck disable=2120
# webi_install may be sourced and used elsewhere # webi_install may be sourced and used elsewhere
webi_install() { webi_install() {
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1:-}" ]; then if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1-}" ]; then
mkdir -p "$(dirname "$pkg_src_cmd")" mkdir -p "$(dirname "$pkg_src_cmd")"
mv ./"$pkg_cmd_name"* "$pkg_src_cmd" mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
else else
@@ -328,9 +491,9 @@ __bootstrap_webi() {
WEBI_SINGLE= WEBI_SINGLE=
if [ -z "${WEBI_WELCOME:-}" ]; then if [ -z "${WEBI_WELCOME-}" ]; then
echo "" 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 "Have a problem? Experience a bug? Please let us know:"
echo " https://github.com/webinstall/webi-installers/issues" echo " https://github.com/webinstall/webi-installers/issues"
echo "" echo ""
@@ -362,14 +525,14 @@ __bootstrap_webi() {
command -v pkg_post_install > /dev/null || command -v pkg_post_install > /dev/null ||
command -v pkg_done_message > /dev/null || command -v pkg_done_message > /dev/null ||
command -v pkg_format_cmd_version > /dev/null || command -v pkg_format_cmd_version > /dev/null ||
[ -n "${WEBI_SINGLE:-}" ] || [ -n "${WEBI_SINGLE-}" ] ||
[ -n "${pkg_cmd_name:-}" ] || [ -n "${pkg_cmd_name-}" ] ||
[ -n "${pkg_dst_cmd:-}" ] || [ -n "${pkg_dst_cmd-}" ] ||
[ -n "${pkg_dst_dir:-}" ] || [ -n "${pkg_dst_dir-}" ] ||
[ -n "${pkg_dst:-}" ] || [ -n "${pkg_dst-}" ] ||
[ -n "${pkg_src_cmd:-}" ] || [ -n "${pkg_src_cmd-}" ] ||
[ -n "${pkg_src_dir:-}" ] || [ -n "${pkg_src_dir-}" ] ||
[ -n "${pkg_src:-}" ]; then [ -n "${pkg_src-}" ]; then
pkg_cmd_name="${pkg_cmd_name:-$PKG_NAME}" pkg_cmd_name="${pkg_cmd_name:-$PKG_NAME}"
@@ -420,10 +583,12 @@ __bootstrap_webi() {
fi fi
webi_path_add "$HOME/.local/bin" 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 if [ -n "$(cat "$_webi_tmp/.PATH.env")" ]; then
printf 'PATH.env updated with:\n' printf 'PATH.env updated with:\n'
sort -u "$_webi_tmp/.PATH.env" sort -u "$_webi_tmp/.PATH.env" | while read -r my_new_path; do
echo " ${my_new_path}"
done
printf "\n" printf "\n"
rm -f "$_webi_tmp/.PATH.env" rm -f "$_webi_tmp/.PATH.env"

View File

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

View File

@@ -3,8 +3,10 @@
var path = require('path'); var path = require('path');
var Releases = require('./releases.js'); var Releases = require('./releases.js');
var cache = {}; var cache = {};
var staleAge = 5 * 1000; //var staleAge = 5 * 1000;
var expiredAge = 15 * 1000; //var expiredAge = 15 * 1000;
var staleAge = 5 * 60 * 1000;
var expiredAge = 15 * 60 * 1000;
let installerDir = path.join(__dirname, '..'); let installerDir = path.join(__dirname, '..');
@@ -64,64 +66,102 @@ function createFormatsSorter(formats) {
async function getCachedReleases(pkg) { async function getCachedReleases(pkg) {
// returns { download: '<template string>', releases: [{ version, date, os, arch, lts, channel, download}] } // returns { download: '<template string>', releases: [{ version, date, os, arch, lts, channel, download}] }
function putCache() { async function chainCachePromise(fn) {
cache[pkg].promise = cache[pkg].promise.then(function () { cache[pkg].promise = cache[pkg].promise.then(fn);
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) {
//console.debug('DOWNLOADED NEW "%s" releases', pkg);
cache[pkg].updatedAt = Date.now();
cache[pkg].all = 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; return cache[pkg].promise;
} }
var p; 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;
})
.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;
}
if (!cache[pkg]) { if (!cache[pkg]) {
cache[pkg] = { cache[pkg] = {
updatedAt: 0, updatedAt: 0,
all: null, all: { download: '', releases: [] },
promise: Promise.resolve() promise: Promise.resolve(),
}; };
} }
var bgRenewal;
var age = Date.now() - cache[pkg].updatedAt; var age = Date.now() - cache[pkg].updatedAt;
if (age >= expiredAge) { var fresh = age < staleAge;
//console.debug("EXPIRED - waiting"); if (!fresh) {
p = putCache(); bgRenewal = chainCachePromise(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);
} }
return p; var tooStale = age > expiredAge;
if (!tooStale) {
return await cache[pkg].all;
}
return await Promise.race([
bgRenewal,
sleep(5000).then(function () {
return cache[pkg].all;
}),
]);
} }
async function filterReleases( async function filterReleases(
all, all,
{ ver, os, arch, lts, channel, formats, limit } { ver, os, arch, lts, channel, formats, limit },
) { ) {
// When multiple formats are downloadable (i.e. .zip and .pkg) // When multiple formats are downloadable (i.e. .zip and .pkg)
// sort the most compatible format first // sort the most compatible format first
@@ -163,7 +203,7 @@ module.exports = function getReleases({
lts, lts,
channel, channel,
formats, formats,
limit limit,
}) { }) {
if (!_count) { if (!_count) {
_count = 0; _count = 0;
@@ -176,20 +216,20 @@ module.exports = function getReleases({
lts, lts,
channel, channel,
formats, formats,
limit limit,
}) })
.catch(function (err) { .catch(function (err) {
if ('MODULE_NOT_FOUND' === err.code) { if ('MODULE_NOT_FOUND' === err.code) {
return null; return null;
} }
console.error( 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); console.error(err);
}) })
.then(function (releases) { .then(function (releases) {
if (!releases.length) { if (!releases.length) {
// Apple Silicon M1 hack-y do workaround fix // Apple Silicon M1 hacky-do workaround fix
if ('macos' === os && 'arm64' === arch) { if ('macos' === os && 'arm64' === arch) {
return getReleases({ return getReleases({
pkg, pkg,
@@ -199,7 +239,20 @@ module.exports = function getReleases({
lts, lts,
channel, channel,
formats, formats,
limit limit,
});
}
// Windows ARM hacky-do workaround fix
if ('windows' === os && 'arm64' === arch) {
return getReleases({
pkg,
ver,
os,
arch: 'amd64',
lts,
channel,
formats,
limit,
}); });
} }
// Raspberry Pi 3+ on Raspbian x86 (not Ubuntu arm64) // Raspberry Pi 3+ on Raspbian x86 (not Ubuntu arm64)
@@ -213,7 +266,7 @@ module.exports = function getReleases({
lts, lts,
channel, channel,
formats, formats,
limit limit,
}); });
} }
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?) // Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?)
@@ -228,7 +281,7 @@ module.exports = function getReleases({
lts, lts,
channel, channel,
formats, formats,
limit limit,
}); });
} }
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?) // Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?)
@@ -242,7 +295,7 @@ module.exports = function getReleases({
lts, lts,
channel, channel,
formats, formats,
limit limit,
}); });
} }
releases = [ releases = [
@@ -260,15 +313,15 @@ module.exports = function getReleases({
comment: comment:
'No matches found. Could be bad or missing version info' + '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 { return {
oses: all.oses, oses: all.oses,
arches: all.arches, arches: all.arches,
formats: all.formats, formats: all.formats,
releases: releases releases: releases,
}; };
}); });
}); });
@@ -284,7 +337,7 @@ if (require.main === module) {
lts: true, lts: true,
channel: 'stable', channel: 'stable',
formats: ['tar', 'exe', 'zip', 'xz', 'dmg', 'pkg'], formats: ['tar', 'exe', 'zip', 'xz', 'dmg', 'pkg'],
limit: 10 limit: 10,
}) })
.then(function (all) { .then(function (all) {
console.info(JSON.stringify(all)); console.info(JSON.stringify(all));

View File

@@ -16,11 +16,11 @@ function getRequest(req) {
} }
return { return {
unix: 'curl -fsSA "$(uname -a)" ' + url, unix: 'curl -fsSA "$(uname -srm)" ' + url,
windows: 'curl.exe -fsSA "MS $Env:PROCESSOR_ARCHITECTURE" ' + url, windows: 'curl.exe -fsSA "MS $Env:PROCESSOR_ARCHITECTURE" ' + url,
ua: ua, ua: ua,
os: uaDetect.os(ua), os: uaDetect.os(ua),
arch: uaDetect.arch(ua) arch: uaDetect.arch(ua),
}; };
} }

View File

@@ -17,7 +17,17 @@ IF ($my_arch -eq $null -or $my_arch -eq "") {
# This is the canonical CPU arch when the process is native # This is the canonical CPU arch when the process is native
$my_arch = "$Env:PROCESSOR_ARCHITECTURE" $my_arch = "$Env:PROCESSOR_ARCHITECTURE"
} }
# TODO API should know to prefer x86 for windows when arm binary is not available 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"
}
}
$Env:WEBI_UA = "Windows/10 $my_arch" $Env:WEBI_UA = "Windows/10 $my_arch"
$exename = $args[0] $exename = $args[0]
@@ -50,27 +60,6 @@ IF($Env:WEBI_HOST -eq $null -or $Env:WEBI_HOST -eq "")
$Env:WEBI_HOST = "https://webinstall.dev" $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 }} # {{ baseurl }}
# {{ version }} # {{ version }}

View File

@@ -10,18 +10,7 @@ pushd "%userprofile%" || goto :error
mkdir .local\opt || goto :error mkdir .local\opt || goto :error
) )
pushd .local\bin || goto :error echo Downloading and installing %1
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 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 rem TODO only add if it's not in there already

125
aliasman/README.md Normal file
View File

@@ -0,0 +1,125 @@
---
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'
```

41
aliasman/install.sh Normal file
View File

@@ -0,0 +1,41 @@
#!/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

28
aliasman/releases.js Normal file
View File

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

View File

@@ -3,9 +3,9 @@ set -e
set -u set -u
__redirect_alias_arc() { __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"} 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 __redirect_alias_arc

View File

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

View File

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

83
beyond-shell/README.md Normal file
View File

@@ -0,0 +1,83 @@
---
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

415
beyond-shell/install.sh Normal file
View File

@@ -0,0 +1,415 @@
#!/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

@@ -7,7 +7,7 @@ _install_brew() {
# Straight from https://brew.sh # Straight from https://brew.sh
#/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" #/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
if uname -a | grep -q -i darwin; then if [ "Darwin" = "$(uname -s)" ]; then
needs_xcode="$(/usr/bin/xcode-select -p > /dev/null 2> /dev/null || echo "true")" needs_xcode="$(/usr/bin/xcode-select -p > /dev/null 2> /dev/null || echo "true")"
if [ -n "${needs_xcode}" ]; then if [ -n "${needs_xcode}" ]; then
echo "" echo ""

160
bun/README.md Normal file
View File

@@ -0,0 +1,160 @@
---
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
```

39
bun/install.sh Normal file
View File

@@ -0,0 +1,39 @@
#!/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"
}

32
bun/releases.js Normal file
View File

@@ -0,0 +1,32 @@
'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,18 +26,9 @@ Here's the things we find most useful:
### How to serve a directory ### How to serve a directory
```sh ```sh
caddy file-server --browse --listen :443 caddy file-server --browse --listen :4040
``` ```
### 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 ### How to serve HTTPS on localhost
Caddy can be used to test with https on localhost. Caddy can be used to test with https on localhost.
@@ -46,50 +37,20 @@ Caddy can be used to test with https on localhost.
```Caddyfile ```Caddyfile
localhost { localhost {
handle /api/* {
reverse_proxy localhost:3000
}
handle /* { handle /* {
root * ./public/ root * ./public/
file_server file_server
} }
handle /api/* {
reverse_proxy localhost:3000
}
} }
``` ```
### How to serve on Linux/VPS (systemd) ```sh
caddyfile run --config ./Caddyfile
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 ### How to redirect and reverse proxy
@@ -185,6 +146,15 @@ 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 ### How to start Caddy as a Linux service
Here are the 3 things you need to do to start Caddy as a system service: Here are the 3 things you need to do to start Caddy as a system service:
@@ -198,11 +168,10 @@ Using a user named `app` to run your services is common industry convention.
**port-binding privileges** **port-binding privileges**
You can use `setcap` or [`setcap-netbind`](/setcap-netbind) to allow Caddy to You can use `setcap` to allow Caddy to use privileged ports.
use privileged ports.
```sh ```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** **systemd config**

View File

@@ -33,7 +33,7 @@ sudo apt --fix-broken install -y
You may get an error like this: You may get an error like this:
```txt ```text
chromedriver: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory 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.*/, metaGeneration: /.*MetaGeneration>(.*)<\/MetaGeneration.*/,
lastModified: /.*LastModified>(.*)<\/LastModified.*/, lastModified: /.*LastModified>(.*)<\/LastModified.*/,
etag: /.*ETag>(.*)<\/ETag.*/, etag: /.*ETag>(.*)<\/ETag.*/,
size: /.*Size>(.*)<\/Size.*/ size: /.*Size>(.*)<\/Size.*/,
}; };
var baseUrl = 'https://chromedriver.storage.googleapis.com'; var baseUrl = 'https://chromedriver.storage.googleapis.com';
module.exports = function (request) { module.exports = function (request) {
var all = { var all = {
download: '', download: '',
releases: [] releases: [],
}; };
// XML // XML
return request({ return request({
url: 'https://chromedriver.storage.googleapis.com/', url: 'https://chromedriver.storage.googleapis.com/',
json: false json: false,
}) })
.then(function (resp) { .then(function (resp) {
var body = resp.body; var body = resp.body;
@@ -32,7 +32,7 @@ module.exports = function (request) {
key: group.replace(matchers.key, '$1'), key: group.replace(matchers.key, '$1'),
//generation: group.replace(matchers.generation, '$1'), //generation: group.replace(matchers.generation, '$1'),
//metaGeneration: group.replace(matchers.metaGeneration, '$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'), //etag: group.replace(matchers.etag, '$1'),
//size: group.replace(matchers.size, '$1') //size: group.replace(matchers.size, '$1')
}; };
@@ -66,7 +66,7 @@ module.exports = function (request) {
os: osname, os: osname,
arch: arch, arch: arch,
hash: '-', // not sure about including etag as hash yet hash: '-', // not sure about including etag as hash yet
download: asset.key download: asset.key,
}); });
}); });
}) })

View File

@@ -20,6 +20,17 @@ etc).
**JSON** (`=`) is the default encoding for `key=value` pairs. **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 ### Simple GET
```sh ```sh

9
dash-cli/README.md Normal file
View File

@@ -0,0 +1,9 @@
---
title: dash-cli (alias)
homepage: https://webinstall.dev/dashcore
tagline: |
`dash-cli` (dash daemon) is an alias for `dashcore` (the dash suite)
alias: dashcore
---
See [Dash Core](/dashcore).

3
dash-cli/install.ps1 Normal file
View File

@@ -0,0 +1,3 @@
echo "'dash-cli@$Env:WEBI_TAG' is an alias for 'dashcore@$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/dashcore@$Env:WEBI_VERSION" | powershell

11
dash-cli/install.sh Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
set -u
function __redirect_alias_dashcore() {
echo "'dash-cli@${WEBI_TAG:-}' (project) is an alias for 'dashcore@${WEBI_VERSION:-}' (command)"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/dashcore@${WEBI_VERSION:-}" | bash
}
__redirect_alias_dashcore

3
dash-cli/releases.js Normal file
View File

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

9
dash-qt/README.md Normal file
View File

@@ -0,0 +1,9 @@
---
title: dash-qt (alias)
homepage: https://webinstall.dev/dashcore
tagline: |
`dash-qt` (dash daemon) is an alias for `dashcore` (the dash suite)
alias: dashcore
---
See [Dash Core](/dashcore).

3
dash-qt/install.ps1 Normal file
View File

@@ -0,0 +1,3 @@
echo "'dash-qt@$Env:WEBI_TAG' is an alias for 'dashcore@$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/dashcore@$Env:WEBI_VERSION" | powershell

11
dash-qt/install.sh Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
set -u
function __redirect_alias_dashcore() {
echo "'dash-qt@${WEBI_TAG:-}' (project) is an alias for 'dashcore@${WEBI_VERSION:-}' (command)"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/dashcore@${WEBI_VERSION:-}" | bash
}
__redirect_alias_dashcore

3
dash-qt/releases.js Normal file
View File

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

9
dash-wallet/README.md Normal file
View File

@@ -0,0 +1,9 @@
---
title: dash-wallet (alias)
homepage: https://webinstall.dev/dashcore
tagline: |
`dash-wallet` (dash daemon) is an alias for `dashcore` (the dash suite)
alias: dashcore
---
See [Dash Core](/dashcore).

3
dash-wallet/install.ps1 Normal file
View File

@@ -0,0 +1,3 @@
echo "'dash-wallet@$Env:WEBI_TAG' is an alias for 'dashcore@$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/dashcore@$Env:WEBI_VERSION" | powershell

11
dash-wallet/install.sh Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
set -u
function __redirect_alias_dashcore() {
echo "'dash-wallet@${WEBI_TAG:-}' (project) is an alias for 'dashcore@${WEBI_VERSION:-}' (command)"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/dashcore@${WEBI_VERSION:-}" | bash
}
__redirect_alias_dashcore

3
dash-wallet/releases.js Normal file
View File

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

9
dash/README.md Normal file
View File

@@ -0,0 +1,9 @@
---
title: Dash (alias)
homepage: https://webinstall.dev/dashcore
tagline: |
`dash` (digital cash) is an alias for `dashcore` (the dash suite)
alias: dashcore
---
See [Dash Core](/dashcore).

3
dash/install.ps1 Normal file
View File

@@ -0,0 +1,3 @@
echo "'dash@$Env:WEBI_TAG' is an alias for 'dashcore@$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/dashcore@$Env:WEBI_VERSION" | powershell

11
dash/install.sh Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
set -u
function __redirect_alias_dashcore() {
echo "'dash@${WEBI_TAG:-}' (project) is an alias for 'dashcore@${WEBI_VERSION:-}' (command)"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/dashcore@${WEBI_VERSION:-}" | bash
}
__redirect_alias_dashcore

3
dash/releases.js Normal file
View File

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

40
dashcore/README.md Normal file
View File

@@ -0,0 +1,40 @@
---
title: Dash Core
homepage: https://github.com/dashpay/dash
tagline: |
foobar: An example that doesn't exist.
---
To update or switch versions, run `webi dashcore@stable` (or `@v0.17`, `@beta`,
etc).
### Files
These are the files / directories that are created and/or modified with this
install:
```txt
~/.config/envman/PATH.env
~/.local/bin/
~/.local/opt/dashcore/
~/Library/Saved Application State/org.dash.Dash-Qt.savedState
~/Library//Preferences/org.dash.Dash-Qt.plist
```
## Cheat Sheet
> _Dash Core_ is a suite of tools for _Dash_, the international digital
> currency.
The tools include:
- `dash-qt` the _Desktop Wallet_ for sending and receiving payments
- `dash-cli` the _Command Line Wallet_
- [`dashd`](/dashd) the ledger and transaction service
- `dash-tx` the transaction debugger
To open the Dash Desktop Wallet:
```bash
dash-qt
```

56
dashcore/install.ps1 Normal file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/env pwsh
##################
# Install dashcore #
##################
# 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 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

45
dashcore/install.sh Normal file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
# shellcheck disable=SC2034
# "'pkg_cmd_name' appears unused. Verify it or export it."
function __init_dashcore() {
set -e
set -u
##################
# Install dashcore #
##################
# 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.17.0
mv ./dashcore-* "${pkg_src_dir}"
}
# pkg_get_current_version is recommended, but not required
pkg_get_current_version() {
# 'dashd --version' has output in this format:
# Dash Core Daemon version v0.17.0.3
# This trims it down to just the version number:
# 0.17.0
dashd --version 2> /dev/null |
head -n 1 |
cut -d ' ' -f 5 |
sed 's:^v::'
}
}
__init_dashcore

28
dashcore/releases.js Normal file
View File

@@ -0,0 +1,28 @@
'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));
});
}

116
dashd/README.md Normal file
View File

@@ -0,0 +1,116 @@
---
title: dashd (alias)
homepage: https://webinstall.dev/dashcore
tagline: |
`dashd` (dash daemon) is an alias for `dashcore` (the dash suite)
alias: dashcore
---
To update or switch versions, run `webi dashd@stable` (or `@v0.17`, `@beta`,
etc).
### Files
These are the files / directories that are created and/or modified with this
install:
```txt
~/.config/envman/PATH.env
~/.local/bin/
~/.local/opt/dashcore/
~/.dashcore/
```
## Cheat Sheet
> The _Dash Daemon_ joins and listens on the Dash network for payment
> transactions.
You will at least 2GB+ RAM + Swap (or 4GB+ without swap) and 50GB storage (20GB
for the ledger + another 20gb for indices) for `dashd` to be able to provide
transaction info and RPC services.
A first run will typically take _several_ hours to sync.
```bash
dashd -- -conf=/home/app/.dashcore/dash.conf -datadir=/mnt/volume_100gb/dashcore/
```
### How to configure dashd
`~/.dashcore/dash.conf`:
```txt
rpcuser=dash
rpcpassword=local321
rpcallowip=127.0.0.1/0
#listen=1
server=1
#daemon=1
whitelist=127.0.0.1/0
# light mode
#prune=945
txindex=1
addressindex=0
timestampindex=0
spentindex=0
zmqpubrawtx=tcp://127.0.0.1:28332
zmqpubrawtxlock=tcp://127.0.0.1:28332
zmqpubhashblock=tcp://127.0.0.1:28332
#ip=
rpcport=9998
uacomment=bitcore
#debug=1
#testnet=1
```
### How to run dashd as a system service
```bash
sudo env PATH="${PATH}" \
serviceman add --system --username "$(whoami)" --path "${PATH}" --name dashd -- \
dashd -- -conf=/home/app/.dashcore/dash.conf -datadir=/mnt/volume_100gb/dashcore/
```
### How to enable Swap Space
`dashd` takes a _lot_ of RAM during the initial sync phase. Once that is
completed, it uses _significantly_ less for daily use.
If you want to save money you can give yourself 4GB+ Swap and although the sync
process will run a little slower (but probably not that much), you'll be able to
complete it using disk storage.
To create a swap file:
```bash
sudo fallocate -l 8G /var/swapfile
sudo chmod 0600 /var/swapfile
sudo mkswap /var/swapfile
```
To temporarily enable swap:
```bash
sudo swapon /var/swapfile
```
To permanently enable swap:
```bash
sudo bash -c 'echo "/var/swapfile none swap sw 0 0" > /etc/fstab'
```
To disable and delete swap:
```bash
sudo swapoff /var/swapfile
```
(don't forget to remove it from `/etc/fstab` as well)
See [vps-addswap](/vps-addswap) for details.

3
dashd/install.ps1 Normal file
View File

@@ -0,0 +1,3 @@
echo "'dashd@$Env:WEBI_TAG' is an alias for 'dashcore@$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/dashcore@$Env:WEBI_VERSION" | powershell

11
dashd/install.sh Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
set -u
function __redirect_alias_dashcore() {
echo "'dashd@${WEBI_TAG:-}' (project) is an alias for 'dashcore@${WEBI_VERSION:-}' (command)"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/dashcore@${WEBI_VERSION:-}" | bash
}
__redirect_alias_dashcore

3
dashd/releases.js Normal file
View File

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

View File

@@ -9,6 +9,17 @@ 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`. **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 ## Cheat Sheet
> `delta` gives you GitHub-style diffs, with word-level diff coloring, right in > `delta` gives you GitHub-style diffs, with word-level diff coloring, right in
@@ -26,17 +37,6 @@ Here we'll cover:
For the full set of options, be sure to check out the helpful For the full set of options, be sure to check out the helpful
[README](https://github.com/dandavison/delta). [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 ## How to set delta's color scheme
Delta uses `~/.gitconfig` for most of its options. Delta uses `~/.gitconfig` for most of its options.
@@ -73,7 +73,7 @@ Here's the current list, for convenience:
### Dark Syntax Themes ### Dark Syntax Themes
```txt ```text
1337 1337
Coldark-Cold Coldark-Cold
Coldark-Dark Coldark-Dark
@@ -97,7 +97,7 @@ zenburn
### Light Syntax Themes ### Light Syntax Themes
```txt ```text
GitHub GitHub
Monokai Extended Light Monokai Extended Light
OneHalfLight OneHalfLight

View File

@@ -38,6 +38,3 @@ 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'" 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 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 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`: You can see the full list of linter rules with `dotenv-linter --show-checks`:
```txt ```text
DuplicatedKey DuplicatedKey
EndingBlankLine EndingBlankLine
ExtraBlankLine ExtraBlankLine

View File

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

98
duckdns.sh/README.md Normal file
View File

@@ -0,0 +1,98 @@
---
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
```

41
duckdns.sh/install.sh Normal file
View File

@@ -0,0 +1,41 @@
#!/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

28
duckdns.sh/releases.js Normal file
View File

@@ -0,0 +1,28 @@
'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));
});
}

15
duckdns/README.md Normal file
View File

@@ -0,0 +1,15 @@
---
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.

11
duckdns/install.sh Normal file
View File

@@ -0,0 +1,11 @@
#!/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: For options see:
```sh ```sh
hexyl --help fd --help
``` ```

View File

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

View File

@@ -2,7 +2,15 @@
set -e set -e
set -u set -u
if ! (uname -a | grep -i "darwin" > /dev/null); then 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
echo "No fish installer for Linux yet. Try this instead:" echo "No fish installer for Linux yet. Try this instead:"
echo " sudo apt install -y fish" echo " sudo apt install -y fish"
exit 1 exit 1
@@ -77,6 +85,12 @@ pkg_post_install() {
# try again to update default shells, now that all files should exist # try again to update default shells, now that all files should exist
_macos_post_install _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 # pkg_get_current_version is recommended, but (soon) not required

View File

@@ -5,7 +5,7 @@ var map = {};
module.exports = function (request) { module.exports = function (request) {
var all = { var all = {
download: '', download: '',
releases: [] releases: [],
}; };
return Promise.all( return Promise.all(
['macos', 'linux', 'windows'].map(function (osname) { ['macos', 'linux', 'windows'].map(function (osname) {
@@ -14,7 +14,7 @@ module.exports = function (request) {
'https://storage.googleapis.com/flutter_infra/releases/releases_' + 'https://storage.googleapis.com/flutter_infra/releases/releases_' +
osname + osname +
'.json', '.json',
json: true json: true,
}).then(function (resp) { }).then(function (resp) {
var body = resp.body; var body = resp.body;
all.download = body.base_url + '/{{ download }}'; all.download = body.base_url + '/{{ download }}';
@@ -31,11 +31,11 @@ module.exports = function (request) {
os: osname, os: osname,
arch: 'amd64', arch: 'amd64',
hash: '-', // not sure about including hash / sha256 yet hash: '-', // not sure about including hash / sha256 yet
download: asset.archive download: asset.archive,
}); });
}); });
}); });
}) }),
).then(function () { ).then(function () {
all.releases.sort(function (a, b) { all.releases.sort(function (a, b) {
if ('stable' === a.channel && a.channel !== b.channel) { 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 ### Use space-delimited regular expressions to search
```txt ```text
^README | .md$ | .txt$ ^README | .md$ | .txt$
``` ```

View File

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

View File

@@ -53,6 +53,4 @@ Remove-Item -Path "$pkg_dst" -Recurse -ErrorAction Ignore
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse
# Add to path # Add to path
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/opt/git/cmd webi_path_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() { __init_git() {
if [ -z "$(command -v git)" ]; then if [ -z "$(command -v git)" ]; then
if uname -a | grep -q -i darwin; then if [ "Darwin" = "$(uname -s)" ]; then
echo >&2 "Error: 'git' not found. You may have to re-install 'git' on Mac after every major update." 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" echo >&2 " for example, try: xcode-select --install"
# sudo xcodebuild -license accept # 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 The deploy scripts should exist in your `scripts/` directory, named after the
repo's name. repo's name.
```txt ```text
scripts/github.com/YOUR_ORG/YOUR_PROJECT/deploy.sh scripts/github.com/YOUR_ORG/YOUR_PROJECT/deploy.sh
``` ```

View File

@@ -3,9 +3,9 @@ set -e
set -u set -u
__redirect_alias_gpg() { __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"} 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 __redirect_alias_gpg

View File

@@ -5,7 +5,7 @@ set -u
__run_go_essentials() { __run_go_essentials() {
WEBI__GO_ESSENTIALS='true' WEBI__GO_ESSENTIALS='true'
export WEBI__GO_ESSENTIALS export WEBI__GO_ESSENTIALS
if [ -z "${WEBI__GO_INSTALL:-}" ]; then if [ -z "${WEBI__GO_INSTALL-}" ]; then
"$HOME/.local/bin/webi" "golang@${WEBI_TAG}" "$HOME/.local/bin/webi" "golang@${WEBI_TAG}"
fi fi

View File

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

View File

@@ -8,6 +8,14 @@ tagline: |
To update or switch versions, run `webi golang@stable` (or `@v1.19`, `@beta`, To update or switch versions, run `webi golang@stable` (or `@v1.19`, `@beta`,
etc). etc).
### Files
```text
~/.config/envman/PATH.env
~/.local/opt/go/
~/go/
```
## Cheat Sheet ## Cheat Sheet
> Go is designed, through and through, to make Software Engineering easy. It's > Go is designed, through and through, to make Software Engineering easy. It's
@@ -55,7 +63,7 @@ You may also want to install the Go IDE tooling:
./hello ./hello
``` ```
You should see your output: You should see your output:
```txt ```text
> Hello, World! > Hello, World!
``` ```

View File

@@ -85,11 +85,7 @@ echo stringer
& "$pkg_dst_cmd" install golang.org/x/tools/cmd/stringer & "$pkg_dst_cmd" install golang.org/x/tools/cmd/stringer
# Add to path # Add to path
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/opt/go/bin webi_path_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 # Special to go: add default GOBIN to PATH
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/go/bin webi_path_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,7 +15,7 @@ pkg_cmd_name="go"
# #
# Their defaults are defined in _webi/template.sh at https://github.com/webinstall/packages # Their defaults are defined in _webi/template.sh at https://github.com/webinstall/packages
if [ -z "${WEBI__GO_ESSENTIALS:-}" ]; then if [ -z "${WEBI__GO_ESSENTIALS-}" ]; then
# TODO nix for go1.21+ # TODO nix for go1.21+
echo >&2 "" echo >&2 ""
printf >&2 '\e[31m%s:\e[0m\n' '#####################' printf >&2 '\e[31m%s:\e[0m\n' '#####################'
@@ -69,7 +69,7 @@ pkg_post_install() {
webi_path_add "$pkg_dst_bin" webi_path_add "$pkg_dst_bin"
webi_path_add "$GOBIN/bin" webi_path_add "$GOBIN/bin"
if [ -z "${WEBI__GO_ESSENTIALS:-}" ]; then if [ -z "${WEBI__GO_ESSENTIALS-}" ]; then
# TODO nix for go1.21+ # TODO nix for go1.21+
WEBI__GO_INSTALL='true' WEBI__GO_INSTALL='true'
export WEBI__GO_INSTALL export WEBI__GO_INSTALL

View File

@@ -1,10 +1,10 @@
'use strict'; 'use strict';
var osMap = { var osMap = {
darwin: 'macos' darwin: 'macos',
}; };
var archMap = { var archMap = {
386: 'x86' 386: 'x86',
}; };
function getAllReleases(request) { function getAllReleases(request) {
@@ -28,12 +28,12 @@ function getAllReleases(request) {
*/ */
return request({ return request({
url: 'https://golang.org/dl/?mode=json&include=all', url: 'https://golang.org/dl/?mode=json&include=all',
json: true json: true,
}).then((resp) => { }).then((resp) => {
var goReleases = resp.body; var goReleases = resp.body;
var all = { var all = {
releases: [], releases: [],
download: 'https://dl.google.com/go/{{ download }}' download: 'https://dl.google.com/go/{{ download }}',
}; };
goReleases.forEach((release) => { goReleases.forEach((release) => {
@@ -58,7 +58,7 @@ function getAllReleases(request) {
arch: arch, arch: arch,
ext: '', // let normalize run the split/test/join ext: '', // let normalize run the split/test/join
hash: '-', // not ready to standardize this yet 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): This is what the output of `gpg-pubkey` looks like (except much longer):
```txt ```text
GnuPG Public Key ID: CA025BC42F00BBBE GnuPG Public Key ID: CA025BC42F00BBBE
~/Downloads/john@example.com.gpg.asc: ~/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 These are the files / directories that are created and/or modified with this
install: install:
```txt ```text
~/.config/envman/PATH.env ~/.config/envman/PATH.env
~/.local/bin/gpg-pubkey ~/.local/bin/gpg-pubkey
~/.local/bin/gpg-pubkey-id ~/.local/bin/gpg-pubkey-id
@@ -143,7 +143,7 @@ format:
gpg --list-secret-keys --keyid-format LONG gpg --list-secret-keys --keyid-format LONG
``` ```
```txt ```text
/Users/me/.gnupg/pubring.kbx /Users/me/.gnupg/pubring.kbx
---------------------------- ----------------------------
sec rsa3072/CA025BC42F00BBBE 2021-11-10 [SCEA] 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`: The line with the Public Key ID is the one that starts with `sec`:
```txt ```text
sec rsa3072/CA025BC42F00BBBE 2021-11-10 [SCEA] 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 These are the files / directories that are created and/or modified with this
install: install:
```txt ```text
~/.config/envman/PATH.env ~/.config/envman/PATH.env
~/.local/opt/gnupg/bin/gpg ~/.local/opt/gnupg/bin/gpg
~/.local/opt/gnupg/bin/gpg-agent ~/.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 `gpg` is generally expected to be used with a Desktop client. On Linux servers
you may get this error: you may get this error:
```txt ```text
error: gpg failed to sign the data error: gpg failed to sign the data
fatal: failed to write commit object fatal: failed to write commit object
``` ```

View File

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

View File

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

View File

@@ -3,9 +3,9 @@ set -e
set -u set -u
__redirect_alias_iterm2_themes() { __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"} 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 __redirect_alias_iterm2_themes

View File

@@ -3,9 +3,9 @@ set -e
set -u set -u
__redirect_alias_iterm2_themes() { __redirect_alias_iterm2_themes() {
echo "'iterm-themes@${WEBI_TAG:-stable}' is an alias for 'iterm2-themes@${WEBI_VERSION:-}'" echo "'iterm-themes@${WEBI_TAG:-stable}' is an alias for 'iterm2-themes@${WEBI_VERSION-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"} 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 __redirect_alias_iterm2_themes

View File

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

View File

@@ -2,6 +2,6 @@
set -e set -e
set -u set -u
echo "'iterm@${WEBI_TAG:-stable}' is an alias for 'iterm2@${WEBI_VERSION:-}'" echo "'iterm@${WEBI_TAG:-stable}' is an alias for 'iterm2@${WEBI_VERSION-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"} WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/iterm2@${WEBI_VERSION:-}" | sh curl -fsSL "$WEBI_HOST/iterm2@${WEBI_VERSION-}" | sh

View File

@@ -3,9 +3,9 @@ set -e
set -u set -u
__redirect_alias_iterm2_themes() { __redirect_alias_iterm2_themes() {
echo "'iterm2-color-schemes@${WEBI_TAG:-stable}' is an alias for 'iterm2-themes@${WEBI_VERSION:-}'" echo "'iterm2-color-schemes@${WEBI_TAG:-stable}' is an alias for 'iterm2-themes@${WEBI_VERSION-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"} 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 __redirect_alias_iterm2_themes

View File

@@ -15,7 +15,7 @@ tagline: |
The installer will download them to `~/Downloads/webi/iterm2-themes` The installer will download them to `~/Downloads/webi/iterm2-themes`
```txt ```text
~/Downloads/webi/iterm2-themes/Tomorrow\ Night.itermcolors ~/Downloads/webi/iterm2-themes/Tomorrow\ Night.itermcolors
~/Downloads/webi/iterm2-themes/Firewatch.itermcolors ~/Downloads/webi/iterm2-themes/Firewatch.itermcolors
~/Downloads/webi/iterm2-themes/Dracula.itermcolors ~/Downloads/webi/iterm2-themes/Dracula.itermcolors

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