-import {resource, template, task} from '../../src/Fig';
+import {resource, template, task} from '../../src/Fig/index.js';
task('configure (global) LaunchDaemons', async () => {
const items = [
import {promises as fs} from 'fs';
import {join} from 'path';
-import {resource, task, template} from '../../src/Fig';
-import Context from '../../src/Fig/Context';
-import tempdir from '../../src/fs/tempdir';
+import {resource, task, template} from '../../src/Fig/index.js';
+import Context from '../../src/Fig/Context.js';
+import tempdir from '../../src/fs/tempdir.js';
// TODO: decide whether these should be tests... maybe they should be?
task('template a file', async () => {
-import {command, file, resource, task, variable} from '../../src/Fig';
+import {command, file, resource, task, variable} from '../../src/Fig/index.js';
task('create target directory', async () => {
await file({
exit 1
fi
-if ! "$N_EXE" which lts &> /dev/null; then
- log_info "Installing Installing Node LTS version"
- "$N_EXE" lts
+if ! "$N_EXE" which latest &> /dev/null; then
+ log_info "Installing Node latest version"
+ "$N_EXE" latest
else
- log_debug "Using Node LTS installation"
+ log_debug "Using Node latest installation"
fi
"$N_EXE" "$@"
source "$REPO_ROOT/bin/common"
-n run lts "$@"
+n run latest "$@"
YARN_EXE="$REPO_ROOT/vendor/yarn-v1.22.4/bin/yarn"
-n exec lts "$YARN_EXE" "$@"
+n exec latest "$YARN_EXE" "$@"
"format:check": "npx prettier --check \"**/*.{js,json,ts}\" \"*.md\" roles/dotfiles/files/.zsh/liferay/bin/portool",
"format": "npx prettier --write \"**/*.{js,json,ts}\" \"*.md\" roles/dotfiles/files/.zsh/liferay/bin/portool"
},
+ "type": "module",
"dependencies": {
"typescript": "3.8.3"
},
import * as os from 'os';
-import stringify from './stringify';
+import stringify from './stringify.js';
/**
* Immutable system attributes (read-only).
import {promises as fs} from 'fs';
-import {compile, fill} from './template';
+import {compile, fill} from './template.js';
-import type {Scope} from './template';
+import type {Scope} from './template.js';
/**
* Template compiler that manages a cache of compiled templates.
import * as assert from 'assert';
-import Attributes from '../Attributes';
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import prompt from '../prompt';
-import * as status from './status';
-import Compiler from '../Compiler';
-import TaskRegistry from './TaskRegistry';
+import Attributes from '../Attributes.js';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import prompt from '../prompt.js';
+import * as status from './status.js';
+import Compiler from '../Compiler.js';
+import TaskRegistry from './TaskRegistry.js';
-import type {Metadata} from '../ErrorWithMetadata';
-import type {Aspect} from '../types/Project';
+import type {Metadata} from '../ErrorWithMetadata.js';
+import type {Aspect} from '../types/Project.js';
type Counts = {
changed: number;
}
get currentAspect(): Aspect {
- assert(this.#currentAspect);
+ assert.ok(this.#currentAspect);
return this.#currentAspect!;
}
}
get currentVariables(): Variables {
- assert(this.#currentVariables);
+ assert.ok(this.#currentVariables);
return this.#currentVariables!;
}
-import type {Aspect} from '../types/Project';
+import type {Aspect} from '../types/Project.js';
type Callback = () => Promise<void>;
import {join} from 'path';
-import {describe, expect, test} from '../../test/harness';
-import compare from '../compare';
-import root from '../root';
+import {describe, expect, test} from '../../test/harness.js';
+import compare from '../compare.js';
+import root from '../root.js';
/**
* Helper to get fixtures (in "src/") irrespective of where we run from.
import {promises as fs} from 'fs';
import {dirname} from 'path';
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import stat from '../fs/stat';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import stat from '../fs/stat.js';
// TODO: decide whether the Ansible definition of "force" (which we use below)
// is the one that we want to actual stick with.
-import escapeRegExpPattern from '../escapeRegExpPattern';
+import escapeRegExpPattern from '../escapeRegExpPattern.js';
+
/**
* Just supports simple globs ("*") for now.
*/
-import {default as command} from './operations/command';
-import {default as file} from './operations/file';
-import * as resource from './resource';
-import {default as root} from './root';
-import {default as task} from './task';
-import {default as template} from './operations/template';
-import {default as variable} from './variable';
+import {default as command} from './operations/command.js';
+import {default as file} from './operations/file.js';
+import * as resource from './resource.js';
+import {default as root} from './root.js';
+import {default as task} from './task.js';
+import {default as template} from './operations/template.js';
+import {default as variable} from './variable.js';
export {command};
export {file};
-import ErrorWithMetadata from '../../ErrorWithMetadata';
-import expand from '../../path/expand';
-import spawn from '../../spawn';
-import Context from '../Context';
+import ErrorWithMetadata from '../../ErrorWithMetadata.js';
+import expand from '../../path/expand.js';
+import spawn from '../../spawn.js';
+import Context from '../Context.js';
/**
* Implements basic shell expansion (of ~).
-import ErrorWithMetadata from '../../ErrorWithMetadata';
-import {log} from '../../console';
-import chown from '../../fs/chown';
-import cp from '../../fs/cp';
-import mkdir from '../../fs/mkdir';
-import tempfile from '../../fs/tempfile';
-import expand from '../../path/expand';
-import Context from '../Context';
-import compare from '../compare';
+import ErrorWithMetadata from '../../ErrorWithMetadata.js';
+import {log} from '../../console/index.js';
+import chown from '../../fs/chown.js';
+import cp from '../../fs/cp.js';
+import mkdir from '../../fs/mkdir.js';
+import tempfile from '../../fs/tempfile.js';
+import expand from '../../path/expand.js';
+import Context from '../Context.js';
+import compare from '../compare.js';
export default async function file({
contents,
-import Context from '../Context';
-import file from './file';
+import Context from '../Context.js';
+import file from './file.js';
export default async function template({
force,
import * as fs from 'fs';
import {join} from 'path';
-import Context from './Context';
-import globToRegExp from './globToRegExp';
+import Context from './Context.js';
+import globToRegExp from './globToRegExp.js';
// TODO: think about exporting these separately
import {dirname, join} from 'path';
import {existsSync} from 'fs';
+import {fileURLToPath} from 'url';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
/**
* Determine repo root directory by walking up directory tree until we see the
-import {log} from '../console';
+import {log} from '../console/index.js';
// TODO: ansible also has: unreachable, rescued, ignored
// decide whether we need any of those.
import {relative, sep} from 'path';
+import * as url from 'url';
-import {assertAspect} from '../types/Project';
-import getCaller from '../getCaller';
-import Context from './Context';
-import {default as root} from './root';
+import {assertAspect} from '../types/Project.js';
+import getCaller from '../getCaller.js';
+import Context from './Context.js';
+import {default as root} from './root.js';
export default function task(name: string, callback: () => Promise<void>) {
const caller = getCaller();
- const ancestors = relative(root, caller).split(sep);
+ const path = url.fileURLToPath(caller);
+
+ const ancestors = relative(root, path).split(sep);
const aspect =
ancestors[0] === 'lib' && ancestors[1] === 'aspects' && ancestors[2];
-import assert from '../assert';
-import Context from './Context';
+import assert from '../assert.js';
+import Context from './Context.js';
export default function variable(
name: string,
-import {expect, test} from '../test/harness';
-import merge from '../merge';
+import {expect, test} from '../test/harness.js';
+import merge from '../merge.js';
test('merge() returns an single object', () => {
expect(merge({example: 'obj'})).toEqual({example: 'obj'});
-import {expect, test} from '../test/harness';
-import regExpFromString from '../regExpFromString';
+import {expect, test} from '../test/harness.js';
+import regExpFromString from '../regExpFromString.js';
test('regExpFromString() returns a RegExp', () => {
const regExp = regExpFromString('/\\bword\\b/');
-import {expect, test} from '../test/harness';
-import dedent from '../dedent';
-import stringify from '../stringify';
+import {expect, test} from '../test/harness.js';
+import dedent from '../dedent.js';
+import stringify from '../stringify.js';
test('stringify() null', () => {
expect(stringify(null)).toBe('null');
-import dedent from '../dedent';
-import {expect, test} from '../test/harness';
-import {compile, fill, tokenize} from '../template';
+import dedent from '../dedent.js';
+import {expect, test} from '../test/harness.js';
+import {compile, fill, tokenize} from '../template.js';
test('compile() compiles an empty template', () => {
expect(compile('')).toBe(dedent`
import {clearLine, cursorTo} from 'readline';
-import stringify from '../stringify';
-import COLORS from './colors';
+import stringify from '../stringify.js';
+import COLORS from './colors.js';
export {COLORS};
-import assert from '../../assert';
-import {expect, test} from '../../test/harness';
-import chmod from '../chmod';
-import stat from '../stat';
-import tempdir from '../tempdir';
-import tempfile from '../tempfile';
+import assert from '../../assert.js';
+import {expect, test} from '../../test/harness.js';
+import chmod from '../chmod.js';
+import stat from '../stat.js';
+import tempdir from '../tempdir.js';
+import tempfile from '../tempfile.js';
test('chmod() changes the mode of a file', async () => {
const path = await tempfile('chmod-test');
import {join} from 'path';
-import assert from '../../assert';
-import {expect, test} from '../../test/harness';
-import chmod from '../chmod';
-import rm from '../rm';
-import stat from '../stat';
-import tempdir from '../tempdir';
-import tempfile from '../tempfile';
-import touch from '../touch';
+import assert from '../../assert.js';
+import {expect, test} from '../../test/harness.js';
+import chmod from '../chmod.js';
+import rm from '../rm.js';
+import stat from '../stat.js';
+import tempdir from '../tempdir.js';
+import tempfile from '../tempfile.js';
+import touch from '../touch.js';
test('rm() removes a file', async () => {
const path = await tempfile('rm-test');
import {join} from 'path';
-import assert from '../../assert';
-import {expect, test} from '../../test/harness';
-import stat from '../stat';
-import tempdir from '../tempdir';
-import touch from '../touch';
+import assert from '../../assert.js';
+import {expect, test} from '../../test/harness.js';
+import stat from '../stat.js';
+import tempdir from '../tempdir.js';
+import touch from '../touch.js';
test('touch() creates a file', async () => {
const path = await tempdir('rm-test');
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import Context from '../Fig/Context';
-import {log} from '../console';
-import run from '../run';
-import stringify from '../stringify';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import Context from '../Fig/Context.js';
+import {log} from '../console/index.js';
+import run from '../run.js';
+import stringify from '../stringify.js';
type Options = {
sudo?: boolean;
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import Context from '../Fig/Context';
-import {log} from '../console';
-import run from '../run';
-import stringify from '../stringify';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import Context from '../Fig/Context.js';
+import {log} from '../console/index.js';
+import run from '../run.js';
+import stringify from '../stringify.js';
type Options = {
group?: string;
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import Context from '../Fig/Context';
-import {log} from '../console';
-import run from '../run';
-import stringify from '../stringify';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import Context from '../Fig/Context.js';
+import {log} from '../console/index.js';
+import run from '../run.js';
+import stringify from '../stringify.js';
type Options = {
sudo?: boolean;
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import Context from '../Fig/Context';
-import {log} from '../console';
-import run from '../run';
-import stringify from '../stringify';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import Context from '../Fig/Context.js';
+import {log} from '../console/index.js';
+import run from '../run.js';
+import stringify from '../stringify.js';
type Options = {
mode?: Mode;
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import Context from '../Fig/Context';
-import {log} from '../console';
-import run from '../run';
-import stringify from '../stringify';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import Context from '../Fig/Context.js';
+import {log} from '../console/index.js';
+import run from '../run.js';
+import stringify from '../stringify.js';
type Options = {
recurse?: boolean;
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import Context from '../Fig/Context';
-import run from '../run';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import Context from '../Fig/Context.js';
+import run from '../run.js';
type Stats = {
group: string;
import {promises as fs} from 'fs';
-import {log} from '../console';
-import tempname from '../tempname';
+import {log} from '../console/index.js';
+import tempname from '../tempname.js';
export default async function tempdir(prefix: string): Promise<string> {
const path = tempname(prefix);
import {promises as fs} from 'fs';
-import {log} from '../console';
-import tempname from '../tempname';
+import {log} from '../console/index.js';
+import tempname from '../tempname.js';
/**
* Writes the `contents` to a temporary file and returns the path to that file.
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import Context from '../Fig/Context';
-import {log} from '../console';
-import run from '../run';
-import stringify from '../stringify';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import Context from '../Fig/Context.js';
+import {log} from '../console/index.js';
+import run from '../run.js';
+import stringify from '../stringify.js';
type Options = {
sudo?: boolean;
import {promises as fs} from 'fs';
import * as path from 'path';
-import {root} from './Fig';
-import {COLORS, LOG_LEVEL, log} from './console';
-import dedent from './dedent';
-import ErrorWithMetadata from './ErrorWithMetadata';
-import escapeRegExpPattern from './escapeRegExpPattern';
-import readAspect from './readAspect';
-import stringify from './stringify';
-
-import {assertAspect} from './types/Project';
-
-import type {LogLevel} from './console';
-import type {Aspect} from './types/Project';
+import {root} from './Fig/index.js';
+import {COLORS, LOG_LEVEL, log} from './console/index.js';
+import dedent from './dedent.js';
+import ErrorWithMetadata from './ErrorWithMetadata.js';
+import escapeRegExpPattern from './escapeRegExpPattern.js';
+import readAspect from './readAspect.js';
+import stringify from './stringify.js';
+
+import {assertAspect} from './types/Project.js';
+
+import type {LogLevel} from './console/index.js';
+import type {Aspect} from './types/Project.js';
type Options = {
focused: Set<Aspect>;
import * as os from 'os';
import * as path from 'path';
-import ErrorWithMetadata from './ErrorWithMetadata';
-import Context from './Fig/Context';
-import {root} from './Fig';
-import {debug, log, setLogLevel} from './console';
-import getOptions from './getOptions';
-import merge from './merge';
-import simplify from './path/simplify';
-import prompt from './prompt';
-import readAspect from './readAspect';
-import readProject from './readProject';
-import regExpFromString from './regExpFromString';
-import stringify from './stringify';
-import test from './test';
-
-import type {Aspect} from './types/Project';
+import ErrorWithMetadata from './ErrorWithMetadata.js';
+import Context from './Fig/Context.js';
+import {root} from './Fig/index.js';
+import {debug, log, setLogLevel} from './console/index.js';
+import getOptions from './getOptions.js';
+import merge from './merge.js';
+import simplify from './path/simplify.js';
+import prompt from './prompt.js';
+import readAspect from './readAspect.js';
+import readProject from './readProject.js';
+import regExpFromString from './regExpFromString.js';
+import stringify from './stringify.js';
+import test from './test/index.js';
+
+import type {Aspect} from './types/Project.js';
async function main() {
if (Context.attributes.uid === 0) {
async function loadAspect(aspect: Aspect): Promise<void> {
switch (aspect) {
case 'launchd':
- await import('../aspects/launchd');
+ await import('../aspects/launchd/index.js');
break;
case 'meta':
- await import('../aspects/meta');
+ await import('../aspects/meta/index.js');
break;
case 'terminfo':
- await import('../aspects/terminfo');
+ await import('../aspects/terminfo/index.js');
break;
default:
const unreachable: never = aspect;
import {promises as fs} from 'fs';
-import {log} from './console';
-import {Aspect, assertAspect} from './types/Aspect';
+import {log} from './console/index.js';
+import {Aspect, assertAspect} from './types/Aspect.js';
export default async function readAspect(path: string): Promise<Aspect> {
log.debug(`Reading aspect configuration: ${path}`);
import {promises as fs} from 'fs';
-import {log} from './console';
-import {Project, assertProject} from './types/Project';
+import {log} from './console/index.js';
+import {Project, assertProject} from './types/Project.js';
export default async function readProject(path: string): Promise<Project> {
log.debug(`Reading project configuration: ${path}`);
-import stringify from './stringify';
+import stringify from './stringify.js';
/**
* Loose definition of "valid" RegExp.
import * as child_process from 'child_process';
-import ErrorWithMetadata from './ErrorWithMetadata';
+import ErrorWithMetadata from './ErrorWithMetadata.js';
/**
* Fire-and-forget child process execution.
-import {LAQUO, RAQUO} from './Unicode';
+import {LAQUO, RAQUO} from './Unicode.js';
const CIRCULAR = `${LAQUO}circular${RAQUO}`;
-import stringify from './stringify';
+import stringify from './stringify.js';
export type Scope = {
[property: string]: JSONValue;
import * as assert from 'assert';
import {Writable} from 'stream';
-import ErrorWithMetadata from '../ErrorWithMetadata';
-import {RAQUO} from '../Unicode';
-import {COLORS, LOG_LEVEL, debug, getLogLevel, log, print} from '../console';
-import stringify from '../stringify';
+import ErrorWithMetadata from '../ErrorWithMetadata.js';
+import {RAQUO} from '../Unicode.js';
+import {
+ COLORS,
+ LOG_LEVEL,
+ debug,
+ getLogLevel,
+ log,
+ print,
+} from '../console/index.js';
+import stringify from '../stringify.js';
const {green, red, yellow} = COLORS;
toMatch(expected: unknown) {
if (expected instanceof RegExp) {
- assert(
+ assert.ok(
expected.test(String(value)),
`Expected ${stringify(value)} to match ${stringify(
expected
import {promises as fs} from 'fs';
import * as path from 'path';
+import * as url from 'url';
-import {log} from '../console';
-import {run} from './harness';
+import {log} from '../console/index.js';
+import {run} from './harness.js';
export default async function test() {
+ const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
+
for await (const file of walk(path.join(__dirname, '..'))) {
if (file.endsWith('-test.js')) {
try {
- require(file);
+ await import(file);
} catch (error) {
log.error(error);
}
return false;
}
- assert(isJSON(value));
+ assert.ok(isJSON(value));
}
-const assert = require('assert');
+import * as assert from 'assert';
-class Builder {
+export default class Builder {
constructor({tabWidth = 2} = {}) {
this.indentLevel = 0;
this.output = '';
dedent() {
this.indentLevel--;
- assert(this.indentLevel >= 0, 'Indent level must be non-negative');
+ assert.ok(this.indentLevel >= 0, 'Indent level must be non-negative');
return this;
}
return this;
}
}
-
-module.exports = Builder;
-const fs = require('fs');
-const path = require('path');
+import * as fs from 'fs';
+import * as path from 'path';
+import * as url from 'url';
const aspects = (() => {
+ const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
const directory = path.join(__dirname, '../../aspects');
const entries = fs.readdirSync(directory, {withFileTypes: true});
},
};
-const SCHEMAS = {
+export default {
Aspect: {
definitions: DEFINITIONS,
properties: {
type: 'object',
},
};
-
-module.exports = SCHEMAS;
-const assert = require('assert');
-const fs = require('fs');
-const path = require('path');
+import * as assert from 'assert';
+import * as fs from 'fs';
+import * as path from 'path';
+import * as url from 'url';
-const Builder = require('./Builder');
+import Builder from './Builder.js';
-const SCHEMAS = require('./SCHEMAS');
+import SCHEMAS from './SCHEMAS.js';
/**
* Generate types and runtime assertion functions for the types defined in
function main() {
for (const [typeName, typeSchema] of Object.entries(SCHEMAS)) {
// We only generate interfaces, which means we need objects.
- assert(typeSchema.type === 'object');
+ assert.ok(typeSchema.type === 'object');
const b = new Builder();
b.docblock('vim: set nomodifiable :', '', '@generated').blank();
// Don't know whether these will be needed yet, but add just in case.
- b.line(`import assert from '../assert';`)
- .line(`import {assertJSONValue} from './JSONValue';`)
+ b.line(`import assert from '../assert.js';`)
+ .line(`import {assertJSONValue} from './JSONValue.js';`)
.blank();
// Create types.
genAssertFunction(typeName, typeSchema, options);
+ const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
+
fs.writeFileSync(
path.join(__dirname, `../../src/types/${typeName}.ts`),
b.output
if (target) {
const definition = definitions[target];
- assert(definition);
+ assert.ok(definition);
if (definition.enum) {
b.line(
}
);
- assert(
+ assert.ok(
!patternProperties ||
Object.keys(patternProperties).length <= 1
);
}
function genPatternProperty(pattern, schema, options) {
- assert(pattern === '.*');
+ assert.ok(pattern === '.*');
const {builder: b, definitions} = options;
{
"compilerOptions": {
- "module": "CommonJS",
+ "module": "esnext",
+ "moduleResolution": "node",
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noUnusedLocals": true,