mirror of
https://github.com/webinstall/webi-installers.git
synced 2026-06-03 22:42:48 +00:00
Compare commits
59 Commits
docs-caddy
...
beyond-she
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1750b92932 | ||
|
|
2a081b527b | ||
|
|
51c7c20c59 | ||
|
|
6025fb3b8e | ||
|
|
89c46b728b | ||
|
|
480a102f64 | ||
|
|
1b37080425 | ||
|
|
e5ffc8a931 | ||
|
|
af3658e240 | ||
|
|
a53fbe5f36 | ||
|
|
fea715f9bd | ||
|
|
30f9fd6271 | ||
|
|
3602972090 | ||
|
|
6cf153de8c | ||
|
|
410bb1c3e3 | ||
|
|
9f7ce9842c | ||
|
|
1984d10878 | ||
|
|
bbaeb0dd38 | ||
|
|
811d5c7d63 | ||
|
|
817e71a8f5 | ||
|
|
0024f69109 | ||
|
|
f84a4c5b69 | ||
|
|
b25da4cae8 | ||
|
|
a2b68dbca8 | ||
|
|
991592e88a | ||
|
|
0782aa6eb8 | ||
|
|
482027b880 | ||
|
|
4678e04654 | ||
|
|
a782c32d59 | ||
|
|
a1be2e4aa7 | ||
|
|
56cb856357 | ||
|
|
f73a284569 | ||
|
|
7f4f9afaaa | ||
|
|
9199531bf5 | ||
|
|
061f9b643e | ||
|
|
9feca1c7af | ||
|
|
e5685b9025 | ||
|
|
6c76ff728c | ||
|
|
f663bb7822 | ||
|
|
2bcc903f80 | ||
|
|
5b6b700943 | ||
|
|
b5fc4d742b | ||
|
|
5fc3d0e174 | ||
|
|
c26c67662b | ||
|
|
e2702eea08 | ||
|
|
c2f1882de5 | ||
|
|
90a919736b | ||
|
|
bab564bdeb | ||
|
|
21c668b4b7 | ||
|
|
2149eeb7f8 | ||
|
|
9c1be4bc3a | ||
|
|
967eff256a | ||
|
|
eddef3c24b | ||
|
|
4723810e2b | ||
|
|
40f37cb916 | ||
|
|
25b003996a | ||
|
|
22aa8ba596 | ||
|
|
2f618384cc | ||
|
|
75284b2a93 |
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"trailingComma": "none",
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"proseWrap": "always"
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
133
_common/github-source.js
Normal 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));
|
||||
});
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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?');
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
125
aliasman/README.md
Normal 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
41
aliasman/install.sh
Normal 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
28
aliasman/releases.js
Normal 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));
|
||||
});
|
||||
}
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
```
|
||||
|
||||
@@ -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
80
beyond-shell/README.md
Normal 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
339
beyond-shell/install.sh
Normal 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
|
||||
@@ -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
160
bun/README.md
Normal 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
39
bun/install.sh
Normal 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
32
bun/releases.js
Normal 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));
|
||||
});
|
||||
}
|
||||
@@ -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**
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
98
duckdns.sh/README.md
Normal 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
41
duckdns.sh/install.sh
Normal 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
28
duckdns.sh/releases.js
Normal 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
15
duckdns/README.md
Normal 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
11
duckdns/install.sh
Normal 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
|
||||
@@ -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',
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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$
|
||||
```
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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]
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
14
jq/README.md
14
jq/README.md
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
22
package-lock.json
generated
@@ -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=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
package.json
11
package.json
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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: '',
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -71,7 +71,7 @@ pyenv global system
|
||||
pyenv install --list
|
||||
```
|
||||
|
||||
```txt
|
||||
```text
|
||||
3.10.7
|
||||
activepython-3.6.0
|
||||
anaconda3-2020.11
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user