Skip to content

Commit

Permalink
feat(php): convert php installer
Browse files Browse the repository at this point in the history
  • Loading branch information
viceice committed Aug 6, 2024
1 parent cc0809b commit ab59afa
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 98 deletions.
3 changes: 3 additions & 0 deletions src/cli/install-tool/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
YarnVersionResolver,
} from '../tools/node/resolver';
import { NpmBaseInstallService } from '../tools/node/utils';
import { PhpInstallService, PhpVersionResolver } from '../tools/php';
import {
ComposerInstallService,
ComposerVersionResolver,
Expand Down Expand Up @@ -99,6 +100,7 @@ function prepareInstallContainer(): Container {
container.bind(INSTALL_TOOL_TOKEN).to(KustomizeInstallService);
container.bind(INSTALL_TOOL_TOKEN).to(MavenInstallService);
container.bind(INSTALL_TOOL_TOKEN).to(NodeInstallService);
container.bind(INSTALL_TOOL_TOKEN).to(PhpInstallService);
container.bind(INSTALL_TOOL_TOKEN).to(RenovateInstallService);
container.bind(INSTALL_TOOL_TOKEN).to(SkopeoInstallService);
container.bind(INSTALL_TOOL_TOKEN).to(SopsInstallService);
Expand Down Expand Up @@ -127,6 +129,7 @@ function prepareResolveContainer(): Container {
container.bind(TOOL_VERSION_RESOLVER).to(JavaJdkVersionResolver);
container.bind(TOOL_VERSION_RESOLVER).to(MavenVersionResolver);
container.bind(TOOL_VERSION_RESOLVER).to(NodeVersionResolver);
container.bind(TOOL_VERSION_RESOLVER).to(PhpVersionResolver);
container.bind(TOOL_VERSION_RESOLVER).to(YarnVersionResolver);

logger.trace('preparing container done');
Expand Down
2 changes: 2 additions & 0 deletions src/cli/prepare-tool/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
JavaPrepareService,
} from '../tools/java';
import { NodePrepareService } from '../tools/node';
import { PhpPrepareService } from '../tools/php';
import { ConanPrepareService } from '../tools/python/conan';
import { logger } from '../utils';
import { PrepareLegacyToolsService } from './prepare-legacy-tools.service';
Expand All @@ -34,6 +35,7 @@ function prepareContainer(): Container {
container.bind(PREPARE_TOOL_TOKEN).to(JavaJrePrepareService);
container.bind(PREPARE_TOOL_TOKEN).to(JavaJdkPrepareService);
container.bind(PREPARE_TOOL_TOKEN).to(NodePrepareService);
container.bind(PREPARE_TOOL_TOKEN).to(PhpPrepareService);

logger.trace('preparing container done');
return container;
Expand Down
155 changes: 155 additions & 0 deletions src/cli/tools/php/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import fs from 'node:fs/promises';
import { join } from 'node:path';
import { isNonEmptyStringAndNotWhitespace } from '@sindresorhus/is';
import { execa } from 'execa';
import { inject, injectable } from 'inversify';
import { BaseInstallService } from '../../install-tool/base-install.service';
import { ToolVersionResolver } from '../../install-tool/tool-version-resolver';
import { BasePrepareService } from '../../prepare-tool/base-prepare.service';
import {
AptService,
CompressionService,
EnvService,
HttpService,
PathService,
} from '../../services';
import { getDistro, logger } from '../../utils';

@injectable()
export class PhpPrepareService extends BasePrepareService {
override readonly name = 'php';

constructor(
@inject(PathService) pathSvc: PathService,
@inject(EnvService) envSvc: EnvService,
@inject(AptService) private readonly aptSvc: AptService,
) {
super(pathSvc, envSvc);
}

override async execute(): Promise<void> {
const distro = await getDistro();

switch (distro.versionCode) {
case 'focal':
await this.aptSvc.install(
'libjpeg-turbo8',
'libmcrypt4',
'libonig5',
'libpng16-16',
'libtidy5deb1',
'libxslt1.1',
'libzip5',
);
break;

case 'jammy':
case 'noble':
await this.aptSvc.install(
'libjpeg-turbo8',
'libmcrypt4',
'libonig5',
'libpng16-16',
'libtidy5deb1',
'libxslt1.1',
'libzip4',
);

break;

default:
throw new Error(`Unsupported distro version: ${distro.versionCode}`);
}
}
}

@injectable()
export class PhpInstallService extends BaseInstallService {
readonly name = 'php';

private get ghArch(): string {
switch (this.envSvc.arch) {
case 'arm64':
return 'aarch64';
case 'amd64':
return 'x86_64';
}
}

constructor(
@inject(EnvService) envSvc: EnvService,
@inject(PathService) pathSvc: PathService,
@inject(HttpService) private http: HttpService,
@inject(CompressionService) private compress: CompressionService,
) {
super(pathSvc, envSvc);
}

override async install(version: string): Promise<void> {
const name = this.name;
const distro = await getDistro();
let code = distro.versionCode;

if (code === 'noble') {
logger.debug(`Using jammy prebuild for ${name} on ${code}`);
code = 'jammy';
}
const filename = `${version}/${name}-${version}-${code}-${this.ghArch}.tar.xz`;
const checksumFileUrl = `https://github.com/containerbase/${name}-prebuild/releases/download/${filename}.sha512`;
const hasChecksum = await this.http.exists(checksumFileUrl);
let file: string;

if (hasChecksum) {
// no distro specific prebuilds
const expectedChecksum = await this.getChecksum(checksumFileUrl);
file = await this.http.download({
url: `https://github.com/containerbase/${name}-prebuild/releases/download/${filename}`,
checksumType: 'sha512',
expectedChecksum,
});
} else {
file = await this.http.download({
url: `https://github.com/containerbase/${name}-prebuild/releases/download/${filename}`,
});
}

const path = await this.pathSvc.ensureToolPath(this.name);

await this.compress.extract({ file, cwd: path });
}

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 });
}

override async test(_version: string): Promise<void> {
await execa('php', ['--version'], {
stdio: ['inherit', 'inherit', 1],
});
}

private async getChecksum(checksumFileUrl: string): Promise<string> {
const checksumFile = await this.http.download({ url: checksumFileUrl });
const expectedChecksum = (await fs.readFile(checksumFile, 'utf-8')).trim();
return expectedChecksum;
}
}

@injectable()
export class PhpVersionResolver extends ToolVersionResolver {
readonly tool = 'php';

async resolve(version: string | undefined): Promise<string | undefined> {
if (!isNonEmptyStringAndNotWhitespace(version) || version === 'latest') {
return await this.http.get(
`https://github.com/containerbase/${this.tool}-prebuild/releases/latest/download/version`,
);
}
return version;
}
}
95 changes: 0 additions & 95 deletions src/usr/local/containerbase/tools/v2/php.sh

This file was deleted.

5 changes: 2 additions & 3 deletions test/php/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ RUN prepare-tool php

USER 1000


# renovate: datasource=github-releases packageName=containerbase/php-prebuild
RUN install-tool php 8.3.9
# test without version
RUN install-tool php

# test without version
RUN install-tool composer
Expand Down

0 comments on commit ab59afa

Please sign in to comment.