From 7c85750089e022240376751086d515d993409d98 Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Tue, 12 Dec 2023 13:00:43 +0000 Subject: [PATCH] feat: update command handles Dockerized sandbox (#3656) This PR cherry-picks some of the changes from #3567 1. It no longer fails if it doesn't detect package.json. So it can now be used to update contracts on their own aztec-cli update --contract path/to/some/folder 2. Instead of looking for the latest @aztec/aztec-sandbox, it now looks for the latest @aztec/aztec.js. 3. Prints a reminder to the user to update Docker containers and links to update instructions. --- yarn-project/cli/src/index.ts | 5 +- yarn-project/cli/src/update/npm.ts | 20 +++++ yarn-project/cli/src/update/update.ts | 111 +++++++------------------- 3 files changed, 52 insertions(+), 84 deletions(-) diff --git a/yarn-project/cli/src/index.ts b/yarn-project/cli/src/index.ts index 08fd0c44b5e..83d5ebd3f96 100644 --- a/yarn-project/cli/src/index.ts +++ b/yarn-project/cli/src/index.ts @@ -483,11 +483,12 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { .description('Updates Nodejs and Noir dependencies') .argument('[projectPath]', 'Path to the project directory', process.cwd()) .option('--contract [paths...]', 'Paths to contracts to update dependencies', []) - .option('--sandbox-version ', 'The sandbox version to update to. Defaults to latest', 'latest') + .option('--aztec-version ', 'The version to update Aztec packages to. Defaults to latest', 'latest') .addOption(pxeOption) .action(async (projectPath: string, options) => { const { update } = await import('./update/update.js'); - await update(projectPath, options.contract, options.rpcUrl, options.sandboxVersion, log, debugLogger); + const { contract, aztecVersion, rpcUrl } = options; + await update(projectPath, contract, rpcUrl, aztecVersion, log); }); addNoirCompilerCommanderActions(program, log); diff --git a/yarn-project/cli/src/update/npm.ts b/yarn-project/cli/src/update/npm.ts index 6d73c1ca7d6..703dc29219f 100644 --- a/yarn-project/cli/src/update/npm.ts +++ b/yarn-project/cli/src/update/npm.ts @@ -9,6 +9,15 @@ import { SemVer, parse } from 'semver'; import { atomicUpdateFile } from '../utils.js'; import { DependencyChanges } from './common.js'; +const deprecatedNpmPackages = new Set([]); +const npmDeprecationMessage = ` +The following packages have been deprecated and will no longer be updated on the npm registry: +${Array.from(deprecatedNpmPackages) + .map(pkg => ` - ${pkg}`) + .join('\n')} +Remove them from package.json +`; + /** * Looks up a package.json file and returns its contents * @param projectPath - Path to Nodejs project @@ -68,6 +77,8 @@ export async function updateAztecDeps( log(`Updating @aztec packages to ${aztecVersion} in ${relative(process.cwd(), changes.file)}`); const version = aztecVersion.version; + let detectedDeprecatedPackages = false; + for (const depType of ['dependencies', 'devDependencies'] as const) { const dependencies = pkg[depType]; if (!dependencies) { @@ -84,6 +95,11 @@ export async function updateAztecDeps( continue; } + if (deprecatedNpmPackages.has(name)) { + detectedDeprecatedPackages = true; + continue; + } + if (dependencies[name] !== version) { changes.dependencies.push({ name, @@ -96,6 +112,10 @@ export async function updateAztecDeps( } } + if (detectedDeprecatedPackages) { + log(npmDeprecationMessage); + } + if (changes.dependencies.length > 0) { const contents = JSON.stringify(pkg, null, 2) + '\n'; await atomicUpdateFile(resolve(join(projectPath, 'package.json')), contents); diff --git a/yarn-project/cli/src/update/update.ts b/yarn-project/cli/src/update/update.ts index 977cb699c4e..9f78d0caab2 100644 --- a/yarn-project/cli/src/update/update.ts +++ b/yarn-project/cli/src/update/update.ts @@ -1,84 +1,68 @@ /* eslint-disable jsdoc/require-jsdoc */ -import { DebugLogger, LogFn } from '@aztec/foundation/log'; +import { LogFn } from '@aztec/foundation/log'; import { relative, resolve } from 'path'; -import { SemVer, coerce, gt, lt, parse } from 'semver'; +import { parse } from 'semver'; -import { createCompatibleClient } from '../client.js'; import { GITHUB_TAG_PREFIX } from '../github.js'; import { DependencyChanges } from './common.js'; import { updateAztecNr } from './noir.js'; -import { getNewestVersion as getLatestVersion, readPackageJson, updateAztecDeps, updateLockfile } from './npm.js'; +import { getNewestVersion, updateAztecDeps, updateLockfile } from './npm.js'; -const SANDBOX_PACKAGE = '@aztec/aztec-sandbox'; +const AZTECJS_PACKAGE = '@aztec/aztec.js'; +const UPDATE_DOCS_URL = 'https://docs.aztec.network/dev_docs/updating'; export async function update( projectPath: string, contracts: string[], pxeUrl: string, - sandboxVersion: string, + aztecVersion: string, log: LogFn, - debugLog: DebugLogger, ): Promise { - const targetSandboxVersion = - sandboxVersion === 'latest' ? await getLatestVersion(SANDBOX_PACKAGE, 'latest') : parse(sandboxVersion); + const targetAztecVersion = + aztecVersion === 'latest' ? await getNewestVersion(AZTECJS_PACKAGE, 'latest') : parse(aztecVersion); - if (!targetSandboxVersion) { - throw new Error(`Invalid aztec version ${sandboxVersion}`); + if (!targetAztecVersion) { + throw new Error(`Invalid aztec version ${aztecVersion}`); } - let currentSandboxVersion = await getNpmSandboxVersion(projectPath, log); - - if (!currentSandboxVersion) { - currentSandboxVersion = await getRemoteSandboxVersion(pxeUrl, log, debugLog); - - if (currentSandboxVersion && lt(currentSandboxVersion, targetSandboxVersion)) { - log(` -Sandbox is older than version ${targetSandboxVersion}. If running via docker-compose, follow update instructions: -https://docs.aztec.network/dev_docs/cli/updating - -Once the sandbox is updated, run the \`aztec-cli update\` command again`); - return; + const projectDependencyChanges: DependencyChanges[] = []; + try { + const npmChanges = await updateAztecDeps(resolve(process.cwd(), projectPath), targetAztecVersion, log); + if (npmChanges.dependencies.length > 0) { + updateLockfile(projectPath, log); } - } - - if (!currentSandboxVersion) { - throw new Error('Sandbox version could not be detected'); - } - - // sanity check - if (gt(currentSandboxVersion, targetSandboxVersion)) { - throw new Error('Local sandbox version is newer than latest version.'); - } - const npmChanges = await updateAztecDeps(projectPath, targetSandboxVersion, log); - if (npmChanges.dependencies.length > 0) { - updateLockfile(projectPath, log); + projectDependencyChanges.push(npmChanges); + } catch (err) { + if (err instanceof Error && 'code' in err && err.code === 'ENOENT') { + log(`No package.json found in ${projectPath}. Skipping npm update...`); + } else { + throw err; + } } - const contractChanges: DependencyChanges[] = []; for (const contract of contracts) { try { - contractChanges.push( + projectDependencyChanges.push( await updateAztecNr( - resolve(projectPath, contract), - `${GITHUB_TAG_PREFIX}-v${targetSandboxVersion.version}`, + resolve(process.cwd(), projectPath, contract), + `${GITHUB_TAG_PREFIX}-v${targetAztecVersion.version}`, log, ), ); } catch (err) { if (err instanceof Error && 'code' in err && err.code === 'ENOENT') { log(`No Nargo.toml found in ${relative(process.cwd(), contract)}. Skipping...`); - process.exit(1); + } else { + throw err; } - - throw err; } } - printChanges(npmChanges, log); + log(`To update Docker containers follow instructions at ${UPDATE_DOCS_URL}`); - contractChanges.forEach(changes => { + projectDependencyChanges.forEach(changes => { printChanges(changes, log); }); } @@ -93,40 +77,3 @@ function printChanges(changes: DependencyChanges, log: LogFn): void { }); } } - -async function getNpmSandboxVersion(projectPath: string, log: LogFn): Promise { - try { - const pkg = await readPackageJson(projectPath); - // use coerce instead of parse because it eliminates semver operators like ~ and ^ - if (pkg.dependencies?.[SANDBOX_PACKAGE]) { - return coerce(pkg.dependencies[SANDBOX_PACKAGE]); - } else if (pkg.devDependencies?.[SANDBOX_PACKAGE]) { - return coerce(pkg.devDependencies[SANDBOX_PACKAGE]); - } else { - return null; - } - } catch (err) { - if (err instanceof Error && 'code' in err && err.code === 'ENOENT') { - log(`No package.json found in ${projectPath}`); - process.exit(1); - } - - throw err; - } -} - -async function getRemoteSandboxVersion(pxeUrl: string, log: LogFn, debugLog: DebugLogger): Promise { - try { - const client = await createCompatibleClient(pxeUrl, debugLog); - const nodeInfo = await client.getNodeInfo(); - - return parse(nodeInfo.sandboxVersion); - } catch (err) { - if (err instanceof Error && err.message === 'fetch failed') { - log(`Could not connect to Sandbox running on ${pxeUrl}`); - process.exit(1); - } - - throw err; - } -}