Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions src/cli/services/link-tool.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import fs from 'node:fs/promises';
import { join } from 'node:path';
import { codeBlock } from 'common-tags';
import { bindingScopeValues, inject, injectable } from 'inversify';
import { pathExists, tool2path } from '../utils/index.ts';
import { fileContent, pathExists, tool2path } from '../utils/index.ts';
import { EnvService } from './env.service.ts';
import { PathService } from './path.service.ts';

Expand Down Expand Up @@ -59,7 +58,7 @@ export class LinkToolService {
: `${srcDir}/${name ?? tool}`;

const envs = [...(extraToolEnvs ?? []), tool].map(tool2path);
let content = codeBlock`
let content = fileContent`
#!/bin/bash

if [[ -z "\${CONTAINERBASE_ENV+x}" ]]; then
Expand All @@ -70,34 +69,29 @@ export class LinkToolService {
# set logging to only warn and above to not interfere with tool output
CONTAINERBASE_LOG_LEVEL=warn containerbase-cli init tool "${tool}"
fi
`;

// `envs` always holds at least the tool itself
content +=
'\n' +
codeBlock`
# load tool envs
include () {
local file=${this.pathSvc.toolsPath}/$1/env.sh
[[ -f "$file" ]] && source "$file"
}
`;
`;

// `envs` always holds at least the tool itself
for (const t of envs) {
content += `\ninclude ${t}`;
content += `include ${t}\n`;
}

content += `\nunset include`;
content += `unset include\n`;

if (exports) {
content += `\nexport ${exports}`;
content += `export ${exports}\n`;
}

if (body) {
content += `\n${body}`;
content += `${body}\n`;
}

content += `\n${src}`;
content += src;
if (args) {
content += ` ${args}`;
}
Expand Down
6 changes: 5 additions & 1 deletion src/cli/services/path.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,13 @@ export class PathService {
await fs.rm(file, { force: true });
}

/**
* Appends a block to the tool env, `content` should end with a newline, eg.
* by using the `fileContent` tag.
*/
async exportToolEnvContent(tool: string, content: string): Promise<void> {
const file = join(await this.ensureToolPath(tool), 'env.sh');
await fs.appendFile(file, `\n${content.trim()}\n`);
await fs.appendFile(file, `\n${content}`);
await this.setOwner({ path: file, mode: 0o644 });
}

Expand Down
2 changes: 1 addition & 1 deletion src/cli/tools/dotnet/mono.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe('cli/tools/dotnet/mono', () => {

const certSync = join(path, 'bin/cert-sync');
expect(await fs.readFile(certSync, 'utf8')).toBe(
`#!/bin/sh\n${path}/bin/mono ${path}/lib/mono/4.5/cert-sync.exe "$@"`,
`#!/bin/sh\n${path}/bin/mono ${path}/lib/mono/4.5/cert-sync.exe "$@"\n`,
);
expect(execaMock).toHaveBeenCalledWith(
certSync,
Expand Down
13 changes: 6 additions & 7 deletions src/cli/tools/dotnet/mono.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import fs from 'fs/promises';
import { join } from 'node:path';
import { codeBlock } from 'common-tags';
import { injectFromHierarchy, injectable } from 'inversify';
import { BasePrepareService } from '../../prepare-tool/base-prepare.service.ts';
import { logger, pathExists } from '../../utils/index.ts';
import { fileContent, logger, pathExists } from '../../utils/index.ts';
import {
PrebuildInstallService,
PrebuildVersionResolver,
Expand Down Expand Up @@ -32,7 +31,7 @@ export class MonoPrepareService extends BasePrepareService {
this.envSvc.rootDir,
'etc/ca-certificates/update.d/containerbase-mono-keystore',
),
codeBlock`
fileContent`
#!/bin/sh

set -e
Expand Down Expand Up @@ -80,10 +79,10 @@ export class MonoInstallService extends PrebuildInstallService {
if (!(await pathExists(join(path, 'bin/cert-sync')))) {
await fs.writeFile(
join(path, 'bin/cert-sync'),
codeBlock`
#!/bin/sh
${path}/bin/mono ${path}/lib/mono/4.5/cert-sync.exe "$@"
`,
fileContent`
#!/bin/sh
${path}/bin/mono ${path}/lib/mono/4.5/cert-sync.exe "$@"
`,
{
mode: this.envSvc.umask,
},
Expand Down
5 changes: 2 additions & 3 deletions src/cli/tools/git/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { readFile } from 'node:fs/promises';
import { codeBlock } from 'common-tags';
import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
import { getDistro } from '../../utils/index.ts';
import { fileContent, getDistro } from '../../utils/index.ts';
import { GitInstallService, GitPrepareService } from './index.ts';
import { scope } from '~test/http-mock.ts';
import { ensurePaths, rootPath } from '~test/path.ts';
Expand Down Expand Up @@ -53,7 +52,7 @@ describe('cli/tools/git/index', () => {
);
expect(
await readFile(rootPath('etc/apt/sources.list.d/git.sources'), 'utf8'),
).toBe(codeBlock`
).toBe(fileContent`
Types: deb
URIs: https://ppa.launchpadcontent.net/git-core/ppa/ubuntu
Suites: noble
Expand Down
10 changes: 7 additions & 3 deletions src/cli/tools/git/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { mkdir, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { codeBlock } from 'common-tags';
import { execa } from 'execa';
import { inject, injectFromHierarchy, injectable } from 'inversify';
import { BaseInstallService } from '../../install-tool/base-install.service.ts';
import { BasePrepareService } from '../../prepare-tool/base-prepare.service.ts';
import { AptService, HttpService } from '../../services/index.ts';
import { getDistro, semverCoerce, semverGte } from '../../utils/index.ts';
import {
fileContent,
getDistro,
semverCoerce,
semverGte,
} from '../../utils/index.ts';

/**
* Keep in sync with the minimum git version renovate needs.
Expand Down Expand Up @@ -41,7 +45,7 @@ export class GitPrepareService extends BasePrepareService {
await writeFile(join(this.envSvc.rootDir, keyPath), key, { mode: 0o644 });
await writeFile(
join(this.envSvc.rootDir, 'etc/apt/sources.list.d/git.sources'),
codeBlock`
fileContent`
Types: deb
URIs: https://ppa.launchpadcontent.net/git-core/ppa/ubuntu
Suites: ${distro.versionCode}
Expand Down
12 changes: 8 additions & 4 deletions src/cli/tools/java/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import path from 'node:path';
import { codeBlock } from 'common-tags';
import type { HttpService, PathService } from '../../services';
import { type Arch, logger, pathExists } from '../../utils/index.ts';
import {
type Arch,
fileContent,
logger,
pathExists,
} from '../../utils/index.ts';
import {
type AdoptiumPackage,
AdoptiumReleaseVersions,
Expand Down Expand Up @@ -58,7 +62,7 @@ export async function createMavenSettings(pathSvc: PathService): Promise<void> {
logger.debug('Creating Maven settings');
await pathSvc.writeFile(
file,
codeBlock`
fileContent`
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
Expand All @@ -84,7 +88,7 @@ export async function createGradleSettings(
logger.debug('Creating Gradle settings');
await pathSvc.writeFile(
file,
codeBlock`
fileContent`
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.daemon=false
Expand Down
5 changes: 2 additions & 3 deletions src/cli/tools/node/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import fs from 'node:fs/promises';
import { join } from 'node:path';
import { env as penv } from 'node:process';
import { codeBlock } from 'common-tags';
import { injectFromHierarchy, injectable } from 'inversify';
import { BasePrepareService } from '../../prepare-tool/base-prepare.service.ts';
import { getDistro, parse } from '../../utils/index.ts';
import { fileContent, getDistro, parse } from '../../utils/index.ts';
import {
NodeBaseInstallService,
prepareNpmCache,
Expand Down Expand Up @@ -37,7 +36,7 @@ export class NodePrepareService extends BasePrepareService {
// node v6.11.0
await this.pathSvc.exportToolEnvContent(
this.name,
codeBlock`
fileContent`
export NODE_OPTIONS="\${NODE_OPTIONS} --use-openssl-ca"
`,
);
Expand Down
5 changes: 2 additions & 3 deletions src/cli/tools/python/conan.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import fs from 'node:fs/promises';
import { join } from 'node:path';
import { codeBlock } from 'common-tags';
import { inject, injectFromHierarchy, injectable } from 'inversify';
import { BasePrepareService } from '../../prepare-tool/base-prepare.service.ts';
import { AptService } from '../../services/index.ts';
import { type Distro, getDistro } from '../../utils/index.ts';
import { type Distro, fileContent, getDistro } from '../../utils/index.ts';
import { PipVersionResolver } from './pip.ts';
import { PipBaseInstallService } from './utils.ts';

Expand All @@ -29,7 +28,7 @@ export class ConanPrepareService extends BasePrepareService {

override async initialize(): Promise<void> {
const distro = await getDistro();
const profile = codeBlock`
const profile = fileContent`
[settings]
arch=${getArchitecture(this.envSvc.arch)}
build_type=Release
Expand Down
1 change: 1 addition & 0 deletions src/cli/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './types.ts';
export * from './versions.ts';
export * from './logger.ts';
export * from './common.ts';
export * from './tags.ts';
export type {
Options as SpawnOptions,
Result as SpawnResult,
Expand Down
17 changes: 17 additions & 0 deletions src/cli/utils/tags.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { describe, expect, test } from 'vitest';
import { fileContent } from './tags.ts';

describe('cli/utils/tags', () => {
test('strips the indentation and keeps the trailing newline', () => {
const name = 'containerbase';

expect(fileContent`
Types: deb
Suites: ${name}
`).toBe('Types: deb\nSuites: containerbase\n');
});

test('works without a leading newline', () => {
expect(fileContent`Types: deb`).toBe('Types: deb\n');
});
});
26 changes: 26 additions & 0 deletions src/cli/utils/tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { TemplateTransformer } from 'common-tags';
import {
TemplateTag,
stripIndentTransformer,
trimResultTransformer,
} from 'common-tags';

const appendNewlineTransformer: TemplateTransformer = {
onEndResult: (endResult) => `${endResult}\n`,
};

/**
* Like `codeBlock` from common-tags, but ends with a newline.
*
* Every tag common-tags exports trims both ends of the result, which drops the
* newline a text file should end with. Use this one when the content is written
* to a file, and `codeBlock` when it is embedded into something else.
*
* `createTag` is only declared by the types, the installed common-tags does not
* export it, so the tag is composed with `TemplateTag` directly.
*/
export const fileContent = new TemplateTag(
stripIndentTransformer(),
trimResultTransformer(),
appendNewlineTransformer,
);
Loading