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

feat: support url rewrite #1210

Merged
merged 12 commits into from
Jul 22, 2023
53 changes: 53 additions & 0 deletions src/cli/command/download-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { createWriteStream } from 'node:fs';
import { mkdir } from 'node:fs/promises';
import { dirname } from 'node:path';
import { pipeline } from 'node:stream/promises';
import { Command, Option } from 'clipanion';
import { got } from 'got';
import prettyMilliseconds from 'pretty-ms';
import { EnvService, rootContainer } from '../services';
import { logger } from '../utils';

export class DownloadFileCommand extends Command {
static override paths = [['download', 'file'], ['df']];

static override usage = Command.Usage({
description: 'Downloads a file and optionally validates the checksum.',
});

url = Option.String({ required: true });
output = Option.String({ required: true });

// checksum = Option.String('-c,--checksum');
// algo = Option.String('-a,--algo');

// dryRun = Option.Boolean('-d,--dry-run', false);

async execute(): Promise<number | void> {
const start = Date.now();
let error = false;
logger.info({ url: this.url }, `Downloading file ...`);
try {
const container = rootContainer.createChild();

const env = container.get(EnvService);
const path = dirname(this.output);
await mkdir(path, { recursive: true });

const nUrl = env.replaceUrl(this.url);
await pipeline(got.stream(nUrl), createWriteStream(this.output));

return 0;
} catch (err) {
logger.fatal(err);
error = true;
return 1;
} finally {
logger.info(
`Download completed ${
error ? 'with errors ' : ''
} in ${prettyMilliseconds(Date.now() - start)}.`
);
}
}
}
2 changes: 2 additions & 0 deletions src/cli/command/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { argv0 } from 'node:process';
import type { Cli } from 'clipanion';
import type { CliMode } from '../utils';
import { logger } from '../utils/logger';
import { DownloadFileCommand } from './download-file';
import { InstallToolCommand, InstallToolShortCommand } from './install-tool';
import { PrepareToolCommand, PrepareToolShortCommand } from './prepare-tool';
import { prepareToolVersion } from './utils';
Expand All @@ -28,6 +29,7 @@ export function prepareCommands(

cli.register(InstallToolCommand);
cli.register(PrepareToolCommand);
cli.register(DownloadFileCommand);
return prepareToolVersion(mode, args);
}

Expand Down
10 changes: 8 additions & 2 deletions src/cli/command/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export function prepareToolVersion(
args: string[]
): string[] {
switch (mode) {
case 'prepare-tool':
break;
case 'install-tool': {
if (args.length === 1) {
// install-tool node
Expand All @@ -14,10 +16,14 @@ export function prepareToolVersion(
}
case 'containerbase-cli':
default: {
if (args.length === 2) {
if (args.length === 2 && args[0] === 'it') {
// containerbase-cli it node
appendVersion(args, 1);
} else if (args.length === 3) {
} else if (
args.length === 3 &&
args[0] === 'install' &&
args[1] === 'tool'
) {
// containerbase-cli install tool node
appendVersion(args, 2);
}
Expand Down
13 changes: 13 additions & 0 deletions src/cli/services/env.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,17 @@ export class EnvService {

return (this.replacements = replacements);
}

public replaceUrl(src: string): string {
let tgt = src;
const replacements = this.urlReplacements;

for (const [from, to] of replacements) {
tgt = tgt.replace(from, to);
}
if (tgt !== src) {
logger.debug({ src, tgt }, 'url replaced');
}
return tgt;
}
}
15 changes: 1 addition & 14 deletions src/cli/services/http.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class HttpService {

await mkdir(cachePath, { recursive: true });

const nUrl = this.replaceUrl(url);
const nUrl = this.envSvc.replaceUrl(url);

for (const run of [1, 2, 3]) {
try {
Expand Down Expand Up @@ -95,17 +95,4 @@ export class HttpService {
await rm(cachePath, { recursive: true });
throw new Error('download failed');
}

private replaceUrl(src: string): string {
let tgt = src;
const replacements = this.envSvc.urlReplacements;

for (const [from, to] of replacements) {
tgt = tgt.replace(from, to);
}
if (tgt !== src) {
logger.debug({ src, tgt }, 'url replaced');
}
return tgt;
}
}
2 changes: 1 addition & 1 deletion src/cli/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function cliMode(): CliMode | null {
if (argv0.endsWith('/prepare-tool') || argv0 === 'prepare-tool') {
return 'prepare-tool';
}
if (argv0.endsWith('/install-tool') || argv0 === 'install-tool') {
if (argv0.endsWith('/containerbase-cli') || argv0 === 'containerbase-cli') {
return 'containerbase-cli';
}

Expand Down
3 changes: 3 additions & 0 deletions src/usr/local/containerbase/util.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/bash

# https://github.com/vercel/pkg/issues/1861
unset PKG_EXECPATH

# get path location
DIR="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
Expand Down
4 changes: 2 additions & 2 deletions src/usr/local/containerbase/utils/cache.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function download_file () {
local temp_folder=${CONTAINERBASE_CACHE_DIR:-${TEMP_DIR}}
while [ "${retry}" -gt 0 ]; do
retry=$((retry-1))
if ! curl --retry 3 --create-dirs -sSfLo "${temp_folder}/${name}" "${url}" ; then
if ! containerbase-cli df "${url}" "${temp_folder}/${name}" >&2; then
echo "Download failed: ${url}" >&2
exit 1
fi;
Expand Down Expand Up @@ -119,7 +119,7 @@ function download_file () {
# First argument is the path to the file
# Second argument is the checksum
# Third argument is the type, currently supported:
# * sha1
# * sha1sum
# * sha224sum
# * sha256sum
# * sha384sum
Expand Down