-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(node): convert npm tools to typescript (#1285)
- Loading branch information
Showing
19 changed files
with
299 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export const NoPrepareTools = [ | ||
'corepack', | ||
'flux', | ||
'lerna', | ||
'npm', | ||
'pnpm', | ||
'renovate', | ||
'yarn', | ||
'yarn-slim', | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { join } from 'node:path'; | ||
import { execa } from 'execa'; | ||
import { injectable } from 'inversify'; | ||
import { InstallNpmBaseService } from './utils'; | ||
|
||
@injectable() | ||
export class InstallCorepackService extends InstallNpmBaseService { | ||
override name: string = 'corepack'; | ||
|
||
override async postInstall(version: string): Promise<void> { | ||
await super.postInstall(version); | ||
|
||
const src = join(this.pathSvc.versionedToolPath(this.name, version), 'bin'); | ||
await this.shellwrapper({ srcDir: src, name: 'pnpm' }); | ||
await this.shellwrapper({ srcDir: src, name: 'yarn' }); | ||
} | ||
} | ||
|
||
@injectable() | ||
export class InstallLernaService extends InstallNpmBaseService { | ||
override readonly name: string = 'lerna'; | ||
} | ||
|
||
@injectable() | ||
export class InstallNpmService extends InstallNpmBaseService { | ||
override readonly name: string = 'npm'; | ||
} | ||
|
||
@injectable() | ||
export class InstallPnpmService extends InstallNpmBaseService { | ||
override readonly name: string = 'pnpm'; | ||
} | ||
|
||
@injectable() | ||
export class InstallRenovateService extends InstallNpmBaseService { | ||
override readonly name: string = 'renovate'; | ||
|
||
override async postInstall(version: string): Promise<void> { | ||
await super.postInstall(version); | ||
|
||
const src = join(this.pathSvc.versionedToolPath(this.name, version), 'bin'); | ||
await this.shellwrapper({ srcDir: src, name: 'renovate-config-validator' }); | ||
} | ||
} | ||
|
||
@injectable() | ||
export class InstallYarnService extends InstallNpmBaseService { | ||
override readonly name: string = 'yarn'; | ||
} | ||
|
||
@injectable() | ||
export class InstallYarnSlimService extends InstallNpmBaseService { | ||
override readonly name: string = 'yarn-slim'; | ||
|
||
protected override get tool(): string { | ||
return 'yarn'; | ||
} | ||
|
||
override async install(version: string): Promise<void> { | ||
await super.install(version); | ||
// TODO: replace with javascript | ||
const prefix = await this.pathSvc.findVersionedToolPath(this.name, version); | ||
await execa( | ||
'sed', | ||
[ | ||
'-i', | ||
's/ steps,/ steps.slice(0,1),/', | ||
`${prefix}/node_modules/yarn/lib/cli.js`, | ||
], | ||
{ stdio: 'inherit' } | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import fs from 'node:fs/promises'; | ||
import { join } from 'node:path'; | ||
import { env as penv } from 'node:process'; | ||
import { execa } from 'execa'; | ||
import { inject, injectable } from 'inversify'; | ||
import { InstallToolBaseService } from '../../install-tool/install-tool-base.service'; | ||
import { EnvService, PathService, VersionService } from '../../services'; | ||
import { parse } from '../../utils'; | ||
|
||
const defaultRegistry = 'https://registry.npmjs.org/'; | ||
|
||
@injectable() | ||
export abstract class InstallNpmBaseService extends InstallToolBaseService { | ||
protected get tool(): string { | ||
return this.name; | ||
} | ||
|
||
constructor( | ||
@inject(EnvService) envSvc: EnvService, | ||
@inject(PathService) pathSvc: PathService, | ||
@inject(VersionService) protected versionSvc: VersionService | ||
) { | ||
super(pathSvc, envSvc); | ||
} | ||
|
||
override async install(version: string): Promise<void> { | ||
const npm = await this.getNodeNpm(); | ||
const tmp = await fs.mkdtemp( | ||
join(this.pathSvc.tmpDir, 'containerbase-npm-') | ||
); | ||
const env: NodeJS.ProcessEnv = { | ||
NO_UPDATE_NOTIFIER: '1', | ||
npm_config_update_notifier: 'false', | ||
npm_config_fund: 'false', | ||
}; | ||
|
||
if (!penv.npm_config_cache && !penv.NPM_CONFIG_CACHE) { | ||
env.npm_config_cache = tmp; | ||
} | ||
|
||
if (!penv.npm_config_registry && !penv.NPM_CONFIG_REGISTRY) { | ||
const registry = this.envSvc.replaceUrl(defaultRegistry); | ||
if (registry !== defaultRegistry) { | ||
env.npm_config_registry = registry; | ||
} | ||
} | ||
|
||
// TODO: create recursive | ||
if (!(await this.pathSvc.findToolPath(this.name))) { | ||
await this.pathSvc.createToolPath(this.name); | ||
} | ||
|
||
const prefix = await this.pathSvc.createVersionedToolPath( | ||
this.name, | ||
version | ||
); | ||
|
||
await execa( | ||
npm, | ||
[ | ||
'install', | ||
`${this.tool}@${version}`, | ||
'--save-exact', | ||
'--no-audit', | ||
'--prefix', | ||
prefix, | ||
'--cache', | ||
tmp, | ||
'--silent', | ||
], | ||
{ stdio: ['inherit', 'inherit', 1], env } | ||
); | ||
|
||
await fs.symlink(`${prefix}/node_modules/.bin`, `${prefix}/bin`); | ||
|
||
const ver = parse(version)!; | ||
|
||
if (this.name === 'npm' && ver.major < 7) { | ||
// update to latest node-gyp to fully support python3 | ||
await execa( | ||
join(prefix, 'bin/npm'), | ||
[ | ||
'explore', | ||
'npm', | ||
'--prefix', | ||
prefix, | ||
'--silent', | ||
'--', | ||
'npm', | ||
'install', | ||
'node-gyp@latest', | ||
'--no-audit', | ||
'--cache', | ||
tmp, | ||
'--silent', | ||
], | ||
{ stdio: ['inherit', 'inherit', 1], env } | ||
); | ||
} | ||
|
||
await fs.rm(tmp, { recursive: true, force: true }); | ||
await fs.rm(join(this.envSvc.home, '.npm/_logs'), { | ||
recursive: true, | ||
force: true, | ||
}); | ||
} | ||
|
||
override async link(version: string): Promise<void> { | ||
await this.postInstall(version); | ||
} | ||
|
||
override async postInstall(version: string): Promise<void> { | ||
const src = join(this.pathSvc.versionedToolPath(this.name, version), 'bin'); | ||
|
||
await this.shellwrapper({ srcDir: src, name: this.tool }); | ||
} | ||
|
||
override async test(_version: string): Promise<void> { | ||
await execa(this.tool, ['--version'], { stdio: 'inherit' }); | ||
} | ||
|
||
override async validate(version: string): Promise<boolean> { | ||
if (!(await super.validate(version))) { | ||
return false; | ||
} | ||
|
||
return (await this.versionSvc.find('node')) !== null; | ||
} | ||
|
||
protected async getNodeNpm(): Promise<string> { | ||
const nodeVersion = await this.versionSvc.find('node'); | ||
|
||
if (!nodeVersion) { | ||
throw new Error('Node not installed'); | ||
} | ||
|
||
return join(this.pathSvc.versionedToolPath('node', nodeVersion), 'bin/npm'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.