-import {
- attributes,
- command,
- fail,
- skip,
- task as defineTask,
- variable,
-} from 'fig';
+import {command, fail, helpers, skip, variable} from 'fig';
-function task(name: string, callback: () => Promise<void>) {
- defineTask(name, async () => {
- if (attributes.distribution === 'debian') {
- await callback();
- } else {
- skip('not on Debian');
- }
- });
-}
+const {debian} = helpers;
-task('install packages', async () => {
+debian.task('install packages', async () => {
for (const pkg of variable.strings('packages')) {
const result = await command(
'dpkg-query',
-import {
- attributes,
- command,
- file,
- handler,
- resource,
- skip,
- task as defineTask,
- variable,
-} from 'fig';
+import {command, file, handler, helpers, resource, skip, variable} from 'fig';
import {join} from 'path';
-// TODO: DRY this up; it is in three files now
-function task(name: string, callback: () => Promise<void>) {
- defineTask(name, async () => {
- if (attributes.distribution === 'arch') {
- await callback();
- } else {
- skip('not on Arch Linux');
- }
- });
-}
+const {arch} = helpers;
-task('fetch yay', async () => {
+arch.task('fetch yay', async () => {
// TODO: make a `git` operation? (if I need to do this in more than one
// place; second place has arrived now, in the vim aspect.)
await command('git', ['clone', 'https://aur.archlinux.org/yay.git/'], {
});
});
-task('install yay', async () => {
+arch.task('install yay', async () => {
await command('makepkg', ['-si', '--noconfirm'], {
chdir: 'vendor/yay',
creates: '/usr/bin/yay',
});
});
-task('install packages', async () => {
+arch.task('install packages', async () => {
await command('yay', ['-S', '--noconfirm', ...variable.strings('packages')]);
});
-task('create ~/.config/systemd/user', async () => {
+arch.task('create ~/.config/systemd/user', async () => {
for (const directory of [
'~/.config',
'~/.config/systemd',
}
});
-task('install ~/.config/systemd/user/clipper.service', async () => {
+arch.task('install ~/.config/systemd/user/clipper.service', async () => {
await file({
notify: 'enable clipper.service',
path: '~/.config/systemd/user/clipper.service',
});
});
-task('set up sensors', async () => {
+arch.task('set up sensors', async () => {
for (const conf of [
'etc/modprobe.d/it87.conf',
'etc/modules-load.d/it87.conf',
}
});
-task('set Microsoft Edge as default browser', async () => {
+arch.task('set Microsoft Edge as default browser', async () => {
const result = await command('xdg-settings', [
'check',
'default-web-browser',
import {
- attributes,
backup,
command,
fail,
file,
+ helpers,
log,
path,
prompt,
variables,
} from 'fig';
+const {darwin} = helpers;
+
variables(({hostHandle, identity}) => {
return {
gitHostSpecificInclude: `.gitconfig.d/${hostHandle}`,
}
});
-task('install glow.yml', async () => {
+darwin.task('install glow.yml', async () => {
// On other platforms, Glow will read from ~/.config/glow/glow.yml.
- if (attributes.platform === 'darwin') {
- await file({
- path: '~/Library/Preferences/glow',
- state: 'directory',
- });
-
- await file({
- force: true,
- path: '~/Library/Preferences/glow/glow.yml',
- src: path.aspect.join('files/Library/Preferences/glow/glow.yml'),
- state: 'link',
- });
- }
+ await file({
+ path: '~/Library/Preferences/glow',
+ state: 'directory',
+ });
+
+ await file({
+ force: true,
+ path: '~/Library/Preferences/glow/glow.yml',
+ src: path.aspect.join('files/Library/Preferences/glow/glow.yml'),
+ state: 'link',
+ });
});
-import {
- attributes,
- command,
- file,
- handler,
- resource,
- skip,
- task as defineTask,
- template,
-} from 'fig';
+import {command, file, handler, helpers, resource, template} from 'fig';
-function task(name: string, callback: () => Promise<void>) {
- defineTask(name, async () => {
- if (attributes.distribution === 'arch') {
- await callback();
- } else {
- skip('not on Arch Linux');
- }
- });
-}
+const {arch} = helpers;
-task('build mac2linux', async () => {
+arch.task('build mac2linux', async () => {
const chdir = resource.support();
await command('cmake', ['--build', '.'], {chdir});
await command('make', [], {chdir});
});
-task('install mac2linux', async () => {
+arch.task('install mac2linux', async () => {
const chdir = resource.support();
await command('cmake', ['--install', '.', '--prefix', '/usr'], {
});
});
-task('create /etc/interception', async () => {
+arch.task('create /etc/interception', async () => {
await file({
path: '/etc/interception',
state: 'directory',
});
});
-task('create /etc/interception/dual-function-keys.yaml', async () => {
+arch.task('create /etc/interception/dual-function-keys.yaml', async () => {
await template({
notify: 'enable udevmon',
path: '/etc/interception/dual-function-keys.yaml',
});
});
-task('create /etc/interception/udevmon.yaml', async () => {
+arch.task('create /etc/interception/udevmon.yaml', async () => {
await template({
notify: 'enable udevmon',
path: '/etc/interception/udevmon.yaml',
// Interception Tools, but it _is_ related to the keyboard and udev, so we
// put it here. Depends on scripts installed by the dotfiles aspect, so the
// separation of concerns is unclear.
-task('create /etc/udev/rules.d/50-realforce-layout.rules', async () => {
+arch.task('create /etc/udev/rules.d/50-realforce-layout.rules', async () => {
await template({
notify: 'reload udevadm',
path: '/etc/udev/rules.d/50-realforce-layout.rules',
-import {attributes, command, file, path, skip, task} from 'fig';
+import {command, file, helpers, path, skip, task} from 'fig';
+
+const {darwin} = helpers;
const NODE_VERSION = '16.13.2';
await file({path: '~/n', state: 'directory'});
});
-task('hide ~/n', async () => {
- if (attributes.platform === 'darwin') {
- await command('chflags', ['hidden', '~/n']);
- }
+darwin.task('hide ~/n', async () => {
+ await command('chflags', ['hidden', '~/n']);
});
task(`install Node.js v${NODE_VERSION}`, async () => {
command,
fetch,
file,
+ helpers,
path,
resource,
skip,
variable,
} from 'fig';
-type Callback = Parameters<typeof task>[1];
-
-const debian = {
- task(description: string, callback: Callback) {
- task(description, async () => {
- if (attributes.distribution === 'debian') {
- await callback();
- } else {
- skip('not on Debian');
- }
- });
- },
-};
+const {debian} = helpers;
task('make directories', async () => {
// Some overlap with "dotfiles" aspect here.
command,
file,
handler,
+ helpers,
line,
path,
- skip,
- task as defineTask,
variable,
} from 'fig';
-function task(name: string, callback: () => Promise<void>) {
- defineTask(name, async () => {
- if (attributes.distribution === 'arch') {
- await callback();
- } else {
- skip('not on Arch Linux');
- }
- });
-}
+const {arch} = helpers;
-task('copy /etc/pacman.conf', async () => {
+arch.task('copy /etc/pacman.conf', async () => {
await file({
path: '/etc/pacman.conf',
src: path.aspect.join('files', 'etc/pacman.conf'),
});
});
-task('refresh package databases', async () => {
+arch.task('refresh package databases', async () => {
await command('pacman', ['-Syy'], {sudo: true});
});
-task('install packages', async () => {
+arch.task('install packages', async () => {
// TODO: make this check rather than running unconditionally?
await command(
'pacman',
);
});
-task('run updatedb', async () => {
+arch.task('run updatedb', async () => {
await command('updatedb', [], {sudo: true});
});
// Tweaks: should be moved into separate aspects.
-task('configure faillock.conf', async () => {
+arch.task('configure faillock.conf', async () => {
await line({
path: '/etc/security/faillock.conf',
regexp: /^\s*#?\s*deny\s*=/,
// TODO: `export N_PREFIX=~`
// TODO: run `n ??.??.??`
-task('create suspend hook', async () => {
+arch.task('create suspend hook', async () => {
await file({
notify: 'enable suspend hook',
path: '/etc/systemd/system/suspend@.service',
-import {
- attributes,
- command,
- file,
- handler,
- path,
- skip,
- task as defineTask,
- variable,
-} from 'fig';
+import {command, file, handler, helpers, path, skip, variable} from 'fig';
-// TODO: need to come up with a better pattern for arch-specific stuff
-function task(name: string, callback: () => Promise<void>) {
- defineTask(name, async () => {
- if (attributes.distribution === 'arch') {
- await callback();
- } else {
- skip('not on Arch Linux');
- }
- });
-}
+const {arch} = helpers;
-task('set up hostname', async () => {
+arch.task('set up hostname', async () => {
// Note that "hostname" is the variable configured in the aspect.json, which
// overwrites the "hostname" that comes in from the Attributes class (via
// Node's `os.hostname()`).
}
});
-task('create ~/.config/systemd/user', async () => {
+arch.task('create ~/.config/systemd/user', async () => {
// TODO: I am doing something similar with a `for` loop in the "aur" aspect;
// maybe I should add `recurse: true` support to the `file` DSL.
await file({path: '~/.config', state: 'directory'});
await file({path: '~/.config/systemd/user', state: 'directory'});
});
-task('set up ~/.config/systemd/user/pulseaudio-null-sink.service', async () => {
- const unit = '.config/systemd/user/pulseaudio-null-sink.service';
- await file({
- force: true,
- notify: ['systemd daemon-reload', 'enable pulseaudio-null-sink.service'],
- path: path.home.join(unit),
- src: path.aspect.join('files', unit),
- state: 'link',
- });
-});
+arch.task(
+ 'set up ~/.config/systemd/user/pulseaudio-null-sink.service',
+ async () => {
+ const unit = '.config/systemd/user/pulseaudio-null-sink.service';
+ await file({
+ force: true,
+ notify: ['systemd daemon-reload', 'enable pulseaudio-null-sink.service'],
+ path: path.home.join(unit),
+ src: path.aspect.join('files', unit),
+ state: 'link',
+ });
+ }
+);
-task('set up ~/.config/systemd/user/ssh-agent.service', async () => {
+arch.task('set up ~/.config/systemd/user/ssh-agent.service', async () => {
const unit = '.config/systemd/user/ssh-agent.service';
await file({
force: true,
import getCaller from '../getCaller.js';
import getAspectFromCaller from '../getAspectFromCaller.js';
-export default function task(name: string, callback: () => Promise<void>) {
- const caller = getCaller();
-
+export default function task(
+ name: string,
+ callback: () => Promise<void>,
+ caller: string = getCaller()
+) {
const aspect = getAspectFromCaller(caller);
Context.tasks.register(aspect, callback, `${aspect} | ${name}`);
export {log} from './console.js';
export {default as path} from './path.js';
export {default as prompt} from './prompt.js';
+
+// Re-export project-local helpers.
+
+export * as helpers from '../helpers.js';
--- /dev/null
+import {attributes, skip, task} from 'fig';
+import getCaller from 'fig/getCaller.js';
+
+type Callback = Parameters<typeof task>[1];
+
+/**
+ * @file
+ *
+ * Project-local helpers.
+ */
+
+export const arch = {
+ task(description: string, callback: Callback) {
+ task(
+ description,
+ async () => {
+ if (attributes.distribution === 'arch') {
+ await callback();
+ } else {
+ skip('not on Arch Linux');
+ }
+ },
+ getCaller()
+ );
+ },
+};
+
+export const darwin = {
+ task(description: string, callback: Callback) {
+ task(
+ description,
+ async () => {
+ if (attributes.platform === 'darwin') {
+ await callback();
+ } else {
+ skip('not on Darwin');
+ }
+ },
+ getCaller()
+ );
+ },
+};
+
+export const debian = {
+ task(description: string, callback: Callback) {
+ task(
+ description,
+ async () => {
+ if (attributes.distribution === 'debian') {
+ await callback();
+ } else {
+ skip('not on Debian');
+ }
+ },
+ getCaller()
+ );
+ },
+};
"target": "ES2019"
},
"exclude": ["aspects/interception/support/CMakeFiles/**", "node_modules"],
- "include": ["aspects/**/*.ts", "fig/**/*.ts", "variables.ts"]
+ "include": ["aspects/**/*.ts", "fig/**/*.ts", "helpers.ts", "variables.ts"]
}