@travetto/pack
Version:
Code packing utilities
119 lines (103 loc) • 4.74 kB
text/typescript
import path from 'node:path';
import { RuntimeIndex } from '@travetto/runtime';
import { CliCommand, CliFlag, CliUtil, CliValidationError } from '@travetto/cli';
import { Ignore, Required } from '@travetto/schema';
import { DockerPackOperation } from './bin/docker-operation.ts';
import { BasePackCommand, PackOperationShape } from './pack.base';
import { DockerPackConfig } from '../src/types.ts';
const NODE_MAJOR = process.version.match(/\d+/)?.[0] ?? '22';
/**
* Standard docker support for pack
*/
export class PackDockerCommand extends BasePackCommand {
dockerFactory = '@travetto/pack/support/pack.dockerfile.ts';
dockerImage = `node:${NODE_MAJOR}-alpine`;
dockerName: string;
dockerRuntimeUserSrc?: string;
dockerRuntimePackages: string[] = [];
dockerPort: number[] = [];
// Publish flags
dockerStageOnly: boolean = false;
dockerTag: string[] = ['latest'];
dockerPush = false;
dockerBuildPlatform?: string;
dockerRegistry?: string;
dockerRuntime: DockerPackConfig['dockerRuntime'];
appFolder = 'app';
defaultUser = this.appFolder;
defaultUserId = 2000;
async validate(): Promise<CliValidationError[] | undefined> {
const errs: CliValidationError[] = [];
if (this.dockerPort?.length) {
for (let i = 0; i < this.dockerPort.length; i++) {
if (this.dockerPort[i] < 1) {
errs.push({ source: 'flag', message: `dockerPort[${i}] is less than (1)` });
} else if (this.dockerPort[i] > 65536) {
errs.push({ source: 'flag', message: `dockerPort[${i}] is greater than (65536)` });
}
}
}
return errs;
}
preMain(): void {
if (this.dockerFactory.startsWith('.')) {
this.dockerFactory = RuntimeIndex.getFromSource(path.resolve(this.dockerFactory))?.import ?? this.dockerFactory;
}
this.dockerName ??= CliUtil.getSimpleModuleName('<module>', this.module || undefined);
// Finalize user/group and ids
const [userOrUid, groupOrGid = userOrUid] = (this.dockerRuntimeUserSrc ?? '').split(':');
const groupIsNum = /^\d+$/.test(groupOrGid);
const userIsNum = /^\d+$/.test(userOrUid);
const uid = userIsNum ? +userOrUid : this.defaultUserId;
const gid = groupIsNum ? +groupOrGid : this.defaultUserId;
const group = (!groupIsNum ? groupOrGid : undefined) || this.defaultUser;
const user = (!userIsNum ? userOrUid : undefined) || this.defaultUser;
this.dockerRuntime = { user, uid, group, gid, folder: `/${this.appFolder}`, packages: this.dockerRuntimePackages };
if (this.dockerStageOnly) {
if (this.dockerRegistry) {
console.warn('Docker Registry is currently ignored due to --docker-build being false');
}
if (this.dockerBuildPlatform) {
console.warn('Docker Build Platform is currently ignored due to --docker-build being false');
}
if (this.dockerPush) {
console.warn('Docker Push is currently ignored due to --docker-build being false');
}
if (this.dockerTag) {
console.warn('Docker Tag is currently ignored due to --docker-build being false');
}
}
}
preHelp(): void {
this.dockerName = CliUtil.getSimpleModuleName('<module>');
}
getOperations(): PackOperationShape<this>[] {
return [
...super.getOperations(),
DockerPackOperation.pullDockerBaseImage,
DockerPackOperation.detectDockerImageOs,
DockerPackOperation.writeDockerFile,
...this.dockerStageOnly ? [] : [
DockerPackOperation.buildDockerContainer,
DockerPackOperation.pushDockerContainer
]
];
}
}