Skip to content

Commit

Permalink
[ci] format
Browse files Browse the repository at this point in the history
  • Loading branch information
natemoo-re authored and astrobot-houston committed Nov 27, 2023
1 parent 5a38750 commit e7ce779
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 112 deletions.
4 changes: 2 additions & 2 deletions packages/upgrade/src/actions/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export async function getContext(argv: string[]): Promise<Context> {
'-h': '--help',
},
{ argv, permissive: true }
)
);

const packageManager = detectPackageManager()?.name ?? 'npm';
const { _: [version = 'latest'] = [], '--help': help = false, '--dry-run': dryRun } = flags;
Expand All @@ -52,5 +52,5 @@ export async function getContext(argv: string[]): Promise<Context> {
exit(code) {
process.exit(code);
},
} satisfies Context
} satisfies Context;
}
2 changes: 1 addition & 1 deletion packages/upgrade/src/actions/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export function help() {
tables: {
Flags: [
['--help (-h)', 'See all available flags.'],
['--dry-run', 'Walk through steps without executing.']
['--dry-run', 'Walk through steps without executing.'],
],
},
});
Expand Down
97 changes: 73 additions & 24 deletions packages/upgrade/src/actions/install.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,82 @@
import type { Context, PackageInfo } from './context.js';

import { color, say } from '@astrojs/cli-kit';
import { random, sleep } from '@astrojs/cli-kit/utils';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { color, say } from '@astrojs/cli-kit';
import { pluralize, celebrations, done, error, info, log, spinner, success, upgrade, banner, title, changelog, warn, bye, newline } from '../messages.js';
import {
banner,
bye,
celebrations,
changelog,
done,
error,
info,
newline,
pluralize,
spinner,
success,
title,
upgrade,
warn,
} from '../messages.js';
import { shell } from '../shell.js';
import { random, sleep } from '@astrojs/cli-kit/utils';
import { satisfies } from 'semver';

export async function install(
ctx: Pick<Context, 'version' | 'packages' | 'packageManager' | 'prompt' | 'dryRun' | 'exit' | 'cwd'>
ctx: Pick<
Context,
'version' | 'packages' | 'packageManager' | 'prompt' | 'dryRun' | 'exit' | 'cwd'
>
) {
await banner();
newline();
const { current, dependencies, devDependencies } = filterPackages(ctx);
const toInstall = [...dependencies, ...devDependencies].sort(sortPackages);
for (const packageInfo of current.sort(sortPackages)) {
const tag = /^\d/.test(packageInfo.targetVersion) ? packageInfo.targetVersion : packageInfo.targetVersion.slice(1)
await info(`${packageInfo.name}`, `is up to date on`, `v${tag}`)
const tag = /^\d/.test(packageInfo.targetVersion)
? packageInfo.targetVersion
: packageInfo.targetVersion.slice(1);
await info(`${packageInfo.name}`, `is up to date on`, `v${tag}`);
await sleep(random(50, 150));
}
if (toInstall.length === 0 && !ctx.dryRun) {
newline()
newline();
await success(random(celebrations), random(done));
return;
}
const majors: PackageInfo[] = []
const majors: PackageInfo[] = [];
for (const packageInfo of toInstall) {
const word = ctx.dryRun ? 'can' : 'will';
await upgrade(packageInfo, `${word} be updated to`)
await upgrade(packageInfo, `${word} be updated to`);
if (packageInfo.isMajor) {
majors.push(packageInfo)
majors.push(packageInfo);
}
}
if (majors.length > 0) {
const { proceed } = await ctx.prompt({
name: 'proceed',
type: 'confirm',
label: title('wait'),
message: `${pluralize(['One package has', 'Some packages have'], majors.length)} breaking changes. Continue?`,
message: `${pluralize(
['One package has', 'Some packages have'],
majors.length
)} breaking changes. Continue?`,
initial: true,
});
if (!proceed) {
return ctx.exit(0);
}

newline();

await warn('check', `Be sure to follow the ${pluralize('CHANGELOG', majors.length)}.`);
for (const pkg of majors.sort(sortPackages)) {
await changelog(pkg.name, pkg.changelogTitle!, pkg.changelogURL!);
}
}

newline()
newline();
if (ctx.dryRun) {
await info('--dry-run', `Skipping dependency installation`);
} else {
Expand All @@ -76,13 +98,13 @@ function filterPackages(ctx: Pick<Context, 'packages'>) {
arr.push(packageInfo);
}
}
return { current, dependencies, devDependencies }
return { current, dependencies, devDependencies };
}

/**
* An `Array#sort` comparator function to normalize how packages are displayed.
* This only changes how the packages are displayed in the CLI, it is not persisted to `package.json`.
*/
* An `Array#sort` comparator function to normalize how packages are displayed.
* This only changes how the packages are displayed in the CLI, it is not persisted to `package.json`.
*/
function sortPackages(a: PackageInfo, b: PackageInfo): number {
if (a.isMajor && !b.isMajor) return 1;
if (b.isMajor && !a.isMajor) return -1;
Expand All @@ -93,7 +115,11 @@ function sortPackages(a: PackageInfo, b: PackageInfo): number {
return a.name.localeCompare(b.name);
}

async function runInstallCommand(ctx: Pick<Context, 'cwd' | 'packageManager' | 'exit'>, dependencies: PackageInfo[], devDependencies: PackageInfo[]) {
async function runInstallCommand(
ctx: Pick<Context, 'cwd' | 'packageManager' | 'exit'>,
dependencies: PackageInfo[],
devDependencies: PackageInfo[]
) {
const cwd = fileURLToPath(ctx.cwd);
if (ctx.packageManager === 'yarn') await ensureYarnLock({ cwd });

Expand All @@ -103,17 +129,40 @@ async function runInstallCommand(ctx: Pick<Context, 'cwd' | 'packageManager' | '
while: async () => {
try {
if (dependencies.length > 0) {
await shell(ctx.packageManager, ['install', ...dependencies.map(({ name, targetVersion }) => `${name}@${(targetVersion).replace(/^\^/, '')}`)], { cwd, timeout: 90_000, stdio: 'ignore' })
await shell(
ctx.packageManager,
[
'install',
...dependencies.map(
({ name, targetVersion }) => `${name}@${targetVersion.replace(/^\^/, '')}`
),
],
{ cwd, timeout: 90_000, stdio: 'ignore' }
);
}
if (devDependencies.length > 0) {
await shell(ctx.packageManager, ['install', '--save-dev', ...devDependencies.map(({ name, targetVersion }) => `${name}@${(targetVersion).replace(/^\^/, '')}`)], { cwd, timeout: 90_000, stdio: 'ignore' })
await shell(
ctx.packageManager,
[
'install',
'--save-dev',
...devDependencies.map(
({ name, targetVersion }) => `${name}@${targetVersion.replace(/^\^/, '')}`
),
],
{ cwd, timeout: 90_000, stdio: 'ignore' }
);
}
} catch {
const packages = [...dependencies, ...devDependencies].map(({ name, targetVersion }) => `${name}@${targetVersion}`).join(' ')
const packages = [...dependencies, ...devDependencies]
.map(({ name, targetVersion }) => `${name}@${targetVersion}`)
.join(' ');
newline();
error(
'error',
`Dependencies failed to install, please run the following command manually:\n${color.bold(`${ctx.packageManager} install ${packages}`)}`
`Dependencies failed to install, please run the following command manually:\n${color.bold(
`${ctx.packageManager} install ${packages}`
)}`
);
return ctx.exit(1);
}
Expand Down
55 changes: 36 additions & 19 deletions packages/upgrade/src/actions/verify.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import type { Context, PackageInfo } from './context.js';

import { color } from '@astrojs/cli-kit';
import dns from 'node:dns/promises';
import { existsSync } from 'node:fs';
import { readFile } from 'node:fs/promises';
import { color } from '@astrojs/cli-kit';
import { bannerAbort, error, getRegistry, info, log, newline } from '../messages.js';
import semverDiff from 'semver/functions/diff.js';
import semverCoerce from 'semver/functions/coerce.js';
import semverDiff from 'semver/functions/diff.js';
import semverParse from 'semver/functions/parse.js';

import { bannerAbort, error, getRegistry, info, newline } from '../messages.js';

export async function verify(
ctx: Pick<Context, 'version' | 'packages' | 'cwd' | 'dryRun' | 'exit'>
Expand Down Expand Up @@ -49,49 +48,56 @@ function safeJSONParse(value: string) {
try {
return JSON.parse(value);
} catch {}
return {}
return {};
}

async function verifyAstroProject(ctx: Pick<Context, 'cwd' | 'version' | 'packages'>) {
const packageJson = new URL('./package.json', ctx.cwd);
if (!existsSync(packageJson)) return false;
if (!existsSync(packageJson)) return false;
const contents = await readFile(packageJson, { encoding: 'utf-8' });
if (!contents.includes('astro')) return false;

const { dependencies = {}, devDependencies = {} } = safeJSONParse(contents)
const { dependencies = {}, devDependencies = {} } = safeJSONParse(contents);
if (dependencies['astro'] === undefined && devDependencies['astro'] === undefined) return false;

// Side-effect! Persist dependency info to the shared context
collectPackageInfo(ctx, dependencies, devDependencies);

return true;
}

function isAstroPackage(name: string) {
return name === 'astro' || name.startsWith('@astrojs/');
}

function collectPackageInfo(ctx: Pick<Context, 'version' | 'packages'>, dependencies: Record<string, string>, devDependencies: Record<string, string>) {
function collectPackageInfo(
ctx: Pick<Context, 'version' | 'packages'>,
dependencies: Record<string, string>,
devDependencies: Record<string, string>
) {
for (const [name, currentVersion] of Object.entries(dependencies)) {
if (!isAstroPackage(name)) continue;
ctx.packages.push({
name,
currentVersion,
targetVersion: ctx.version,
})
});
}
for (const [name, currentVersion] of Object.entries(devDependencies)) {
if (!isAstroPackage(name)) continue;
ctx.packages.push({
name,
currentVersion,
targetVersion: ctx.version,
isDevDependency: true
})
isDevDependency: true,
});
}
}

async function verifyVersions(ctx: Pick<Context, 'version' | 'packages' | 'exit'>, registry: string) {
async function verifyVersions(
ctx: Pick<Context, 'version' | 'packages' | 'exit'>,
registry: string
) {
const tasks: Promise<void>[] = [];
for (const packageInfo of ctx.packages) {
tasks.push(resolveTargetVersion(packageInfo, registry));
Expand All @@ -110,11 +116,13 @@ async function verifyVersions(ctx: Pick<Context, 'version' | 'packages' | 'exit'
}

async function resolveTargetVersion(packageInfo: PackageInfo, registry: string): Promise<void> {
const packageMetadata = await fetch(`${registry}/${packageInfo.name}`, { headers: { accept: 'application/vnd.npm.install-v1+json' }});
const packageMetadata = await fetch(`${registry}/${packageInfo.name}`, {
headers: { accept: 'application/vnd.npm.install-v1+json' },
});
if (packageMetadata.status >= 400) {
throw new Error(`Unable to resolve "${packageInfo.name}"`);
}
const { "dist-tags": distTags } = await packageMetadata.json();
const { 'dist-tags': distTags } = await packageMetadata.json();
let version = distTags[packageInfo.targetVersion];
if (version) {
packageInfo.tag = packageInfo.targetVersion;
Expand Down Expand Up @@ -159,7 +167,16 @@ async function resolveTargetVersion(packageInfo: PackageInfo, registry: string):
}
}

function extractChangelogURLFromRepository(repository: Record<string, string>, version: string, branch = 'main') {
return repository.url.replace('git+', '').replace('.git', '') + `/blob/${branch}/` + repository.directory + '/CHANGELOG.md#' + version.replace(/\./g, '')
function extractChangelogURLFromRepository(
repository: Record<string, string>,
version: string,
branch = 'main'
) {
return (
repository.url.replace('git+', '').replace('.git', '') +
`/blob/${branch}/` +
repository.directory +
'/CHANGELOG.md#' +
version.replace(/\./g, '')
);
}

14 changes: 3 additions & 11 deletions packages/upgrade/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getContext } from './actions/context.js';

import { install } from './actions/install.js';
import { help } from './actions/help.js';
import { install } from './actions/install.js';
import { verify } from './actions/verify.js';
import { setStdout } from './messages.js';

Expand All @@ -21,20 +21,12 @@ export async function main() {
return;
}

const steps = [
verify,
install,
];
const steps = [verify, install];

for (const step of steps) {
await step(ctx);
}
process.exit(0);
}

export {
install,
getContext,
setStdout,
verify,
};
export { getContext, install, setStdout, verify };
Loading

0 comments on commit e7ce779

Please sign in to comment.