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

Bugfix 45 addons config #46

Merged
merged 7 commits into from
Jan 17, 2025
4 changes: 2 additions & 2 deletions packages/compiler/src/options.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("createOptions", () => {
);
});

it("should return expected path w/ custom addons directory", () => {
it("should return expected path w/ custom addons directory and '*' target", () => {
const { addons } = compileSystem({
files: {
"./expected/addon-foo/addon.js": "export const activate = () => {};",
Expand All @@ -54,7 +54,7 @@ describe("createOptions", () => {
{ virtual: true }
);

const actual = addons.refresh().getAvailableAddons();
const actual = addons.refresh().getAvailableAddons("*");

expect(actual.getNames()).toEqual(["addon-foo"]);
});
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const createOptions = (args: CompilerArguments, reporter = new NoReporter
const compilationConfig = resolveCompilationConfig(args.config ?? DEFAULTS.config, reporter, system);

const projectDirectory =
(compilationConfig && dirname(compilationConfig.configFilePath)) ??
(compilationConfig?.configFilePath && dirname(compilationConfig.configFilePath)) ??
(tsconfig.raw && tsconfig.raw.configFilePath && dirname(tsconfig.raw?.configFilePath));
tsconfig.options.outDir = args.buildDir ?? tsconfig.options.outDir ?? DEFAULTS.outDir;
if (projectDirectory) {
Expand Down
4 changes: 0 additions & 4 deletions packages/core/src/compiler/Compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,6 @@ export class Compiler {

public setOptions(options: CompilerOptions): this {
this.options = options;
if (!this.options?.targets || this.options.targets.length === 0) {
this.options.targets = ["*"];
}

this.reporter = options.reporter ?? new DefaultReporter(this.system);

this.compilationHost = new CompilationHost(createSharedHost(this.system) as ts.LanguageServiceHost);
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/compiler/CompilerOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ export interface CompilerOptions {
project: ts.CompilerOptions;
reporter: Reporter;
sourceMap: boolean;
/**
* List of targets to be compiled. Refers to the `targets` defined in the `config` property.
* Use `["*"]` to compile with all available addons. No addons will be used if no target is specified.
*/
targets: string[];
/**
* Whether to only transpile the code without emitting any output.
* Overrides the `transpileOnly` specified in the `tsconfig.json`.
* @deprecated use `config.transpileOnly` instead.
*/
transpileOnly: boolean;
watch: boolean;
additionalArguments?: Map<string, unknown>;
Expand Down
40 changes: 20 additions & 20 deletions packages/core/src/compiler/addons/AddonRegistry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ describe("getAvailableAddons", () => {
it("returns empty addons w/ empty addons directory", () => {
const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system });

expect(testObj.getAvailableAddons()).toHaveLength(0);
expect(testObj.getAvailableAddons("*")).toHaveLength(0);
});

it("returns addons w/ single addon in addon directory", () => {
createAddon("addons/expected/addon");

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);
});

it("returns addons w/ multiple addons in addon directory", () => {
Expand All @@ -58,7 +58,7 @@ describe("getAvailableAddons", () => {

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["one", "two", "three"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["one", "two", "three"]);
});

it("returns valid addons w/ invalid and valid addons in addon directory", () => {
Expand All @@ -67,15 +67,15 @@ describe("getAvailableAddons", () => {

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);
});

it("returns no addons w/ empty files in addon directory", () => {
createAddon("addons/empty/addon", "", {});

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons()).toHaveLength(0);
expect(testObj.getAvailableAddons("*")).toHaveLength(0);
});

it("reports warning w/ non-existing addons name", () => {
Expand All @@ -87,7 +87,7 @@ describe("getAvailableAddons", () => {
addonsDir: "./addons",
reporter,
system,
}).getAvailableAddons();
}).getAvailableAddons("*");

expect(reporter.reportDiagnostic).toHaveBeenCalledWith(new WarnMessage('Missing addons: "does-not-exist".'));
});
Expand Down Expand Up @@ -127,25 +127,25 @@ describe("refresh", () => {

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);

createAddon("addons/new/addon");

testObj.refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected", "new"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected", "new"]);
});

it("refreshes addons w/o new addons", () => {
createAddon("addons/expected/addon");

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);

testObj.refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);
});

it("refreshes addons w/ removed addons", () => {
Expand All @@ -154,27 +154,27 @@ describe("refresh", () => {

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected", "removed"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected", "removed"]);

removeAddon("addons/removed/addon");

testObj.refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);
});

it("refreshes addons w/ empty addons directory", () => {
createAddon("addons/expected/addon");

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);

removeAddon("addons/expected/addon");

testObj.refresh();

expect(testObj.getAvailableAddons()).toHaveLength(0);
expect(testObj.getAvailableAddons("*")).toHaveLength(0);
});
});

Expand Down Expand Up @@ -271,7 +271,7 @@ describe("reportMissingAddons", () => {
system.createDirectory("./target");
reporter.reportDiagnostic = jest.fn();

new AddonRegistry({ addonsDir: "./target", addons: ["missing"], reporter, system }).getAvailableAddons();
new AddonRegistry({ addonsDir: "./target", addons: ["missing"], reporter, system }).getAvailableAddons("*");

expect(reporter.reportDiagnostic).toHaveBeenCalledWith(new WarnMessage('Missing addons: "missing".'));
});
Expand All @@ -281,7 +281,7 @@ describe("reportMissingAddons", () => {
createAddon("target/expected/addon");
reporter.reportDiagnostic = jest.fn();

new AddonRegistry({ addonsDir: "./target", addons: ["expected"], reporter, system }).refresh().getAvailableAddons();
new AddonRegistry({ addonsDir: "./target", addons: ["expected"], reporter, system }).refresh().getAvailableAddons("*");

expect(reporter.reportDiagnostic).not.toHaveBeenCalled();
});
Expand Down Expand Up @@ -324,7 +324,7 @@ describe("findAddons", () => {

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);
});

it("finds addons w/ multiple addons in addons directory", () => {
Expand All @@ -334,7 +334,7 @@ describe("findAddons", () => {

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["one", "two", "three"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["one", "two", "three"]);
});

it("finds valid addons w/ invalid and valid addons in addons directory", () => {
Expand All @@ -343,15 +343,15 @@ describe("findAddons", () => {

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system }).refresh();

expect(testObj.getAvailableAddons().getNames()).toEqual(["expected"]);
expect(testObj.getAvailableAddons("*").getNames()).toEqual(["expected"]);
});

it("finds no addons w/ empty files in addons directory", () => {
createAddon("addons/empty/addon", "", {});

const testObj = new AddonRegistry({ addonsDir: "./addons", reporter, system });

expect(testObj.getAvailableAddons()).toHaveLength(0);
expect(testObj.getAvailableAddons("*")).toHaveLength(0);
});
});

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/compiler/addons/AddonRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ export class AddonRegistry {
this.reportMissingAddons(target);
const expectedNames = this.getExpectedAddons(target);
const results =
expectedNames.length > 0
? [...this.availableAddons].filter(([name]) => expectedNames.includes(name)).map(([, addon]) => addon)
: Array.from(this.availableAddons.values());
expectedNames.length === 0 && target === "*"
? Array.from(this.availableAddons.values())
: [...this.availableAddons].filter(([name]) => expectedNames.includes(name)).map(([, addon]) => addon);
return compilerAddons(results);
}

Expand Down
10 changes: 9 additions & 1 deletion packages/core/src/compiler/config/CompilationConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@
import type { TargetConfig } from "@quatico/websmith-api";

export type CompilationConfig = {
/** List of addons to be loaded. Overrides the `addons` specified in the configuration file. */
addons?: string[];
/** Relative path to the directory containing the addons. Overrides the `addonsDir` specified in the configuration file. */
addonsDir?: string;
configFilePath: string;
/** Relative path to the `websmith.config.json` configuration file. */
configFilePath?: string;
/** Record of target specific addons configurations. Overrides the `targets` specified in the configuration file. */
targets?: Record<string, TargetConfig>;
/**
* Whether to only transpile the code without emitting any output.
* Overrides the `transpileOnly` specified in the `tsconfig.json`.
*/
transpileOnly?: boolean;
};
2 changes: 1 addition & 1 deletion packages/core/test/compile-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const compileOptions = (
configFilePath: "./tsconfig.json",
...overrides?.project,
},
targets: overrides?.targets ?? [],
targets: overrides?.targets ?? ["*"],
tsconfig: {
options: {},
fileNames: system.readDirectory("./src"),
Expand Down
2 changes: 1 addition & 1 deletion packages/test/src/bar-addon.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe("test-project-foo", () => {
it("should install addon successfully", () => {
const testObj = compilationEnv("__TEST__").addAddon("foo-addon", join(__dirname, "../test-data/addons"));

const actual = testObj.getActiveAddons().getNames();
const actual = testObj.getActiveAddons("*").getNames();

expect(actual).toContain("foo-addon");
});
Expand Down
14 changes: 7 additions & 7 deletions packages/testing/src/compilation/environment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe("compilationEnv", () => {
target: ts.ScriptTarget.ESNext,
},
sourceMap: false,
targets: [],
targets: ["*"],
transpileOnly: false,
tsconfig: {
errors: [],
Expand Down Expand Up @@ -80,13 +80,13 @@ describe("compilationEnv#addons", () => {
const testObj = compilationEnv("/target");

expect(testObj.getAddonsDir()).toBe("/target/addons");
expect(testObj.getActiveAddons()).toHaveLength(0);
expect(testObj.getActiveAddons("*")).toHaveLength(0);
});

it("should yield addon with valid addon source", () => {
const testObj = compilationEnv("/target").addAddon("expected-addon", { "addon.ts": `export const activate = () => {};` });

const actual = testObj.getActiveAddons().getNames();
const actual = testObj.getActiveAddons("*").getNames();

expect(actual).toEqual(["expected-addon"]);
});
Expand All @@ -95,7 +95,7 @@ describe("compilationEnv#addons", () => {
console.warn = jest.fn();
const testObj = compilationEnv("/target").addAddon("invalid-addon", { "addon.ts": `export const NO_ACTIVATE_FUNCTION = true;` });

const actual = testObj.getActiveAddons();
const actual = testObj.getActiveAddons("*").getNames();

expect(actual).toHaveLength(0);
});
Expand All @@ -106,7 +106,7 @@ describe("compilationEnv#addons", () => {

testObj.addAddon("expected-addon");

const actual = testObj.getActiveAddons().getNames();
const actual = testObj.getActiveAddons("*").getNames();

expect(actual).toEqual(["expected-addon"]);
});
Expand All @@ -118,7 +118,7 @@ describe("compilationEnv#addons", () => {

testObj.addAddons(["expected-addon1", "expected-addon2"]);

const actual = testObj.getActiveAddons().getNames();
const actual = testObj.getActiveAddons("*").getNames();

expect(actual).toEqual(["expected-addon1", "expected-addon2"]);
});
Expand All @@ -130,7 +130,7 @@ describe("compilationEnv#addons", () => {

testObj.addAddons(["expected-addon1", "expected-addon2"], "./custom-addons-folder/");

const actual = testObj.getActiveAddons().getNames();
const actual = testObj.getActiveAddons("*").getNames();

expect(actual).toEqual(["expected-addon1", "expected-addon2"]);
});
Expand Down
6 changes: 4 additions & 2 deletions packages/testing/src/compilation/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class CompilationEnv {

this.compilerOptions = compileOptions(this.system, {
buildDir: this.buildDir,
targets: options?.compilerOptions?.targets?.length ? options.compilerOptions.targets : ["*"],
config: {
configFilePath: `${this.rootDir}/websmith.config.json`,
targets: {
Expand Down Expand Up @@ -144,8 +145,8 @@ export class CompilationEnv {
return this.addons?.getAvailableAddons().find((it: CompilerAddon) => it.getName() === addonName);
}

public getActiveAddons(): CompilerAddons {
return this.addons?.getAvailableAddons() ?? compilerAddons([]);
public getActiveAddons(target?: string): CompilerAddons {
return this.addons?.getAvailableAddons(target) ?? compilerAddons([]);
}

/**
Expand Down Expand Up @@ -330,6 +331,7 @@ export class CompilationEnv {
esModuleInterop: true,
moduleResolution: ts.ModuleResolutionKind.NodeNext,
},
targets: ["*"],
tsconfig: { fileNames: this.system.readDirectory(curDir).filter(isSourceFile), options: {}, errors: [] },
},
this.system
Expand Down
8 changes: 4 additions & 4 deletions packages/webpack-test/src/compile-module-date.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { readdirSync, readFileSync, rmSync } from "fs";
import { resolve } from "path";
import { Configuration, NormalModule } from "webpack";
import { createWebpackCompiler } from "./webpack-utils";
import { webpackBuild } from "./webpack-utils";

describe("project bundling", () => {
const projectDir = resolve(__dirname, "../__data__/module-test");
Expand All @@ -24,7 +24,7 @@ describe("project bundling", () => {
});

it("yields modules", async () => {
const { stats, compiler } = await createWebpackCompiler(config, projectDir);
const { stats, compiler } = await webpackBuild(config, projectDir);

expect(
Array.from(stats!.compilation.modules.values())
Expand All @@ -36,15 +36,15 @@ describe("project bundling", () => {
});

it("yields chunks", async () => {
const { stats, compiler } = await createWebpackCompiler(config, projectDir);
const { stats, compiler } = await webpackBuild(config, projectDir);

expect(Array.from(stats!.compilation.chunks.values()).map(cur => cur.name)).toEqual(expect.arrayContaining(["functions", "main"]));

compiler.close(() => undefined);
});

it("yields bundled output", async () => {
const { compiler } = await createWebpackCompiler(config, projectDir);
const { compiler } = await webpackBuild(config, projectDir);

expect(readdirSync(resolve(__dirname, "../__data__/module-test/.build/lib"))).toEqual([
"functions.js",
Expand Down
Loading
Loading