88
99import * as path from 'path' ;
1010import * as fs from 'fs' ;
11- import lockfile from '@yarnpkg/lockfile' ;
1211import { parse as parseYaml } from 'yaml' ;
13- import { ngDevNpmPackageName , workspaceRelativePackageJsonPath } from './constants.js' ;
12+ import { workspaceRelativePackageJsonPath } from './constants.js' ;
1413import { Log } from './logging.js' ;
1514import { tryGetPackageId } from '@pnpm/dependency-path' ;
1615import { determineRepoBaseDirFromCwd } from './repo-directory.js' ;
16+ import { GitClient } from './git/git-client.js' ;
17+
18+ /**
19+ * The currently executing version of ng-dev
20+ * Note: The placeholder will be replaced by the `pkg_npm` substitutions.
21+ */
22+ const localVersion = `0.0.0-{SCM_HEAD_SHA}` ;
1723
1824/** Whether ngDevVersionMiddleware verification has already occured. */
1925let verified = false ;
@@ -38,21 +44,14 @@ export async function ngDevVersionMiddleware() {
3844 * @returns a boolean indicating success or failure.
3945 */
4046export async function verifyNgDevToolIsUpToDate ( workspacePath : string ) : Promise < boolean > {
41- // The placeholder will be replaced by the `pkg_npm` substitutions.
42- const localVersion = `0.0.0-{SCM_HEAD_SHA}` ;
43- if ( ! ! process . env [ 'LOCAL_NG_DEV_BUILD' ] ) {
47+ const packageJsonPath = path . join ( workspacePath , workspaceRelativePackageJsonPath ) ;
48+ const packageJson = JSON . parse ( fs . readFileSync ( packageJsonPath , 'utf-8' ) ) ;
49+ // If we are operating in the actual dev-infra repo, always return `true`.
50+ if ( packageJson . name === '@angular/build-tooling' ) {
4451 Log . debug ( 'Skipping ng-dev version check as this is a locally generated version.' ) ;
4552 return true ;
4653 }
47- const workspacePackageJsonFile = path . join ( workspacePath , workspaceRelativePackageJsonPath ) ;
48- const pnpmLockFile = path . join ( workspacePath , 'pnpm-lock.yaml' ) ;
49- const yarnLockFile = path . join ( workspacePath , 'yarn.lock' ) ;
50-
51- // TODO: Clean up this logic when fully dropping Yarn
52- const isPnpmMigrated = fs . existsSync ( pnpmLockFile ) && ! fs . existsSync ( yarnLockFile ) ;
53- const expectedVersion = isPnpmMigrated
54- ? getExpectedVersionFromPnpmLock ( workspacePackageJsonFile , pnpmLockFile )
55- : getExpectedVersionFromYarnLock ( workspacePackageJsonFile , yarnLockFile ) ;
54+ const expectedVersion = await getExpectedVersionFromPnpmLockUpstream ( ) ;
5655
5756 Log . debug ( 'Checking ng-dev version in lockfile and in the running script:' ) ;
5857 Log . debug ( ` Local: ${ localVersion } ` ) ;
@@ -68,49 +67,26 @@ export async function verifyNgDevToolIsUpToDate(workspacePath: string): Promise<
6867 return true ;
6968}
7069
71- function getExpectedVersionFromYarnLock ( workspacePackageJsonFile : string , lockFilePath : string ) {
72- try {
73- const packageJson = JSON . parse ( fs . readFileSync ( workspacePackageJsonFile , 'utf8' ) ) as any ;
74- // If we are operating in the actual dev-infra repo, always return `true`.
75- if ( packageJson . name === ngDevNpmPackageName ) {
76- return true ;
77- }
78-
79- const lockFileContent = fs . readFileSync ( lockFilePath , 'utf8' ) ;
80-
81- let lockFileObject : Record < string , { version : string } > ;
82- try {
83- const lockFile = lockfile . parse ( lockFileContent ) ;
84-
85- if ( lockFile . type !== 'success' ) {
86- throw Error ( 'Unable to parse workspace lock file. Please ensure the file is valid.' ) ;
87- }
88- lockFileObject = lockFile . object as lockfile . LockFileObject ;
89- } catch {
90- lockFileObject = parseYaml ( lockFileContent ) ;
91- }
92-
93- const devInfraPkgVersion =
94- packageJson ?. dependencies ?. [ ngDevNpmPackageName ] ??
95- packageJson ?. devDependencies ?. [ ngDevNpmPackageName ] ??
96- packageJson ?. optionalDependencies ?. [ ngDevNpmPackageName ] ;
97- return lockFileObject [ `${ ngDevNpmPackageName } @${ devInfraPkgVersion } ` ] . version ;
98- } catch ( e ) {
99- Log . debug ( 'Could not find expected ng-dev version from `yarn.lock` file:' , e ) ;
100- return null ;
101- }
102- }
103-
104- function getExpectedVersionFromPnpmLock ( workspacePackageJsonFile : string , lockFilePath : string ) {
70+ /** Retrieves the pnpm lock file from upstream on the primary branch and extracts the version. */
71+ async function getExpectedVersionFromPnpmLockUpstream ( ) : Promise < string > {
72+ const git = await GitClient . get ( ) ;
10573 try {
106- const packageJson = JSON . parse ( fs . readFileSync ( workspacePackageJsonFile , 'utf8' ) ) as any ;
107- // If we are operating in the actual dev-infra repo, always return `true`.
108- if ( packageJson . name === ngDevNpmPackageName ) {
109- return true ;
74+ const { data} = await git . github . repos . getContent ( {
75+ repo : git . remoteConfig . name ,
76+ owner : git . remoteConfig . owner ,
77+ ref : git . remoteConfig . mainBranchName ,
78+ // This media type ensures requested files come back as the raw content.
79+ mediaType : { format : 'application/vnd.github.raw+json' } ,
80+ path : 'pnpm-lock.yaml' ,
81+ } ) ;
82+ if ( Array . isArray ( data ) || data . type !== 'file' ) {
83+ throw Error (
84+ `A non-single file of content was retrieved from Github when the pnpm-lock.yaml file was requested` ,
85+ ) ;
11086 }
111-
112- const lockFileContent = fs . readFileSync ( lockFilePath , 'utf8' ) ;
113- const lockFile = parseYaml ( lockFileContent ) ;
87+ const lockFile = parseYaml (
88+ Buffer . from ( data . content , data . encoding as BufferEncoding ) . toString ( 'utf-8' ) ,
89+ ) ;
11490 const importers = lockFile [ 'importers' ] [ '.' ] ;
11591 const depEntry =
11692 importers . dependencies ?. [ '@angular/ng-dev' ] ??
@@ -121,6 +97,6 @@ function getExpectedVersionFromPnpmLock(workspacePackageJsonFile: string, lockFi
12197 return lockFile [ 'packages' ] [ `@angular/ng-dev@${ packageId } ` ] . version ;
12298 } catch ( e ) {
12399 Log . debug ( 'Could not find expected ng-dev version from `pnpm-lock.yaml` file:' , e ) ;
124- return null ;
100+ return 'unknown' ;
125101 }
126102}
0 commit comments