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

report cdk versions #2414

Merged
merged 9 commits into from
Jan 10, 2025
Merged
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
10 changes: 10 additions & 0 deletions .changeset/silver-tables-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@aws-amplify/backend-deployer': patch
'create-amplify': patch
'@aws-amplify/backend-cli': patch
'@aws-amplify/cli-core': patch
'@aws-amplify/platform-core': minor
'@aws-amplify/plugin-types': minor
---

Report cdk versions
3 changes: 3 additions & 0 deletions .eslint_dictionary.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"changelog",
"changeset",
"changesets",
"checksum",
"chown",
"claude",
"cloudformation",
Expand Down Expand Up @@ -99,6 +100,7 @@
"lang",
"linux",
"localhost",
"lockfile",
"lsof",
"lstat",
"macos",
Expand Down Expand Up @@ -167,6 +169,7 @@
"subpath",
"syncable",
"synthing",
"testapp",
"testname",
"testnamebucket",
"testuser",
Expand Down
1 change: 1 addition & 0 deletions packages/backend-deployer/src/cdk_deployer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void describe('invokeCDKCommand', () => {
runWithPackageManager: mock.fn(() => Promise.resolve() as never),
getCommand: (args: string[]) => `'npx ${args.join(' ')}'`,
allowsSignalPropagation: () => true,
tryGetDependencies: mock.fn(() => Promise.resolve([])),
};

const invoker = new CDKDeployer(
Expand Down
3 changes: 2 additions & 1 deletion packages/cli-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@aws-amplify/platform-core": "^1.3.0",
"@inquirer/prompts": "^3.0.0",
"execa": "^9.5.1",
"kleur": "^4.1.5"
"kleur": "^4.1.5",
"zod": "^3.22.2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import assert from 'assert';
import fsp from 'fs/promises';
import { afterEach, describe, it, mock } from 'node:test';
import path from 'path';
import { NpmLockFileReader } from './npm_lock_file_reader.js';

void describe('NpmLockFileReader', () => {
const fspReadFileMock = mock.method(fsp, 'readFile', () =>
JSON.stringify({
name: 'test_project',
version: '1.0.0',
packages: {
'': {
name: 'test_project',
version: '1.0.0',
},
'node_modules/test_dep': {
version: '1.2.3',
},
'node_modules/some_other_dep': {
version: '12.13.14',
},
},
})
);
const npmLockFileReader = new NpmLockFileReader();

afterEach(() => {
fspReadFileMock.mock.resetCalls();
});

void it('can get lock file contents from cwd', async () => {
const lockFileContents =
await npmLockFileReader.getLockFileContentsFromCwd();
const expectedLockFileContents = {
dependencies: [
{
name: 'test_dep', // "node_modules/" prefix is removed
version: '1.2.3',
},
{
name: 'some_other_dep', // "node_modules/" prefix is removed
version: '12.13.14',
},
],
};
assert.deepEqual(lockFileContents, expectedLockFileContents);
assert.strictEqual(
fspReadFileMock.mock.calls[0].arguments[0],
path.resolve(process.cwd(), 'package-lock.json')
);
assert.strictEqual(fspReadFileMock.mock.callCount(), 1);
});

void it('returns undefined when package-lock.json is not present or parse-able', async () => {
fspReadFileMock.mock.mockImplementationOnce(() =>
Promise.reject(new Error())
);
const lockFileContents =
await npmLockFileReader.getLockFileContentsFromCwd();
assert.deepEqual(lockFileContents, undefined);
});

void it('returns empty dependency array when package-lock.json does not have dependencies', async () => {
fspReadFileMock.mock.mockImplementationOnce(() =>
JSON.stringify({
name: 'test_project',
version: '1.0.0',
})
);
const lockFileContents =
await npmLockFileReader.getLockFileContentsFromCwd();
assert.deepEqual(lockFileContents, { dependencies: [] });
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Dependency } from '@aws-amplify/plugin-types';
import fsp from 'fs/promises';
import path from 'path';
import z from 'zod';
import { LockFileContents, LockFileReader } from './types.js';
import { printer } from '../../printer.js';
import { LogLevel } from '../../printer/printer.js';

/**
* NpmLockFileReader is an abstraction around the logic used to read and parse lock file contents
*/
export class NpmLockFileReader implements LockFileReader {
getLockFileContentsFromCwd = async (): Promise<
LockFileContents | undefined
> => {
const dependencies: Array<Dependency> = [];
const packageLockJsonPath = path.resolve(
process.cwd(),
'package-lock.json'
);
let packageLockJson;
try {
const jsonLockContents = await fsp.readFile(packageLockJsonPath, 'utf-8');
const jsonLockParsedValue = JSON.parse(jsonLockContents);
// This will strip fields that are not part of the package lock schema
packageLockJson = packageLockJsonSchema.parse(jsonLockParsedValue);
} catch (error) {
printer.log(
`Failed to get lock file contents because ${packageLockJsonPath} does not exist or is not parse-able`,
LogLevel.DEBUG
);
return;
}

for (const key in packageLockJson.packages) {
if (key === '') {
// Skip root project in packages
continue;
}
const dependencyVersion = packageLockJson.packages[key].version;

// Version may not exist if package is a symbolic link
if (dependencyVersion) {
// Remove "node_modules/" prefix
const dependencyName = key.replace(/^node_modules\//, '');
dependencies.push({
name: dependencyName,
version: dependencyVersion,
});
}
}

return { dependencies };
};
}

const packageLockJsonSchema = z.object({
packages: z
.record(
z.string(),
z.object({
version: z.string().optional(),
})
)
.optional(),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import assert from 'assert';
import fsp from 'fs/promises';
import { afterEach, describe, it, mock } from 'node:test';
import path from 'path';
import { PnpmLockFileReader } from './pnpm_lock_file_reader.js';

void describe('PnpmLockFileReader', () => {
const fspReadFileMock = mock.method(
fsp,
'readFile',
() => `lockfileVersion: '9.0'

settings:
autoInstallPeers: true
excludeLinksFromLockfile: false

importers:

.:
dependencies:
aws-amplify:
specifier: ^6.12.0
version: 6.12.0
devDependencies:
'@aws-amplify/backend':
specifier: ^1.11.0
version: 1.12.0(@aws-sdk/[email protected])(@aws-sdk/[email protected])(@aws-sdk/[email protected](@aws-sdk/[email protected]))(@aws-sdk/[email protected])([email protected]([email protected]))([email protected])([email protected])
'@aws-amplify/backend-cli':
specifier: ^1.4.5
version: 1.4.6(@aws-sdk/[email protected](@aws-sdk/[email protected]))(@aws-sdk/[email protected])(@aws-sdk/[email protected])([email protected]([email protected]))([email protected])([email protected])([email protected]([email protected]))([email protected])([email protected])
aws-cdk:
specifier: ^2.173.4
version: 2.174.1
aws-cdk-lib:
specifier: ^2.173.4
version: 2.174.1([email protected])
constructs:
specifier: ^10.4.2
version: 10.4.2
esbuild:
specifier: ^0.24.2
version: 0.24.2
tsx:
specifier: ^4.19.2
version: 4.19.2
typescript:
specifier: ^5.7.2
version: 5.7.2

packages:

'@[email protected]':
resolution: {integrity: some-sha}
engines: {node: '>=6.0.0'}

'[email protected]':
resolution: {integrity: some-other-sha}
engines: {node: '>=8'}`
);
const pnpmLockFileReader = new PnpmLockFileReader();

afterEach(() => {
fspReadFileMock.mock.resetCalls();
});

void it('can get lock file contents from cwd', async () => {
const lockFileContents =
await pnpmLockFileReader.getLockFileContentsFromCwd();
const expectedLockFileContents = {
dependencies: [
{
name: '@test_dep',
version: '1.2.3',
},
{
name: 'some_other_dep',
version: '12.13.14',
},
],
};
assert.deepEqual(lockFileContents, expectedLockFileContents);
assert.strictEqual(
fspReadFileMock.mock.calls[0].arguments[0],
path.resolve(process.cwd(), 'pnpm-lock.yaml')
);
assert.strictEqual(fspReadFileMock.mock.callCount(), 1);
});

void it('returns empty lock file contents when pnpm-lock.yaml is not present or parse-able', async () => {
fspReadFileMock.mock.mockImplementationOnce(() =>
Promise.reject(new Error())
);
const lockFileContents =
await pnpmLockFileReader.getLockFileContentsFromCwd();
assert.deepEqual(lockFileContents, undefined);
});

void it('returns empty dependency array when pnpm-lock.yaml does not have dependencies', async () => {
mock.method(
fsp,
'readFile',
() => `lockfileVersion: '9.0'

settings:
autoInstallPeers: true
excludeLinksFromLockfile: false

importers:

.:
dependencies:
aws-amplify:
specifier: ^6.12.0
version: 6.12.0
devDependencies:
'@aws-amplify/backend':
specifier: ^1.11.0
version: 1.12.0(@aws-sdk/[email protected])(@aws-sdk/[email protected])(@aws-sdk/[email protected](@aws-sdk/[email protected]))(@aws-sdk/[email protected])([email protected]([email protected]))([email protected])([email protected])
'@aws-amplify/backend-cli':
specifier: ^1.4.5
version: 1.4.6(@aws-sdk/[email protected](@aws-sdk/[email protected]))(@aws-sdk/[email protected])(@aws-sdk/[email protected])([email protected]([email protected]))([email protected])([email protected])([email protected]([email protected]))([email protected])([email protected])
aws-cdk:
specifier: ^2.173.4
version: 2.174.1
aws-cdk-lib:
specifier: ^2.173.4
version: 2.174.1([email protected])
constructs:
specifier: ^10.4.2
version: 10.4.2
esbuild:
specifier: ^0.24.2
version: 0.24.2
tsx:
specifier: ^4.19.2
version: 4.19.2
typescript:
specifier: ^5.7.2
version: 5.7.2`
);
const lockFileContents =
await pnpmLockFileReader.getLockFileContentsFromCwd();
assert.deepEqual(lockFileContents, { dependencies: [] });
});
});
Loading
Loading