Skip to content

Commit

Permalink
Meta tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Feb 26, 2024
1 parent 4b3b599 commit 587d6f6
Show file tree
Hide file tree
Showing 43 changed files with 393 additions and 375 deletions.
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"repository": "sindresorhus/np",
"funding": "https://github.com/sindresorhus/np?sponsor=1",
"type": "module",
"bin": "source/cli.js",
"bin": "./source/cli.js",
"engines": {
"node": ">=18",
"npm": ">=9",
Expand Down Expand Up @@ -44,7 +44,7 @@
"hosted-git-info": "^7.0.1",
"ignore-walk": "^6.0.3",
"import-local": "^3.1.0",
"inquirer": "^9.2.12",
"inquirer": "^9.2.15",
"is-installed-globally": "^1.0.0",
"is-interactive": "^2.0.0",
"is-scoped": "^3.0.0",
Expand All @@ -54,9 +54,9 @@
"log-symbols": "^6.0.0",
"meow": "^13.1.0",
"new-github-release-url": "^2.0.0",
"npm-name": "^7.1.1",
"npm-name": "^8.0.0",
"onetime": "^7.0.0",
"open": "^9.1.0",
"open": "^10.0.4",
"ow": "^1.1.1",
"p-memoize": "^7.1.1",
"p-timeout": "^6.1.2",
Expand All @@ -65,24 +65,24 @@
"read-package-up": "^11.0.0",
"read-pkg": "^9.0.1",
"rxjs": "^7.8.1",
"semver": "^7.5.4",
"semver": "^7.6.0",
"symbol-observable": "^4.0.0",
"terminal-link": "^3.0.0",
"update-notifier": "^7.0.0"
},
"devDependencies": {
"@sindresorhus/is": "^6.1.0",
"@types/semver": "^7.5.6",
"@types/semver": "^7.5.8",
"ava": "^5.3.1",
"common-tags": "^1.8.2",
"esmock": "^2.6.0",
"esmock": "^2.6.3",
"fs-extra": "^11.1.1",
"map-obj": "^5.0.2",
"sinon": "^17.0.1",
"strip-ansi": "^7.1.0",
"tempy": "^3.1.0",
"write-package": "^7.0.0",
"xo": "^0.56.0"
"write-package": "^7.0.1",
"xo": "^0.57.0"
},
"ava": {
"files": [
Expand Down
22 changes: 11 additions & 11 deletions source/cli-implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ updateNotifier({pkg: cli.pkg}).notify();
/** @typedef {Awaited<ReturnType<typeof getOptions>>['options']} Options */

export async function getOptions() {
const {pkg, rootDir} = await util.readPkg(cli.flags.contents);
const {package_, rootDirectory} = await util.readPackage(cli.flags.contents);

const localConfig = await config(rootDir);
const localConfig = await config(rootDirectory);
const flags = {
...localConfig,
...cli.flags,
Expand All @@ -121,19 +121,19 @@ export async function getOptions() {
}

if (flags.packageManager) {
pkg.packageManager = flags.packageManager;
package_.packageManager = flags.packageManager;
}

const runPublish = !flags.releaseDraftOnly && flags.publish && !pkg.private;
const runPublish = !flags.releaseDraftOnly && flags.publish && !package_.private;

// TODO: does this need to run if `runPublish` is false?
const availability = runPublish ? await npm.isPackageNameAvailable(pkg) : {
const availability = runPublish ? await npm.isPackageNameAvailable(package_) : {
isAvailable: false,
isUnknown: false,
};

// Use current (latest) version when 'releaseDraftOnly', otherwise try to use the first argument.
const version = flags.releaseDraftOnly ? pkg.version : cli.input.at(0);
const version = flags.releaseDraftOnly ? package_.version : cli.input.at(0);

const branch = flags.branch ?? await git.defaultBranch();

Expand All @@ -143,26 +143,26 @@ export async function getOptions() {
availability,
version,
branch,
}, {pkg, rootDir});
}, {package_, rootDirectory});

return {options, rootDir, pkg};
return {options, rootDirectory, package_};
}

try {
const {options, rootDir, pkg} = await getOptions();
const {options, rootDirectory, package_} = await getOptions();

if (!options.confirm) {
gracefulExit();
}

console.log(); // Prints a newline for readability
const newPkg = await np(options.version, options, {pkg, rootDir});
const newPackage = await np(options.version, options, {package_, rootDirectory});

if (options.preview || options.releaseDraftOnly) {
gracefulExit();
}

console.log(`\n ${newPkg.name} ${newPkg.version} published 🎉`);
console.log(`\n ${newPackage.name} ${newPackage.version} published 🎉`);
} catch (error) {
console.error(`\n${logSymbols.error} ${error?.stack ?? error}`);
gracefulExit(1);
Expand Down
8 changes: 4 additions & 4 deletions source/git-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const root = async () => {
return stdout;
};

export const newFilesSinceLastRelease = async rootDir => {
export const newFilesSinceLastRelease = async rootDirectory => {
try {
const {stdout} = await execa('git', ['diff', '--name-only', '--diff-filter=A', await latestTag(), 'HEAD']);
if (stdout.trim().length === 0) {
Expand All @@ -26,7 +26,7 @@ export const newFilesSinceLastRelease = async rootDir => {
} catch {
// Get all files under version control
return ignoreWalker({
path: rootDir,
path: rootDirectory,
ignoreFiles: ['.gitignore'],
});
}
Expand Down Expand Up @@ -234,8 +234,8 @@ export const commitLogFromRevision = async revision => {
return stdout;
};

const push = async (tagArg = '--follow-tags') => {
await execa('git', ['push', tagArg]);
const push = async (tagArgument = '--follow-tags') => {
await execa('git', ['push', tagArgument]);
};

export const pushGraceful = async remoteIsOnGitHub => {
Expand Down
78 changes: 42 additions & 36 deletions source/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import {execa} from 'execa';
import {deleteAsync} from 'del';
import Listr from 'listr';
import {merge, catchError, filter, finalize, from} from 'rxjs';
import {
merge,
catchError,
filter,
finalize,
from,
} from 'rxjs';
import hostedGitInfo from 'hosted-git-info';
import onetime from 'onetime';
import {asyncExitHook} from 'exit-hook';
import logSymbols from 'log-symbols';
import prerequisiteTasks from './prerequisite-tasks.js';
import gitTasks from './git-tasks.js';
import {getPackagePublishArguments} from './npm/publish.js';
import enable2fa, {getEnable2faArgs} from './npm/enable-2fa.js';
import enable2fa, {getEnable2faArguments} from './npm/enable-2fa.js';
import handleNpmError from './npm/handle-npm-error.js';
import releaseTaskHelper from './release-task-helper.js';
import {findLockfile, getPackageManagerConfig, printCommand} from './package-manager/index.js';
Expand All @@ -18,20 +24,20 @@ import * as git from './git-util.js';
import * as npm from './npm/util.js';

/** @type {(cmd: string, args: string[], options?: import('execa').Options) => any} */
const exec = (cmd, args, options) => {
const exec = (command, arguments_, options) => {
// Use `Observable` support if merged https://github.com/sindresorhus/execa/pull/26
const cp = execa(cmd, args, options);
const subProcess = execa(command, arguments_, options);

return merge(cp.stdout, cp.stderr, cp).pipe(filter(Boolean));
return merge(subProcess.stdout, subProcess.stderr, subProcess).pipe(filter(Boolean));
};

/**
@param {string} input
@param {import('./cli-implementation.js').Options} options
@param {{pkg: import('read-pkg').NormalizedPackageJson; rootDir: string}} context
@param {{package_: import('read-pkg').NormalizedPackageJson; rootDirectory: string}} context
*/
const np = async (input = 'patch', options, {pkg, rootDir}) => {
const pkgManager = getPackageManagerConfig(rootDir, pkg);
const np = async (input = 'patch', options, {package_, rootDirectory}) => {
const packageManager = getPackageManagerConfig(rootDirectory, package_);

// TODO: Remove sometime far in the future
if (options.skipCleanup) {
Expand All @@ -40,13 +46,13 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => {

const runTests = options.tests && !options.yolo;
const runCleanup = options.cleanup && !options.yolo;
const lockfile = findLockfile(rootDir, pkgManager);
const lockfile = findLockfile(rootDirectory, packageManager);
const isOnGitHub = options.repoUrl && hostedGitInfo.fromUrl(options.repoUrl)?.type === 'github';
const testScript = options.testScript || 'test';

if (options.releaseDraftOnly) {
await releaseTaskHelper(options, pkg, pkgManager);
return pkg;
await releaseTaskHelper(options, package_, packageManager);
return package_;
}

let publishStatus = 'UNKNOWN';
Expand All @@ -55,19 +61,19 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => {
const rollback = onetime(async () => {
console.log('\nPublish failed. Rolling back to the previous state…');

const tagVersionPrefix = await util.getTagVersionPrefix(pkgManager);
const tagVersionPrefix = await util.getTagVersionPrefix(packageManager);

const latestTag = await git.latestTag();
const versionInLatestTag = latestTag.slice(tagVersionPrefix.length);

async function getPkgVersion() {
const pkg = await util.readPkg(rootDir);
return pkg.version;
async function getPackageVersion() {
const package_ = await util.readPackage(rootDirectory);
return package_.version;
}

try {
// Verify that the package's version has been bumped before deleting the last tag and commit.
if (versionInLatestTag === await getPkgVersion() && versionInLatestTag !== pkg.version) {
if (versionInLatestTag === await getPackageVersion() && versionInLatestTag !== package_.version) {
await git.deleteTag(latestTag);
await git.removeLastCommit();
}
Expand All @@ -90,23 +96,23 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => {
}
}, {wait: 2000});

const shouldEnable2FA = options['2fa'] && options.availability.isAvailable && !options.availability.isUnknown && !pkg.private && !npm.isExternalRegistry(pkg);
const shouldEnable2FA = options['2fa'] && options.availability.isAvailable && !options.availability.isUnknown && !package_.private && !npm.isExternalRegistry(package_);

// To prevent the process from hanging due to watch mode (e.g. when running `vitest`)
const ciEnvOptions = {env: {CI: 'true'}};

/** @param {typeof options} _options */
function getPublishCommand(_options) {
const publishCommand = pkgManager.publishCommand || (args => [pkgManager.cli, args]);
const args = getPackagePublishArguments(_options);
return publishCommand(args);
const publishCommand = packageManager.publishCommand || (arguments_ => [packageManager.cli, arguments_]);
const arguments_ = getPackagePublishArguments(_options);
return publishCommand(arguments_);
}

const tasks = new Listr([
{
title: 'Prerequisite check',
enabled: () => options.runPublish,
task: () => prerequisiteTasks(input, pkg, options, pkgManager),
task: () => prerequisiteTasks(input, package_, options, packageManager),
},
{
title: 'Git',
Expand All @@ -118,13 +124,13 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => {
task: () => deleteAsync('node_modules'),
},
{
title: `Installing dependencies using ${pkgManager.id}`,
title: `Installing dependencies using ${packageManager.id}`,
enabled: () => runCleanup,
task: () => new Listr([
{
title: 'Running install command',
task() {
const installCommand = lockfile ? pkgManager.installCommand : pkgManager.installCommandNoLockfile;
const installCommand = lockfile ? packageManager.installCommand : packageManager.installCommandNoLockfile;
return exec(...installCommand);
},
},
Expand All @@ -137,29 +143,29 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => {
{
title: 'Running tests',
enabled: () => runTests,
task: () => exec(pkgManager.cli, ['run', testScript], ciEnvOptions),
task: () => exec(packageManager.cli, ['run', testScript], ciEnvOptions),
},
{
title: 'Bumping version',
skip() {
if (options.preview) {
const [cli, args] = pkgManager.versionCommand(input);
const [cli, arguments_] = packageManager.versionCommand(input);

if (options.message) {
args.push('--message', options.message.replaceAll('%s', input));
arguments_.push('--message', options.message.replaceAll('%s', input));
}

return `[Preview] Command not executed: ${printCommand([cli, args])}`;
return `[Preview] Command not executed: ${printCommand([cli, arguments_])}`;
}
},
task() {
const [cli, args] = pkgManager.versionCommand(input);
const [cli, arguments_] = packageManager.versionCommand(input);

if (options.message) {
args.push('--message', options.message);
arguments_.push('--message', options.message);
}

return exec(cli, args);
return exec(cli, arguments_);
},
},
...options.runPublish ? [
Expand Down Expand Up @@ -199,11 +205,11 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => {
title: 'Enabling two-factor authentication',
async skip() {
if (options.preview) {
const args = await getEnable2faArgs(pkg.name, options);
return `[Preview] Command not executed: npm ${args.join(' ')}.`;
const arguments_ = await getEnable2faArguments(package_.name, options);
return `[Preview] Command not executed: npm ${arguments_.join(' ')}.`;
}
},
task: (context, task) => enable2fa(task, pkg.name, {otp: context.otp}),
task: (context, task) => enable2fa(task, package_.name, {otp: context.otp}),
}] : [],
] : [],
{
Expand Down Expand Up @@ -234,7 +240,7 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => {
}
},
// TODO: parse version outside of index
task: () => releaseTaskHelper(options, pkg, pkgManager),
task: () => releaseTaskHelper(options, package_, packageManager),
}] : [],
], {
showSubtasks: false,
Expand All @@ -251,8 +257,8 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => {
console.error(`\n${logSymbols.error} ${pushedObjects.reason}`);
}

const {pkg: newPkg} = await util.readPkg();
return newPkg;
const {package_: newPackage} = await util.readPackage();
return newPackage;
};

export default np;
10 changes: 5 additions & 5 deletions source/npm/enable-2fa.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ import Version from '../version.js';
import handleNpmError from './handle-npm-error.js';
import {version as npmVersionCheck} from './util.js';

export const getEnable2faArgs = async (packageName, options) => {
export const getEnable2faArguments = async (packageName, options) => {
const npmVersion = await npmVersionCheck();
const args = new Version(npmVersion).satisfies('>=9.0.0')
const arguments_ = new Version(npmVersion).satisfies('>=9.0.0')
? ['access', 'set', 'mfa=publish', packageName]
: ['access', '2fa-required', packageName];

if (options && options.otp) {
args.push('--otp', options.otp);
arguments_.push('--otp', options.otp);
}

return args;
return arguments_;
};

const enable2fa = (packageName, options) => execa('npm', getEnable2faArgs(packageName, options));
const enable2fa = (packageName, options) => execa('npm', getEnable2faArguments(packageName, options));

const tryEnable2fa = (task, packageName, options) => {
from(enable2fa(packageName, options)).pipe(
Expand Down
Loading

0 comments on commit 587d6f6

Please sign in to comment.