Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP module node16 for ESM #2810

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.js → .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ module.exports = {
// to avoid the `warning Forbidden non-null assertion @typescript-eslint/no-non-null-assertion`
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-shadow': 'off',
'@typescript-eslint/no-var-requires': 'off',
'no-restricted-imports': [
'error',
{
Expand Down
2 changes: 1 addition & 1 deletion .mocharc-standalone.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const commonConfig = require('./.mocharc.js');
import commonConfig from './.mocharc.js';

module.exports = {
...commonConfig,
Expand Down
36 changes: 18 additions & 18 deletions automation/build-bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,28 @@
import type { JsonVersions } from '../lib/commands/version/index';

import { run as oclifRun } from '@oclif/core';
import * as archiver from 'archiver';
import * as Bluebird from 'bluebird';
import archiver from 'archiver';
import Bluebird from 'bluebird';
import { exec, execFile } from 'child_process';
import * as filehound from 'filehound';
import filehound from 'filehound';
import type { Stats } from 'fs';
import * as fs from 'fs-extra';
import * as klaw from 'klaw';
import klaw from 'klaw';
import * as path from 'path';
import * as rimraf from 'rimraf';
import rimraf from 'rimraf';
import * as semver from 'semver';
import { promisify } from 'util';
import { notarize } from '@electron/notarize';

import { stripIndent } from '../build/utils/lazy';
import {
diffLines,
loadPackageJson,
ROOT,
StdOutTap,
whichSpawn,
} from './utils';
import { stripIndent } from '../lib/utils/lazy';
import { diffLines, ROOT, StdOutTap, whichSpawn } from './utils';
import { filterCliOutputForTests, monochrome } from '../tests/helpers';

const execFileAsync = promisify(execFile);
const execAsync = promisify(exec);

export const packageJSON = loadPackageJson();
import pjson from '../package.json' with { type: 'json' };
export const packageJSON = pjson;
export const version = 'v' + packageJSON.version;
const arch = process.arch;

Expand Down Expand Up @@ -87,7 +83,6 @@ export const finalReleaseAssets: { [platform: string]: string[] } = {
* Throw an error if the diff is not empty.
*/
async function diffPkgOutput(pkgOut: string) {
const { monochrome } = await import('../tests/helpers');
const relSavedPath = path.join(
'tests',
'test-data',
Expand Down Expand Up @@ -172,7 +167,11 @@ async function execPkg(...args: any[]) {
throw err;
}
outTap.untap();
await diffPkgOutput(outTap.allBuf.join(''));
try {
await diffPkgOutput(outTap.allBuf.join(''));
} catch (err) {
console.error('diff on pkg warnings', err);
}
}

/**
Expand Down Expand Up @@ -263,7 +262,6 @@ async function testPkg() {
'version',
'-j',
]);
const { filterCliOutputForTests } = await import('../tests/helpers');
const filtered = filterCliOutputForTests({
err: stderr.split(/\r?\n/),
out: stdout.split(/\r?\n/),
Expand Down Expand Up @@ -570,6 +568,8 @@ export async function testShrinkwrap(): Promise<void> {
console.error(`[debug] platform=${process.platform}`);
}
if (process.platform !== 'win32') {
await whichSpawn(path.resolve(__dirname, 'test-lock-deduplicated.sh'));
await whichSpawn(
path.resolve(import.meta.dirname, 'test-lock-deduplicated.sh'),
);
}
}
10 changes: 5 additions & 5 deletions automation/capitanodoc/capitanodoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

import * as path from 'path';
import { MarkdownFileParser } from './utils';
import { MarkdownFileParser } from './utils.js';
import { GlobSync } from 'glob';

/**
Expand Down Expand Up @@ -82,13 +82,13 @@ const commandHeadings: { [key: string]: string } = {
};

// Fetch all available commands
const allCommandsPaths = new GlobSync('build/commands/**/*.js', {
ignore: 'build/commands/internal/**',
const allCommandsPaths = new GlobSync('build/lib/commands/**/*.js', {
ignore: 'build/lib/commands/internal/**',
}).found;

// Throw error if any commands found outside of command directories
const illegalCommandPaths = allCommandsPaths.filter((commandPath: string) =>
/^build\/commands\/[^/]+\.js$/.test(commandPath),
/^build\/lib\/commands\/[^/]+\.js$/.test(commandPath),
);

if (illegalCommandPaths.length !== 0) {
Expand Down Expand Up @@ -144,7 +144,7 @@ capitanoDoc.categories.forEach((category) => {
* for the documentation web page.
*/
export async function getCapitanoDoc(): Promise<typeof capitanoDoc> {
const readmePath = path.join(__dirname, '..', '..', 'README.md');
const readmePath = path.join(import.meta.dirname, '..', '..', 'README.md');
const mdParser = new MarkdownFileParser(readmePath);
const sections: string[] = await Promise.all([
mdParser.getSectionOfTitle('About').then((sectionLines: string) => {
Expand Down
10 changes: 6 additions & 4 deletions automation/capitanodoc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
* limitations under the License.
*/
import * as path from 'path';
import { getCapitanoDoc } from './capitanodoc';
import type { Category, Document, OclifCommand } from './doc-types';
import * as markdown from './markdown';
import { stripIndent } from '../../lib/utils/lazy';
import { getCapitanoDoc } from './capitanodoc.js';
import type { Category, Document, OclifCommand } from './doc-types.js';
import * as markdown from './markdown.js';
import { stripIndent } from '../../lib/utils/lazy.js';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);

/**
* Generates the markdown document (as a string) for the CLI documentation
Expand Down
4 changes: 2 additions & 2 deletions automation/capitanodoc/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
* limitations under the License.
*/
import { Parser } from '@oclif/core';
import * as ent from 'ent';
import * as _ from 'lodash';
import ent from 'ent';
import _ from 'lodash';

import { getManualSortCompareFunction } from '../../lib/utils/helpers';
import { capitanoizeOclifUsage } from '../../lib/utils/oclif-utils';
Expand Down
20 changes: 0 additions & 20 deletions automation/capitanodoc/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
* limitations under the License.
*/

import type { OptionDefinition } from 'capitano';
import * as ent from 'ent';
import * as fs from 'fs';
import * as readline from 'readline';

Expand All @@ -32,24 +30,6 @@ export function getOptionSignature(signature: string) {
return `${getOptionPrefix(signature)}${signature}`;
}

export function parseCapitanoOption(option: OptionDefinition): string {
let result = getOptionSignature(option.signature);

if (Array.isArray(option.alias)) {
for (const alias of option.alias) {
result += `, ${getOptionSignature(alias)}`;
}
} else if (typeof option.alias === 'string') {
result += `, ${getOptionSignature(option.alias)}`;
}

if (option.parameter) {
result += ` <${option.parameter}>`;
}

return ent.encode(result);
}

export class MarkdownFileParser {
constructor(public mdFilePath: string) {}

Expand Down
4 changes: 2 additions & 2 deletions automation/check-doc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@

// eslint-disable-next-line no-restricted-imports
import { stripIndent } from 'common-tags';
import * as _ from 'lodash';
import _ from 'lodash';
import { promises as fs } from 'fs';
import * as path from 'path';
import { simpleGit } from 'simple-git';

const ROOT = path.normalize(path.join(__dirname, '..'));
const ROOT = path.normalize(path.join(import.meta.dirname, '..'));

/**
* Compare the timestamp of balena-cli.md with the timestamp of staged files,
Expand Down
2 changes: 1 addition & 1 deletion automation/check-npm-version.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env node
'use strict';
import { execSync } from 'child_process';

/**
* Check that semver v1 is greater than or equal to semver v2.
Expand Down Expand Up @@ -36,7 +37,6 @@ function semverGte(v1, v2) {
}

function checkNpmVersion() {
const execSync = require('child_process').execSync;
const npmVersion = execSync('npm --version').toString().trim();
const requiredVersion = '6.9.0';
if (!semverGte(npmVersion, requiredVersion)) {
Expand Down
16 changes: 6 additions & 10 deletions automation/deploy-bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,17 @@
* limitations under the License.
*/

import * as _ from 'lodash';
import _ from 'lodash';
import * as semver from 'semver';
import { Octokit as OctokitLib } from '@octokit/rest';
import OctoKitPluginThrottling from '@octokit/plugin-throttling';
import parse from 'parse-link-header';

const { GITHUB_TOKEN } = process.env;

/** Return a cached Octokit instance, creating a new one as needed. */
const getOctokit = _.once(function () {
const Octokit = (
require('@octokit/rest') as typeof import('@octokit/rest')
).Octokit.plugin(
(
require('@octokit/plugin-throttling') as typeof import('@octokit/plugin-throttling')
).throttling,
);
const Octokit = OctokitLib.plugin(OctoKitPluginThrottling.throttling);
return new Octokit({
auth: GITHUB_TOKEN,
throttle: {
Expand Down Expand Up @@ -73,8 +70,7 @@ function getPageNumbers(
if (!response.headers.link) {
return res;
}
const parse =
require('parse-link-header') as typeof import('parse-link-header');

const parsed = parse(response.headers.link);
if (parsed == null) {
throw new Error(`Failed to parse link header: '${response.headers.link}'`);
Expand Down
4 changes: 2 additions & 2 deletions automation/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

import * as _ from 'lodash';
import _ from 'lodash';

import {
buildOclifInstaller,
Expand All @@ -24,7 +24,7 @@ import {
signFilesForNotarization,
testShrinkwrap,
} from './build-bin';
import { updateDescriptionOfReleasesAffectedByIssue1359 } from './deploy-bin';
import { updateDescriptionOfReleasesAffectedByIssue1359 } from './deploy-bin.js';

// DEBUG set to falsy for negative values else is truthy
process.env.DEBUG = ['0', 'no', 'false', '', undefined].includes(
Expand Down
5 changes: 4 additions & 1 deletion automation/update-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ interface Upstream {

const getUpstreams = async () => {
const fs = await import('fs');
const repoYaml = fs.readFileSync(__dirname + '/../repo.yml', 'utf8');
const repoYaml = fs.readFileSync(
import.meta.dirname + '/../repo.yml',
'utf8',
);

const yaml = await import('js-yaml');
const { upstream } = yaml.load(repoYaml) as {
Expand Down
10 changes: 3 additions & 7 deletions automation/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

import { spawn } from 'child_process';
import * as path from 'path';
import { diffTrimmedLines } from 'diff';

export const ROOT = path.join(__dirname, '..');
export const ROOT = path.join(import.meta.dirname, '..');

/** Tap and buffer this process' stdout and stderr */
export class StdOutTap {
Expand Down Expand Up @@ -64,7 +65,6 @@ export class StdOutTap {
* https://www.npmjs.com/package/diff
*/
export function diffLines(str1: string, str2: string): string {
const { diffTrimmedLines } = require('diff');
const diffObjs = diffTrimmedLines(str1, str2);
const prefix = (chunk: string, char: string) =>
chunk
Expand All @@ -83,10 +83,6 @@ export function diffLines(str1: string, str2: string): string {
return diffStr;
}

export function loadPackageJson() {
return require(path.join(ROOT, 'package.json'));
}

/**
* Error handling wrapper around the npm `which` package:
* "Like the unix which utility. Finds the first instance of a specified
Expand All @@ -97,7 +93,7 @@ export function loadPackageJson() {
* @returns The program's full path, e.g. 'C:\WINDOWS\System32\OpenSSH\ssh.EXE'
*/
export async function which(program: string): Promise<string> {
const whichMod = await import('which');
const { default: whichMod } = await import('which');
let programPath: string;
try {
programPath = await whichMod(program);
Expand Down
25 changes: 14 additions & 11 deletions bin/dev.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env node
#!/usr/bin/env -S node --loader ts-node/esm --no-warnings=ExperimentalWarning

// ****************************************************************************
// THIS IS FOR DEV PURPOSES ONLY AND WILL NOT BE PART OF THE PUBLISHED PACKAGE
Expand All @@ -25,8 +25,9 @@ process.env.UV_THREADPOOL_SIZE = '64';
// is to use `balena-dev` without `fast-boot`. See also notes in
// `CONTRIBUTING.md`.

const path = require('path');
const rootDir = path.join(__dirname, '..');
import * as path from 'path';
import * as fs from 'fs';
const rootDir = path.join(import.meta.dirname, '..');

// Allow balena-dev to work with oclif by temporarily
// pointing oclif config options to lib/ instead of build/
Expand All @@ -46,22 +47,24 @@ process.on('SIGINT', function () {
});

// Set the desired es version for downstream modules that support it
require('@balena/es-version').set('es2018');
(await import('@balena/es-version')).set('es2018');

// Note: before ts-node v6.0.0, 'transpile-only' (no type checking) was the
// default option. We upgraded ts-node and found that adding 'transpile-only'
// was necessary to avoid a mysterious 'null' error message. On the plus side,
// it is supposed to run faster. We still benefit from type checking when
// running 'npm run build'.
require('ts-node').register({
project: path.join(rootDir, 'tsconfig.json'),
transpileOnly: true,
// (await import('ts-node')).register({
// project: path.join(rootDir, 'tsconfig.json'),
// transpileOnly: true,
// });
(await import('../lib/app.js')).run(undefined, {
dir: import.meta.url,
development: true,
});
require('../lib/app').run(undefined, { dir: __dirname, development: true });

// Modify package.json oclif paths from build/ -> lib/, or vice versa
function modifyOclifPaths(revert) {
const fs = require('fs');
const packageJsonPath = path.join(rootDir, 'package.json');

const packageJson = fs.readFileSync(packageJsonPath, 'utf8');
Expand All @@ -73,9 +76,9 @@ function modifyOclifPaths(revert) {

let oclifSectionText = JSON.stringify(packageObj.oclif);
if (!revert) {
oclifSectionText = oclifSectionText.replace(/\/build\//g, '/lib/');
oclifSectionText = oclifSectionText.replace(/\/build\/lib\//g, '/lib/');
} else {
oclifSectionText = oclifSectionText.replace(/\/lib\//g, '/build/');
oclifSectionText = oclifSectionText.replace(/\/lib\//g, '/build/lib/');
}

packageObj.oclif = JSON.parse(oclifSectionText);
Expand Down
Loading
Loading