Compare commits

..

59 Commits

Author SHA1 Message Date
AJ ONeal
1750b92932 feat: add beyond-shell (for Workshops) 2023-03-07 11:26:15 +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
148 changed files with 2441 additions and 577 deletions

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

@@ -15,7 +15,7 @@ __install_webi() {
export WEBI_HOST
echo ""
printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[31m%s/%s\e[0m'.\n" "${WEBI_PKG:-}" "$(uname -s)" "$(uname -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 " https://github.com/webinstall/webi-installers/issues"
echo ""
@@ -93,7 +93,7 @@ __webi_main() {
set -e
export WEBI_HOST="\${WEBI_HOST:-https://webinstall.dev}"
export WEBI_UA="\$(uname -a)"
export WEBI_UA="\$(uname -s)/\$(uname -r) \$(uname -m)/unknown"
webinstall() {
@@ -214,13 +214,13 @@ EOF
chmod a+x "$HOME/.local/bin/webi"
if [ -n "${WEBI_PKG:-}" ]; then
if [ -n "${WEBI_PKG-}" ]; then
"$HOME/.local/bin/webi" "${WEBI_PKG}"
else
echo ""
echo "Hmm... no WEBI_PKG was specified. This is probably an error in the script."
echo ""
echo "Please open an issue with this information: Package '${WEBI_PKG:-}' on '$(uname -s)/$(uname -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 ""
fi

View File

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

View File

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

View File

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

View File

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

View File

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

@@ -30,16 +30,25 @@ __bootstrap_webi() {
#PKG_OSES=
#PKG_ARCHES=
#PKG_FORMATS=
WEBI_UA="$(uname -a)"
WEBI_UA="$(uname -s)/$(uname -r) $(uname -m)/unknown"
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
##
## Set up tmp, download, and install directories
##
WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-"${WEBI_PKG:-}".XXXXXXXX)"}
WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-"${WEBI_PKG-}".XXXXXXXX)"}
export _webi_tmp="${_webi_tmp:-"$HOME/.local/opt/webi-tmp.d"}"
mkdir -p "${WEBI_PKG_PATH}"
@@ -82,7 +91,7 @@ __bootstrap_webi() {
return 0
fi
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1:-}" ]; then
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1-}" ]; then
rm -rf "$pkg_dst_cmd"
ln -s "$pkg_src_cmd" "$pkg_dst_cmd"
else
@@ -150,12 +159,12 @@ __bootstrap_webi() {
# detect if file is downloaded, and how to download it
webi_download() {
# determine the url to download
if [ -n "${1:-}" ]; then
if [ -n "${1-}" ]; then
my_url="$1"
else
if [ "error" = "$WEBI_CHANNEL" ]; then
# TODO pass back requested OS / Arch / Version
echo >&2 "Error: no '$PKG_NAME' release for '${WEBI_OS:-}' on '$WEBI_ARCH' as one of '$WEBI_FORMATS' by the tag '${WEBI_TAG:-}'"
echo >&2 "Error: no '$PKG_NAME' release for '${WEBI_OS-}' on '$WEBI_ARCH' as one of '$WEBI_FORMATS' by the tag '${WEBI_TAG-}'"
echo >&2 " '$PKG_NAME' is available for '$PKG_OSES' on '$PKG_ARCHES' as one of '$PKG_FORMATS'"
echo >&2 " (check that the package name and version are correct)"
echo >&2 ""
@@ -167,7 +176,7 @@ __bootstrap_webi() {
fi
# determine the location to download to
if [ -n "${2:-}" ]; then
if [ -n "${2-}" ]; then
my_dl="$2"
else
my_dl="${WEBI_PKG_PATH}/$WEBI_PKG_FILE"
@@ -274,7 +283,7 @@ __bootstrap_webi() {
# shellcheck disable=2120
# webi_install may be sourced and used elsewhere
webi_install() {
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1:-}" ]; then
if [ -n "$WEBI_SINGLE" ] || [ "single" = "${1-}" ]; then
mkdir -p "$(dirname "$pkg_src_cmd")"
mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
else
@@ -328,9 +337,9 @@ __bootstrap_webi() {
WEBI_SINGLE=
if [ -z "${WEBI_WELCOME:-}" ]; then
if [ -z "${WEBI_WELCOME-}" ]; then
echo ""
printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[31m%s/%s\e[0m'.\n" "${WEBI_PKG:-}" "$(uname -s)" "$(uname -m)"
printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[31m%s/%s\e[0m'.\n" "${WEBI_PKG-}" "$(uname -s)" "$(uname -m)"
echo "Have a problem? Experience a bug? Please let us know:"
echo " https://github.com/webinstall/webi-installers/issues"
echo ""
@@ -362,14 +371,14 @@ __bootstrap_webi() {
command -v pkg_post_install > /dev/null ||
command -v pkg_done_message > /dev/null ||
command -v pkg_format_cmd_version > /dev/null ||
[ -n "${WEBI_SINGLE:-}" ] ||
[ -n "${pkg_cmd_name:-}" ] ||
[ -n "${pkg_dst_cmd:-}" ] ||
[ -n "${pkg_dst_dir:-}" ] ||
[ -n "${pkg_dst:-}" ] ||
[ -n "${pkg_src_cmd:-}" ] ||
[ -n "${pkg_src_dir:-}" ] ||
[ -n "${pkg_src:-}" ]; then
[ -n "${WEBI_SINGLE-}" ] ||
[ -n "${pkg_cmd_name-}" ] ||
[ -n "${pkg_dst_cmd-}" ] ||
[ -n "${pkg_dst_dir-}" ] ||
[ -n "${pkg_dst-}" ] ||
[ -n "${pkg_src_cmd-}" ] ||
[ -n "${pkg_src_dir-}" ] ||
[ -n "${pkg_src-}" ]; then
pkg_cmd_name="${pkg_cmd_name:-$PKG_NAME}"
@@ -420,7 +429,7 @@ __bootstrap_webi() {
fi
webi_path_add "$HOME/.local/bin"
if [ -z "${_WEBI_CHILD:-}" ] && [ -f "$_webi_tmp/.PATH.env" ]; then
if [ -z "${_WEBI_CHILD-}" ] && [ -f "$_webi_tmp/.PATH.env" ]; then
if [ -n "$(cat "$_webi_tmp/.PATH.env")" ]; then
printf 'PATH.env updated with:\n'
sort -u "$_webi_tmp/.PATH.env"

View File

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

View File

@@ -3,8 +3,10 @@
var path = require('path');
var Releases = require('./releases.js');
var cache = {};
var staleAge = 5 * 1000;
var expiredAge = 15 * 1000;
//var staleAge = 5 * 1000;
//var expiredAge = 15 * 1000;
var staleAge = 5 * 60 * 1000;
var expiredAge = 15 * 60 * 1000;
let installerDir = path.join(__dirname, '..');
@@ -64,64 +66,102 @@ function createFormatsSorter(formats) {
async function getCachedReleases(pkg) {
// returns { download: '<template string>', releases: [{ version, date, os, arch, lts, channel, download}] }
function putCache() {
cache[pkg].promise = cache[pkg].promise.then(function () {
var age = Date.now() - cache[pkg].updatedAt;
if (age < staleAge) {
//console.debug('NOT STALE ANYMORE - updated in previous promise');
return cache[pkg].all;
}
//console.debug('DOWNLOADING NEW "%s" releases', pkg);
var pkgdir = path.join(installerDir, pkg);
return Releases.get(pkgdir)
.then(function (all) {
//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;
});
});
async function chainCachePromise(fn) {
cache[pkg].promise = cache[pkg].promise.then(fn);
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]) {
cache[pkg] = {
updatedAt: 0,
all: null,
promise: Promise.resolve()
all: { download: '', releases: [] },
promise: Promise.resolve(),
};
}
var bgRenewal;
var age = Date.now() - cache[pkg].updatedAt;
if (age >= expiredAge) {
//console.debug("EXPIRED - waiting");
p = putCache();
} else if (age >= staleAge) {
//console.debug("STALE - background update");
putCache();
p = Promise.resolve(cache[pkg].all);
} else {
//console.debug("FRESH");
p = Promise.resolve(cache[pkg].all);
var fresh = age < staleAge;
if (!fresh) {
bgRenewal = chainCachePromise(putCache);
}
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(
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)
// sort the most compatible format first
@@ -163,7 +203,7 @@ module.exports = function getReleases({
lts,
channel,
formats,
limit
limit,
}) {
if (!_count) {
_count = 0;
@@ -176,14 +216,14 @@ module.exports = function getReleases({
lts,
channel,
formats,
limit
limit,
})
.catch(function (err) {
if ('MODULE_NOT_FOUND' === err.code) {
return null;
}
console.error(
'TODO: lib/release.js: check type of error, such as MODULE_NOT_FOUND'
'TODO: lib/release.js: check type of error, such as MODULE_NOT_FOUND',
);
console.error(err);
})
@@ -199,7 +239,7 @@ module.exports = function getReleases({
lts,
channel,
formats,
limit
limit,
});
}
// Raspberry Pi 3+ on Raspbian x86 (not Ubuntu arm64)
@@ -213,7 +253,7 @@ module.exports = function getReleases({
lts,
channel,
formats,
limit
limit,
});
}
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?)
@@ -228,7 +268,7 @@ module.exports = function getReleases({
lts,
channel,
formats,
limit
limit,
});
}
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?)
@@ -242,7 +282,7 @@ module.exports = function getReleases({
lts,
channel,
formats,
limit
limit,
});
}
releases = [
@@ -260,15 +300,15 @@ module.exports = function getReleases({
comment:
'No matches found. Could be bad or missing version info' +
',' +
"Check query parameters. Should be something like '/api/releases/{package}@{version}.tab?os={macos|linux|windows|-}&arch={amd64|x86|aarch64|arm64|armv7l|-}&limit=100'"
}
"Check query parameters. Should be something like '/api/releases/{package}@{version}.tab?os={macos|linux|windows|-}&arch={amd64|x86|aarch64|arm64|armv7l|-}&limit=100'",
},
];
}
return {
oses: all.oses,
arches: all.arches,
formats: all.formats,
releases: releases
releases: releases,
};
});
});
@@ -284,7 +324,7 @@ if (require.main === module) {
lts: true,
channel: 'stable',
formats: ['tar', 'exe', 'zip', 'xz', 'dmg', 'pkg'],
limit: 10
limit: 10,
})
.then(function (all) {
console.info(JSON.stringify(all));

View File

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

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).
### Files
```text
~/.config/envman/PATH.env
~/.local/opt/archiver/
```
## Cheat Sheet
> 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
```txt
```text
# arc ls <archive file>
arc ls example.zip
```
### Unarchive (whole)
```txt
```text
# arc unarchive <archive file>
arc unarchive example.zip
```
### Extract (partial)
```txt
```text
# arc extract <archive file> <archived path> <extracted path>
arc extract example.zip example/foo ~/Downloads/foo
```
### Archive (recursive)
```txt
```text
# arc archive <archive file> <files or folders ...>
arc archive example.zip ./README.md ./bin ./src
```
### Compress (single file)
```txt
```text
# arc compress <single file> <format>
arc compress ./example.tar xz
```
### Decompress (single file)
```txt
```text
# arc decompress <archive file>
arc decompress ./example.tar.xz
```

View File

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

View File

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

View File

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

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

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

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

@@ -0,0 +1,339 @@
#!/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_fish_install() { (
if ! command -v fish > /dev/null; 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 (may require password)\n"
sleep 1
if [ "Darwin" = "$(uname -s)" ]; then
"${webi_cmd}" fish
else
echo sudo apt-get install fish
export DEBIAN_FRONTEND=noninteractive
if ! sudo apt-get install -qq -y -o=Dpkg::Use-Pty=0 fish; then
echo "failed to install fish on"
cat /etc/issue
fi
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 ""
echo "[Info] PATH updates in ~/.config/envman/PATH.env"
if [ "Darwin" = "$(uname -s)" ]; then
"${webi_cmd}" iterm2
fi
fn_fish_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 ""
fn_path_bin
fn_touch ~/.vimrc '~'/.vimrc
fn_touch ~/.config/envman/alias.env '~'/.config/envman/alias.env
echo ""
fn_node_install
for my_cmd in aliasman bat curlie jq pathman shfmt@3.5 shellcheck 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 ""
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
} | 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
#/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")"
if [ -n "${needs_xcode}" ]; then
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
```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
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
localhost {
handle /api/* {
reverse_proxy localhost:3000
}
handle /* {
root * ./public/
file_server
}
handle /api/* {
reverse_proxy localhost:3000
}
}
```
### How to serve on Linux/VPS (systemd)
1. Create a generic `Caddyfile`
```sh
mkdir -p ~/srv/caddy
echo '
# Generically vhost all domains pointed at this server
https:// {
tls {
on_demand
}
handle /* {
file_server
root * /home/app/srv/www/{host}/public/
}
}
' > ~/srv/caddy/Caddyfile
```
2. Install serviceman
```sh
webi serviceman
source ~/.config/envman/PATH.env
```
3. Install caddy as a system service
```sh
sudo env PATH="$PATH" \
serviceman add --system --username "$(whoami)" --name caddy -- \
caddy run --config ~/srv/caddy/Caddyfile
```
Note: In this example any host that points to the server and has files in
`~/srv/www/{host}/public` can be served without additional changes.
Note: More on using `systemctl` below.
```sh
caddyfile run --config ./Caddyfile
```
### 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
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**
You can use `setcap` or [`setcap-netbind`](/setcap-netbind) to allow Caddy to
use privileged ports.
You can use `setcap` to allow Caddy to use privileged ports.
```sh
sudo setcap cap_net_bind_service=+ep "$(readlink -f "$(command -v caddy)")"
sudo setcap cap_net_bind_service=+ep $(readlink -f $(command -v caddy))
```
**systemd config**

View File

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

View File

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

View File

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

View File

@@ -34,7 +34,7 @@ dashmsg gen > pirv.wif
dashmsg sign ./priv.wif 'vote2022-alice|bob|charlie'
```
```txt
```text
H2Opy9NX72iPZRcDVEHrFn2qmVwWMgc+DKILdVxl1yfmcL2qcpu9esw9wcD7RH0/dJHnIISe5j39EYahorWQM7I=
```
@@ -58,7 +58,7 @@ Addresses:
dashmsg inspect 'XK5DHnAiSj6HQNsNcDkawd9qdp8UFMdYftdVZFuRreTMJtbJhk8i'
```
```txt
```text
PrivateKey (hex): cc (coin type)
: e84f59fec1c8cc7feb9ce1c829849ae336f73e56437301eb5db945c8e0dd2683
: 01 (compressed)
@@ -76,7 +76,7 @@ Address (b58c): Xn4A2vv5fb7LvmiiXPPMexYbSbiQ29rzDu
dashmsg inspect 'IFLv0JVRM70bTZCTmzMfNX3NVkSULmnAR/3PSWpgC5GXBD7rRi5g4QsK968ITE3dfKdzhX7fAIXwhpnsP0WvQOc='
```
```txt
```text
I (0): 1 (quadrant)
R (1-32): 52efd0955133bd1b4d90939b331f357dcd5644942e69c047fdcf496a600b9197
S (33-64): 043eeb462e60e10b0af7af084c4ddd7ca773857edf0085f08699ec3f45af40e7
@@ -88,7 +88,7 @@ S (33-64): 043eeb462e60e10b0af7af084c4ddd7ca773857edf0085f08699ec3f45af40e7
dashmsg inspect 'Xn4A2vv5fb7LvmiiXPPMexYbSbiQ29rzDu'
```
```txt
```text
Address (hex): 4c (coin type)
: 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`.
### Files
These are the files that are created and/or modified with this installer:
```text
~/.config/envman/PATH.env
~/.gitconfig
~/.local/bin/delta
~/.local/opt/delta-VERSION/bin/delta
```
## Cheat Sheet
> `delta` gives you GitHub-style diffs, with word-level diff coloring, right in
@@ -26,17 +37,6 @@ Here we'll cover:
For the full set of options, be sure to check out the helpful
[README](https://github.com/dandavison/delta).
## Files
These are the files that are created and/or modified with this installer:
```txt
~/.config/envman/PATH.env
~/.gitconfig
~/.local/bin/delta
~/.local/opt/delta-VERSION/bin/delta
```
## How to set delta's color scheme
Delta uses `~/.gitconfig` for most of its options.
@@ -73,7 +73,7 @@ Here's the current list, for convenience:
### Dark Syntax Themes
```txt
```text
1337
Coldark-Cold
Coldark-Dark
@@ -97,7 +97,7 @@ zenburn
### Light Syntax Themes
```txt
```text
GitHub
Monokai Extended Light
OneHalfLight

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`:
```txt
```text
DuplicatedKey
EndingBlankLine
ExtraBlankLine

View File

@@ -31,7 +31,7 @@ dotenv -f .env -- node server.js --debug
## ENV syntax
```txt
```text
# comments and blank lines are ignored
# 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

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

View File

@@ -2,7 +2,15 @@
set -e
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 " sudo apt install -y fish"
exit 1
@@ -77,6 +85,12 @@ pkg_post_install() {
# try again to update default shells, now that all files should exist
_macos_post_install
if [ ! -e ~/.config/fish/config.fish ]; then
mkdir -p ~/.config/fish
touch ~/.config/fish/config.fish
chmod 0600 ~/.config/fish/config.fish
fi
}
# pkg_get_current_version is recommended, but (soon) not required

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,7 +5,7 @@ set -u
__init_git() {
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 " for example, try: xcode-select --install"
# sudo xcodebuild -license accept

View File

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

View File

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

View File

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

View File

@@ -3,9 +3,9 @@ set -e
set -u
__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"}
curl -fsSL "$WEBI_HOST/golang@${WEBI_VERSION:-}" | sh
curl -fsSL "$WEBI_HOST/golang@${WEBI_VERSION-}" | sh
}
__redirect_alias_golang

View File

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

View File

@@ -15,7 +15,7 @@ pkg_cmd_name="go"
#
# 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+
echo >&2 ""
printf >&2 '\e[31m%s:\e[0m\n' '#####################'
@@ -69,7 +69,7 @@ pkg_post_install() {
webi_path_add "$pkg_dst_bin"
webi_path_add "$GOBIN/bin"
if [ -z "${WEBI__GO_ESSENTIALS:-}" ]; then
if [ -z "${WEBI__GO_ESSENTIALS-}" ]; then
# TODO nix for go1.21+
WEBI__GO_INSTALL='true'
export WEBI__GO_INSTALL

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,9 +3,9 @@ set -e
set -u
__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"}
curl -fsSL "$WEBI_HOST/iterm2-themes@${WEBI_VERSION:-}" | sh
curl -fsSL "$WEBI_HOST/iterm2-themes@${WEBI_VERSION-}" | sh
}
__redirect_alias_iterm2_themes

View File

@@ -3,9 +3,9 @@ set -e
set -u
__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"}
curl -fsSL "$WEBI_HOST/iterm2-utils@${WEBI_VERSION:-}" | sh
curl -fsSL "$WEBI_HOST/iterm2-utils@${WEBI_VERSION-}" | sh
}
__redirect_alias_iterm2_utils

View File

@@ -2,6 +2,6 @@
set -e
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"}
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
__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"}
curl -fsSL "$WEBI_HOST/iterm2-themes@${WEBI_VERSION:-}" | sh
curl -fsSL "$WEBI_HOST/iterm2-themes@${WEBI_VERSION-}" | sh
}
__redirect_alias_iterm2_themes

View File

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

View File

@@ -5,6 +5,17 @@ tagline: |
iTerm2: a terminal emulator for macOS that does amazing things.
---
To update versions, use iTerm2's built-in software update.
### Files
These are the files / directories that are created and/or modified with this
install:
```text
/Applications/iTerm.app/
```
## Cheat Sheet
> The only bad thing about iTerm2 is that it's so seamless and intuitive that
@@ -22,7 +33,7 @@ iTerm2 supports a lot of nifty features, including:
- GPU-accelerated
**Important**: Unlike most packages, iTerm2 will be installed to
`~/Applications`.
`/Applications`.
### How to make the best of iTerm2

View File

@@ -25,11 +25,11 @@ _install_iterm2() {
exit 1
fi
if [ -d ~/Applications/iTerm.app ]; then
mv ~/Applications/iTerm.app "${WEBI_TMP}/iTerm.app-webi.bak"
if [ -d /Applications/iTerm.app ]; then
mv /Applications/iTerm.app "${WEBI_TMP}/iTerm.app-webi.bak"
fi
mkdir -p ~/Applications/
mv "${WEBI_TMP}/iTerm.app" ~/Applications/
mkdir -p /Applications/
mv "${WEBI_TMP}/iTerm.app" /Applications/
}
_install_iterm2

View File

@@ -2,7 +2,7 @@
function getRawReleases(request) {
return request({ url: 'https://iterm2.com/downloads.html' }).then(function (
resp
resp,
) {
var links = resp.body
.split(/[<>]+/g)
@@ -40,10 +40,10 @@ function transformReleases(links) {
os: 'macos',
arch: 'amd64',
ext: '', // let normalize run the split/test/join
download: link
download: link,
};
})
.filter(Boolean)
.filter(Boolean),
};
}

View File

@@ -27,7 +27,7 @@ You can also [try online](https://jqplay.org/).
echo '{ "name": "foo" }' | jq '.name'
```
```txt
```text
"foo"
```
@@ -39,7 +39,7 @@ The `-r` or `--raw-output` flag unwraps strings:
echo '{ "name": "foo" }' | jq -r '.name'
```
```txt
```text
foo
```
@@ -49,7 +49,7 @@ foo
echo '{ "name": "foo" }' | jq '.'
```
```txt
```text
{
"name": "foo"
}
@@ -61,7 +61,7 @@ echo '{ "name": "foo" }' | jq '.'
echo '[ { "name": "foo" } ]' | jq '.[0]'
```
```txt
```text
{
"name": "foo"
}
@@ -73,7 +73,7 @@ echo '[ { "name": "foo" } ]' | jq '.[0]'
echo '[ { "name": "foo" } ]' | jq -r '.[0].name'
```
```txt
```text
foo
```
@@ -84,7 +84,7 @@ echo '[ { "name": "foo" }, { "name": "bar" } ]' \
| jq -r '.[].name'
```
```txt
```text
foo
bar
```
@@ -106,7 +106,7 @@ echo '[ { "name": "foo", "age": 0 }, { "name": "bar", "age": 2 } ]' \
| jq '{ names: [.[] | .name], ages: [.[] | .age] }'
```
```txt
```text
{
"names": [
"foo",

View File

@@ -13,7 +13,7 @@ etc).
These are the files / directories that are created and/or modified with this
install:
```txt
```text
~/.config/envman/PATH.env
~/.local/opt/node
~/.jshintrc.defaults.json5
@@ -111,7 +111,7 @@ Engineering_ (as opposed to just _Code Monkey_-ing around):
strict: true,
maxdepth: 4,
maxstatements: 100,
maxcomplexity: 20
maxcomplexity: 20,
}
```
@@ -147,8 +147,8 @@ certain file patterns and directories.
esversion: 11,
overrides: {
'./browser/*.js': {
esversion: 7
}
}
esversion: 7,
},
},
}
```

View File

@@ -50,7 +50,7 @@ keypairs sign --exp 1h key.jwk.json '{ "sub": "me@example.com" }' > token.jwt 2>
A JWT (JSON Web Token) has 3 sections (protected header, payload, and signature)
separated by dots (`.`):
```txt
```text
eyJhbGciOiJFUzI1NiIsImtpZCI6ImpkeHhZY1NCZUJfeUdoZWlCVW14NjF0eHExZGFjR1hIX191bEJuWlZHMEUiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjIxNDczODU3MTIsInN1YiI6Im1lQGV4YW1wbGUuY29tIn0.oh8-PUMdrbQU6seRXjo68wPWAKbA-V9LMnd_wZEkPHc3C8A5xJzV7mDDMNOLEy4VcuNGxced_yjYulzcMa5FLQ
```

View File

@@ -25,7 +25,7 @@ You can use koji in one of two ways:
Here's the shortlist of options we've found most useful:
```txt
```text
-e, --emoji - use emoji for commit type (ex: `✨ feat:`)
-a, --autocomplete - guess 'scope' based on commit history (slow on large projects)
--hook - expect to be run from 'git commit', rather than wrap it

View File

@@ -48,7 +48,20 @@ lsd
### How to alias as `ls`, `ll`, `la`, etc
Update your `.bashrc`, `.zshrc`, or `.profile`
This will affect the interactive shell, but not scripts.
Using [aliasman](/aliasman):
```sh
aliasman ls "lsd -F"
aliasman la "lsd -AF"
aliasman ll "lsd -lAF"
aliasman lg "lsd -F --group-dirs=first"
```
(and follow the on-screen instructions or restart your shell)
Or manually update your `.bashrc`, `.zshrc`, or `.profile`
```sh
alias ls="lsd -F"
@@ -66,7 +79,14 @@ the alias:
### How to alias as `tree`
Update your `.bashrc`, `.zshrc`, or `.profile`
Using [aliasman](/aliasman):
```sh
aliasman tree "lsd -AF --tree"
alias tree="lsd -AF --tree"
```
Or manually update your `.bashrc`, `.zshrc`, or `.profile`
```sh
alias tree="lsd -AF --tree"

View File

@@ -12,6 +12,6 @@ tagline: |
Use with Balena Etcher to burn ISO to USB, or boot with VirtualBox.
```txt
```text
Created ~/Downloads/el-capitan.iso
```

View File

@@ -6,7 +6,7 @@ var oses = [
version: '10.12.6',
date: '2018-09-26',
channel: 'beta',
url: 'https://support.apple.com/en-us/HT208202'
url: 'https://support.apple.com/en-us/HT208202',
},
{
name: 'OS X El Capitan',
@@ -14,15 +14,15 @@ var oses = [
date: '2018-07-09',
lts: true,
channel: 'stable',
url: 'https://support.apple.com/en-us/HT206886'
url: 'https://support.apple.com/en-us/HT206886',
},
{
name: 'OS X Yosemite',
version: '10.10.5',
date: '2017-07-19',
channel: 'beta',
url: 'https://support.apple.com/en-us/HT210717'
}
url: 'https://support.apple.com/en-us/HT210717',
},
];
var headers = {
@@ -37,7 +37,7 @@ var headers = {
'Sec-Fetch-Site': 'none',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-User': '?1',
'Accept-Language': 'en-US,en;q=0.9,sq;q=0.8'
'Accept-Language': 'en-US,en;q=0.9,sq;q=0.8',
};
module.exports = function (request) {
@@ -48,7 +48,7 @@ module.exports = function (request) {
return request({
method: 'GET',
url: os.url,
headers: headers
headers: headers,
}).then(function (resp) {
var m = resp.body.match(/(http[^>]+Install[^>]+.dmg)/);
var download = m && m[1];
@@ -62,11 +62,11 @@ module.exports = function (request) {
arch: 'amd64',
ext: 'dmg',
hash: '-',
download: download
download: download,
});
});
});
})
}),
).then(function () {
all.releases.sort(function (a, b) {
if ('10.11.6' === a.version) {

View File

@@ -41,8 +41,8 @@ module.exports = function (request) {
download:
'http://archive.mariadb.org/mariadb-{{ v }}/bintar-linux-x86_64/mariadb-{{ v }}-linux-x86_64.tar.gz'.replace(
/{{ v }}/g,
ver.version
)
ver.version,
),
});
all.releases.push({
version: ver.version,
@@ -54,8 +54,8 @@ module.exports = function (request) {
download:
'http://archive.mariadb.org/mariadb-{{ v }}/bintar-linux-x86/mariadb-{{ v }}-linux-x86.tar.gz'.replace(
/{{ v }}/g,
ver.version
)
ver.version,
),
});
// windows
@@ -69,8 +69,8 @@ module.exports = function (request) {
download:
'http://archive.mariadb.org/mariadb-{{ v }}/winx64-packages/mariadb-{{ v }}-winx64.zip'.replace(
/{{ v }}/g,
ver.version
)
ver.version,
),
});
all.releases.push({
version: ver.version,
@@ -82,8 +82,8 @@ module.exports = function (request) {
download:
'http://archive.mariadb.org/mariadb-{{ v }}/win32-packages/mariadb-{{ v }}-win32.zip'.replace(
/{{ v }}/g,
ver.version
)
ver.version,
),
});
// Note: versions are sorted most-recent first.
@@ -95,7 +95,7 @@ module.exports = function (request) {
// 10.3 => ^10.2(\b|\.)
var reBrewVer = new RegExp(
'^' + brew.version.replace(/\./, '\\.') + '(\\b|\\.)',
'g'
'g',
);
if (!ver.version.match(reBrewVer)) {
return;
@@ -107,7 +107,7 @@ module.exports = function (request) {
date: ver.date,
os: 'macos',
arch: 'amd64',
download: brew.download.replace(/{{ v }}/g, ver.version)
download: brew.download.replace(/{{ v }}/g, ver.version),
});
brews.splice(i, 1); // remove
return true;
@@ -120,7 +120,7 @@ module.exports = function (request) {
function mariaReleases() {
return request({
url: 'https://downloads.mariadb.org/mariadb/+releases/',
fail: true // https://git.coolaj86.com/coolaj86/request.js/issues/2
fail: true, // https://git.coolaj86.com/coolaj86/request.js/issues/2
})
.then(failOnBadStatus)
.then(function (resp) {
@@ -159,7 +159,7 @@ module.exports = function (request) {
return {
version: m[1],
channel: mapChannel(m[3].toLowerCase()),
date: m[2]
date: m[2],
};
})
.filter(Boolean);
@@ -203,8 +203,8 @@ if (module === require.main) {
})
.slice(0, 2),
null,
2
)
2,
),
);
});
}

View File

@@ -20,7 +20,7 @@ webi myip
Example output:
```txt
```text
IPv4 (A) : 136.36.196.101
IPv6 (AAAA): 2605:a601:a919:9800:f8be:f2c4:9ad7:9763
```

View File

@@ -5,7 +5,7 @@ set -u
__redirect_alias_nerdfont() {
echo "'nerd-font' is an alias for 'nerdfont'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/nerdfont@${WEBI_VERSION:-}" | sh
curl -fsSL "$WEBI_HOST/nerdfont@${WEBI_VERSION-}" | sh
}
__redirect_alias_nerdfont

View File

@@ -9,6 +9,17 @@ To update or switch versions, run `webi node@<tag>`. \
(you can use `@lts` for long-term support, `@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/node/
~/.npmrc
```
## Cheat Sheet
> Node is great for simple, snappy HTTP(S) servers, and for stitching APIs
@@ -20,8 +31,6 @@ Installing node via webi will:
[Node Releases API](https://nodejs.org/dist/index.tab)
- download and unpack to `$HOME/.local/opt/node/`
- update your `PATH` in `$HOME/.config/envman/PATH.env`
- run `npm config set scripts-prepend-node-path=true`
- (prevents conflicts with other installed node versions)
- absolutely leave system file permissions alone
- (no dreaded `sudo npm` permission errors)

View File

@@ -40,8 +40,5 @@ echo "Copying into '$Env:USERPROFILE\.local\opt\$Env:PKG_NAME' from '$Env:USERPR
Remove-Item -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME" -Recurse -ErrorAction Ignore
Copy-Item -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERSION" -Destination "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME" -Recurse
# make npm not act stupid about which node to use... ugh (this should be the default)
& .\.local\opt\node\npm.cmd --scripts-prepend-node-path=true config set scripts-prepend-node-path true
# Add to path
& "$Env:USERPROFILE\.local\bin\pathman.exe" add ~/.local/opt/node

View File

@@ -37,9 +37,6 @@ pkg_link() {
# ln -s "$HOME/.local/opt/node-v14.4.0" "$HOME/.local/opt/node"
ln -s "$pkg_src" "$pkg_dst"
# Node bugfix: use the correct version of node, even if PATH has a conflict
"$pkg_src"/bin/node "$pkg_src"/bin/npm config set scripts-prepend-node-path=true
}
pkg_done_message() {

View File

@@ -23,18 +23,18 @@ var map = {
msi: 'msi',
'7z': '7z',
zip: 'zip',
tar: 'tar.gz'
tar: 'tar.gz',
};
function getAllReleases(request) {
return request({
url: 'https://nodejs.org/dist/index.json',
json: true
json: true,
}).then(function (resp) {
var rels = resp.body;
var all = {
releases: [],
download: '' // node's download URLs are unpredictable
download: '', // node's download URLs are unpredictable
};
// https://blog.risingstack.com/update-nodejs-8-end-of-life-no-support/
@@ -84,7 +84,7 @@ function getAllReleases(request) {
// See https://nodejs.org/dist/v14.0.0/
// usually like https://nodejs.org/dist/v14.0.0/node-{version}-{plat}-{arch}.{ext}
download:
'https://nodejs.org/dist/' + rel.version + '/node-' + rel.version
'https://nodejs.org/dist/' + rel.version + '/node-' + rel.version,
};
all.releases.push(r);

View File

@@ -12,7 +12,7 @@ To update or switch versions, run `webi ots@stable` (or `@v2`, `@beta`, etc).
These are the files / directories that are created and/or modified with this
install:
```txt
```text
~/.config/envman/PATH.env
~/.local/bin/ots
~/.local/opt/ots

22
package-lock.json generated
View File

@@ -1,13 +1,13 @@
{
"name": "@webinstall/webi-installers",
"version": "0.2.0",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@root/request": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/@root/request/-/request-1.6.1.tgz",
"integrity": "sha512-8wrWyeBLRp7T8J36GkT3RODJ6zYmL0/maWlAUD5LOXT28D3TDquUepyYDKYANNA3Gc8R5ZCgf+AXvSTYpJEWwQ=="
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@root/request/-/request-1.9.2.tgz",
"integrity": "sha512-wVaL9yVV9oDR9UNbPZa20qgY+4Ch6YN8JUkaE4el/uuS5dmhD8Lusm/ku8qJVNtmQA56XLzEDCRS6/vfpiHK2A=="
},
"dotenv": {
"version": "8.2.0",
@@ -15,17 +15,9 @@
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
},
"marked": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-1.1.0.tgz",
"integrity": "sha512-EkE7RW6KcXfMHy2PA7Jg0YJE1l8UPEZE8k45tylzmZM30/r1M1MUXWQfJlrSbsTeh7m/XTwHbWUENvAJZpp1YA=="
},
"shmatter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/shmatter/-/shmatter-1.0.1.tgz",
"integrity": "sha512-bBAvHI8640XcMDsShK2HOR8WOkF65hMprXr7Rsqb3z+26/5qna3jZfP7VZScItGoULUYyNeen9isD60KxtD2hQ==",
"requires": {
"marked": "^1.0.0"
}
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz",
"integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw=="
}
}
}

View File

@@ -15,7 +15,12 @@
"type": "git",
"url": "git+https://github.com/webinstall/webi-installers.git"
},
"keywords": ["webinstall", "brew", "apt", "chocolately"],
"keywords": [
"webinstall",
"brew",
"apt",
"chocolately"
],
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
"license": "MPL-2.0",
"bugs": {
@@ -23,8 +28,8 @@
},
"homepage": "https://github.com/webinstall/webi-installers#readme",
"dependencies": {
"@root/request": "^1.6.1",
"@root/request": "^1.9.2",
"dotenv": "^8.2.0",
"shmatter": "^1.0.1"
"marked": "^4.1.1"
}
}

View File

@@ -40,7 +40,7 @@ Note: Even on Windows it is best to use Unix-style `/` paths and `~` for
pathman list
```
```txt
```text
pathman-managed PATH entries:
$HOME/.local/bin

View File

@@ -28,11 +28,19 @@ pkg_link() {
# rm -f "$HOME/.local/opt/postgres"
rm -f "$pkg_dst"
rm -f "$HOME/Applications/pgAdmin"*.app || true
rm -f "/Applications/pgAdmin"*.app || true
# ln -s "$HOME/.local/opt/postgres-v10.13" "$HOME/.local/opt/postgres"
ln -s "$pkg_src" "$pkg_dst"
mkdir -p ~/Applications
ln -s "$pkg_src/pgAdmin 4.app" "$HOME/Applications/pgAdmin 4.app" || true
if [ "Darwin" = "$(uname -s)" ]; then
mkdir -p /Applications
ln -s "$pkg_src/pgAdmin 4.app" "/Applications/pgAdmin 4.app" || true
if [ -e "$pkg_src/pgAdmin 4.app/Contents/Resources/venv/lib/libpython3.8.dylib" ]; then
# a simple patch to fix the bad link in the package
rm "$pkg_src/pgAdmin 4.app/Contents/Resources/venv/lib/libpython3.8.dylib"
ln -s "../../../Frameworks/Python" "$pkg_src/pgAdmin 4.app/Contents/Resources/venv/lib/libpython3.8.dylib"
fi
fi
}
pkg_post_install() {

View File

@@ -17,7 +17,7 @@ module.exports = async function () {
os: 'linux',
arch: 'amd64',
ext: 'tar',
download: ''
download: '',
},
{
name: 'postgresql-10.12-1-linux-binaries.tar.gz',
@@ -28,7 +28,7 @@ module.exports = async function () {
os: 'linux',
arch: 'x86',
ext: 'tar',
download: ''
download: '',
},
{
name: 'postgresql-10.12-1-osx-binaries.zip',
@@ -39,7 +39,7 @@ module.exports = async function () {
os: 'macos',
arch: 'amd64',
ext: 'zip',
download: ''
download: '',
},
{
name: 'postgresql-10.13-1-osx-binaries.zip',
@@ -50,7 +50,7 @@ module.exports = async function () {
os: 'macos',
arch: 'amd64',
ext: 'zip',
download: ''
download: '',
},
{
name: 'postgresql-11.8-1-osx-binaries.zip',
@@ -61,7 +61,7 @@ module.exports = async function () {
os: 'macos',
arch: 'amd64',
ext: 'zip',
download: ''
download: '',
},
{
name: 'postgresql-12.3-1-osx-binaries.zip',
@@ -72,8 +72,8 @@ module.exports = async function () {
os: 'macos',
arch: 'amd64',
ext: 'zip',
download: ''
}
download: '',
},
].map(function (rel) {
rel.download =
'https://get.enterprisedb.com/postgresql/' +
@@ -81,7 +81,7 @@ module.exports = async function () {
'?ls=Crossover&type=Crossover';
return rel;
}),
download: ''
download: '',
};
};

View File

@@ -5,7 +5,7 @@ set -u
__redirect_alias_postgres() {
echo "'postgresql' is an alias for 'postgres'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/postgres@${WEBI_VERSION:-}" | sh
curl -fsSL "$WEBI_HOST/postgres@${WEBI_VERSION-}" | sh
}
__redirect_alias_postgres

View File

@@ -13,11 +13,13 @@ etc).
These are the files / directories that are created and/or modified with this
install:
```txt
```text
~/.config/envman/PATH.env
~/.local/opt/node
~/.local/opt/node/bin/prettier
```
If [`node`](/node) is not found, it will also be installed.
## Cheat Sheet
> The core value of Prettier is not in what it gives, but in what it takes away:

View File

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

View File

@@ -71,7 +71,7 @@ pyenv global system
pyenv install --list
```
```txt
```text
3.10.7
activepython-3.6.0
anaconda3-2020.11

View File

@@ -35,7 +35,7 @@ sudo apt install -y libreadline-dev libbz2-dev libsqlite3-dev
These are the files / directories that are created and/or modified with this
install:
```txt
```text
~/.bashrc (or your shell's equivalent)
~/.config/envman/PATH.env
~/.pyenv

View File

@@ -35,7 +35,7 @@ sudo apt install -y libreadline-dev libbz2-dev libsqlite3-dev
These are the files / directories that are created and/or modified with this
install:
```txt
```text
~/.bashrc (or your shell's equivalent)
~/.config/envman/PATH.env
~/.pyenv

View File

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

View File

@@ -7,6 +7,15 @@ tagline: |
To update or switch versions, run `webi rg@stable` (or `@v13.0`, `@beta`, etc).
### Files
```text
~/.config/envman/PATH.env
~/.local/opt/rg/
~/.local/bin/rg
~/.ripgreprc
```
## Cheat Sheet
> Ripgrep (`rg`) is smart. It's like grep if grep were built for code. It

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