Skip to content

Commit

Permalink
Merge pull request #809 from CleverCloud/bundle-project-to-single-cjs
Browse files Browse the repository at this point in the history
Big rework (no lazy require, CJS => ESM sources, rollup to CJS build)
  • Loading branch information
hsablonniere authored Oct 16, 2024
2 parents 4bfdcb0 + e5196dd commit 0b9e4d9
Show file tree
Hide file tree
Showing 98 changed files with 2,031 additions and 2,415 deletions.
File renamed without changes.
575 changes: 154 additions & 421 deletions bin/clever.js

Large diffs are not rendered by default.

1,216 changes: 1,050 additions & 166 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "3.8.3",
"description": "Command Line Interface for Clever Cloud.",
"main": "bin/clever.js",
"type": "module",
"keywords": [
"clever-tools",
"cli",
Expand All @@ -25,8 +26,8 @@
"scripts/*.sh"
],
"dependencies": {
"@clevercloud/client": "8.3.0",
"cliparse": "0.4.0",
"@clevercloud/client": "9.0.0",
"cliparse": "0.5.0",
"colors": "1.4.0",
"common-env": "6.4.0",
"curlconverter": "3.21.0",
Expand All @@ -51,6 +52,9 @@
"devDependencies": {
"@commitlint/cli": "18.4.3",
"@commitlint/config-conventional": "18.4.3",
"@rollup/plugin-commonjs": "26.0.1",
"@rollup/plugin-json": "6.1.0",
"@rollup/plugin-node-resolve": "15.2.3",
"aws-sdk": "2.919.0",
"chai": "4.3.4",
"del": "6.0.0",
Expand All @@ -66,6 +70,7 @@
"grunt-cli": "1.4.3",
"grunt-http": "2.3.3",
"grunt-mocha-test": "0.13.3",
"magic-string": "0.30.11",
"mime-types": "2.1.35",
"mocha": "8.4.0",
"pkg": "5.8.1",
Expand All @@ -76,6 +81,7 @@
"pkg-fetch": "3.5.2"
},
"scripts": {
"build": "rollup -c rollup.config.js",
"pretest": "npm run lint",
"test": "grunt test",
"lint": "eslint bin src scripts",
Expand Down
76 changes: 76 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { defineConfig } from 'rollup';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import MagicString from 'magic-string';

export default defineConfig({
input: 'bin/clever.js',
output: {
file: 'build/clever.cjs',
format: 'cjs',
sourcemap: 'inline',
},
plugins: [
{
transform (code, id) {

// formidable (used by superagent) hijacks require :-(
if (id.includes('/node_modules/formidable/')) {
const ms = new MagicString(code);
ms.replaceAll(
'if (global.GENTLY) require = GENTLY.hijack(require);',
'',
);
return {
code: ms.toString(),
map: ms.generateMap(),
};
}

// for update notifier
if (id.includes('/node_modules/update-notifier/')) {
const ms = new MagicString(code);
ms
.replaceAll(
`const importLazy = require('import-lazy')(require);`,
'',
)
.replaceAll(
/const ([^ ]+) = importLazy\(\'([^']+)\'\);/g,
'const $1_ = require(\'$2\'); const $1 = () => $1_',
);

return {
code: ms.toString(),
map: ms.generateMap(),
};
}

// for ws peer deps
if (id.includes('/node_modules/ws/')) {
const ms = new MagicString(code);
ms
.replaceAll(
'require(\'bufferutil\')',
'null',
)
.replaceAll(
'require(\'utf-8-validate\')',
'{}',
);

return {
code: ms.toString(),
map: ms.generateMap(),
};
}
},
},
commonjs(),
nodeResolve({
preferBuiltins: true,
}),
json(),
],
});
25 changes: 7 additions & 18 deletions scripts/archive.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
const fs = require('fs-extra');
const path = require('path');
const cfg = require('./config.js');
const {
getArchiveFilepath,
getArchiveDirectory,
getBinaryFilepath, getArchiveLatestFilepath, getBinaryLatestFilepath,
} = require('./paths.js');
const {
generateChecksumFile,
startTask,
endTask,
exec,
cleanupDirectory,
assertFileExists,
} = require('./utils.js');

module.exports = async function build (version, latest) {
import fs from 'fs-extra';
import path from 'node:path';
import * as cfg from './config.js';
import { getArchiveFilepath, getArchiveDirectory, getBinaryFilepath, getArchiveLatestFilepath, getBinaryLatestFilepath } from './paths.js';
import { generateChecksumFile, startTask, endTask, exec, cleanupDirectory, assertFileExists } from './utils.js';

export async function archive (version, latest) {
await cleanupDirectory(getArchiveDirectory(version));

for (const arch of cfg.archList) {
Expand Down
33 changes: 18 additions & 15 deletions scripts/build.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
const { exec: pkg } = require('pkg');
const cfg = require('./config.js');
const {
getBinaryFilepath,
getBinaryDirectory,
} = require('./paths.js');
const {
startTask,
endTask,
cleanupDirectory,
} = require('./utils.js');
import { exec as pkg } from 'pkg';
import * as cfg from './config.js';
import { getBinaryFilepath, getBinaryDirectory, getWorkingDirectory } from './paths.js';
import { startTask, endTask, cleanupDirectory, exec } from './utils.js';

module.exports = async function build (version) {
export async function build (version) {
await cleanupDirectory(getBinaryDirectory(version));

const singleCjsScriptFilepath = getWorkingDirectory(version) + '/clever.cjs';

await bundleToSingleCjsScript(singleCjsScriptFilepath);

for (const arch of cfg.archList) {
const binaryFilepath = getBinaryFilepath(arch, version);
await buildBinary(arch, binaryFilepath);
await buildBinary(arch, singleCjsScriptFilepath, binaryFilepath);
}
};

// --- private

async function buildBinary (arch, binaryFilepath) {
async function bundleToSingleCjsScript (singleCjsScriptFilepath) {
startTask('Bundling project with rollup to single CJS script');
await exec(`npm run build -- -o ${singleCjsScriptFilepath}`);
endTask(`Bundling project with rollup to single CJS script to ${singleCjsScriptFilepath}`);
}

async function buildBinary (arch, sourceFilepath, binaryFilepath) {
const { nodeVersion } = cfg;
startTask(`Building binary for ${arch}`);
await pkg(['.', '-t', `node${nodeVersion}-${arch}`, '-o', binaryFilepath]);
await pkg([sourceFilepath, '-t', `node${nodeVersion}-${arch}`, '-o', binaryFilepath]);
endTask(`Building binary for ${arch} to ${binaryFilepath}`);
}
29 changes: 7 additions & 22 deletions scripts/bundle.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
const path = require('path');
const { readFile } = require('fs/promises');
const cfg = require('./config.js');
const {
startTask,
writeStringToFile,
applyTemplates,
exec,
endTask,
generateChecksumFile,
assertFileExists,
cleanupDirectory,
} = require('./utils.js');
const {
getBinaryFilepath,
getArchiveFilepath,
getShaFilepath,
getBundleDirectory,
getBundleFilepath,
} = require('./paths.js');

module.exports = async function bundle (version) {
import path from 'node:path';
import { readFile } from 'fs/promises';
import * as cfg from './config.js';
import { startTask, writeStringToFile, applyTemplates, exec, endTask, generateChecksumFile, assertFileExists, cleanupDirectory } from './utils.js';
import { getBinaryFilepath, getArchiveFilepath, getShaFilepath, getBundleDirectory, getBundleFilepath } from './paths.js';

export async function bundle (version) {
await cleanupDirectory(getBundleDirectory(version));

for (const arch of cfg.archList) {
Expand Down
14 changes: 5 additions & 9 deletions scripts/cellar-client.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const AWS = require('aws-sdk');
const fs = require('fs-extra');
const mime = require('mime-types');
const { getCellarConf } = require('./config.js');
import AWS from 'aws-sdk';
import fs from 'fs-extra';
import mime from 'mime-types';
import { getCellarConf } from './config.js';

// Forces the *.sha256 files to be uploaded with a text/plain mime type.
mime.types.sha256 = 'text/plain';

const CELLAR_CLIENTS = {};

function getCellarClient (scope) {
export function getCellarClient (scope) {
if (CELLAR_CLIENTS[scope] == null) {
const conf = getCellarConf(scope);
if (!conf.accessKeyId || !conf.secretAccessKey) {
Expand Down Expand Up @@ -85,7 +85,3 @@ function cellar ({ accessKeyId, secretAccessKey, host, bucket }) {

return client;
}

module.exports = {
getCellarClient,
};
50 changes: 18 additions & 32 deletions scripts/config.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
'use strict';
import os from 'node:os';
import { getPackageJson } from '../src/load-package-json.cjs';
const pkg = getPackageJson();

const os = require('os');
const pkgJson = require('../package.json');

const archList = ['linux', 'macos', 'win'];
const archEmoji = {
export const archList = ['linux', 'macos', 'win'];
export const archEmoji = {
linux: '🐧',
macos: '🍏',
win: '🪟',
};
const nodeVersion = pkgJson['pkg-node-version'];
const git = {
export const nodeVersion = pkg['pkg-node-version'];
export const git = {
email: '[email protected]',
name: 'Clever Cloud CI',
};
const appInfos = {
name: pkgJson.name,
export const appInfos = {
name: pkg.name,
vendor: 'Clever Cloud',
url: pkgJson.homepage,
description: pkgJson.description,
license: pkgJson.license,
url: pkg.homepage,
description: pkg.description,
license: pkg.license,
maintainer: `${git.name} <${git.email}>`,
keywords: pkgJson.keywords.join(' '),
keywords: pkg.keywords.join(' '),
};

function getNexusAuth () {
export function getNexusAuth () {
const user = process.env.NEXUS_USER || 'ci';
const password = process.env.NEXUS_PASSWORD;
const nugetApiKey = process.env.NUGET_API_KEY;
Expand All @@ -37,15 +36,15 @@ function getNexusAuth () {
return { user, password, nugetApiKey };
}

function getNpmToken () {
export function getNpmToken () {
const token = process.env.NPM_TOKEN;
if (!token) {
throw new Error('Could not read NPM token!');
}
return token;
}

function getDockerHubConf () {
export function getDockerHubConf () {
const username = process.env.DOCKERHUB_USERNAME;
const token = process.env.DOCKERHUB_TOKEN;
if (username == null || token == null) {
Expand All @@ -54,15 +53,15 @@ function getDockerHubConf () {
return { username, token, imageName: 'clevercloud/clever-tools' };
}

function getGpgConf () {
export function getGpgConf () {
const gpgPrivateKey = process.env.RPM_GPG_PRIVATE_KEY;
const gpgPath = process.env.RPM_GPG_PATH || os.homedir();
const gpgName = process.env.RPM_GPG_NAME;
const gpgPass = process.env.RPM_GPG_PASS;
return { gpgPrivateKey, gpgPath, gpgName, gpgPass };
}

function getCellarConf (scope) {
export function getCellarConf (scope) {
if (scope === 'previews') {
return {
host: 'cellar-c2.services.clever-cloud.com',
Expand All @@ -81,16 +80,3 @@ function getCellarConf (scope) {
}
throw new Error(`Unsupported cellar scope "${scope}". Supported scopes: "previews", "releases".`);
}

module.exports = {
archList,
archEmoji,
nodeVersion,
git,
appInfos,
getNexusAuth,
getNpmToken,
getDockerHubConf,
getGpgConf,
getCellarConf,
};
10 changes: 5 additions & 5 deletions scripts/job-build.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env node

const build = require('./build.js');
const archive = require('./archive.js');
const bundle = require('./bundle.js');
const { cleanupDirectory } = require('./utils.js');
const { getWorkingDirectory } = require('./paths.js');
import { build } from './build.js';
import { archive } from './archive.js';
import { bundle } from './bundle.js';
import { cleanupDirectory } from './utils.js';
import { getWorkingDirectory } from './paths.js';

async function run () {
const [versionArg, ...optionsArgs] = process.argv.slice(2);
Expand Down
Loading

0 comments on commit 0b9e4d9

Please sign in to comment.