Skip to content

Commit e28cbc6

Browse files
authored
Merge pull request #9 from typed-ember/environments
Introduce environments
2 parents 470a2b5 + ff9a216 commit e28cbc6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+1002
-666
lines changed

.eslintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
],
1010
"rules": {
1111
"prefer-const": "off",
12+
"require-yield": "off",
1213
"@typescript-eslint/prefer-const": "off",
1314
"@typescript-eslint/no-empty-function": "off",
1415
"@typescript-eslint/no-empty-interface": "off",

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
yarn-error.log
3+
test-packages/ephemeral

packages/cli/__tests__/check.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ describe('single-pass typechecking', () => {
129129
`;
130130

131131
project.write('index.ts', code);
132-
project.write('.glintrc', 'exclude: "index.ts"\n');
132+
project.write('.glintrc', 'environment: glimmerx\nexclude: "index.ts"\n');
133133

134134
let checkResult = await project.check();
135135

packages/cli/__tests__/declaration.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ describe('emitting declarations', () => {
1313

1414
test('emit for a valid project', async () => {
1515
let code = stripIndent`
16-
import '@glint/template/glimmerx';
1716
import Component, { hbs } from '@glimmerx/component';
1817
1918
export interface ApplicationArgs {
@@ -37,8 +36,7 @@ describe('emitting declarations', () => {
3736
expect(emitResult.exitCode).toBe(0);
3837

3938
expect(project.read('index.d.ts')).toMatchInlineSnapshot(`
40-
"import '@glint/template/glimmerx';
41-
import Component from '@glimmerx/component';
39+
"import Component from '@glimmerx/component';
4240
export interface ApplicationArgs {
4341
version: string;
4442
}

packages/cli/__tests__/utils/project.ts

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import path from 'path';
2-
import os from 'os';
32
import fs from 'fs';
43
import execa, { ExecaChildProcess, Options } from 'execa';
54

5+
const ROOT = path.resolve(__dirname, '../../../../test-packages/ephemeral');
6+
67
export default class Project {
7-
private rootDir = path.join(os.tmpdir(), Math.random().toString(16).slice(2));
8+
private rootDir = path.join(ROOT, Math.random().toString(16).slice(2));
89

910
private constructor() {}
1011

@@ -18,7 +19,6 @@ export default class Project {
1819
let project = new Project();
1920
let tsconfig = {
2021
compilerOptions: {
21-
plugins: [{ name: path.resolve(__dirname, '../lib') }],
2222
strict: true,
2323
target: 'es2019',
2424
module: 'es2015',
@@ -29,17 +29,14 @@ export default class Project {
2929
};
3030

3131
fs.rmdirSync(project.rootDir, { recursive: true });
32-
fs.mkdirSync(project.rootDir);
32+
fs.mkdirSync(project.rootDir, { recursive: true });
3333

34+
fs.writeFileSync(path.join(project.rootDir, 'package.json'), '{}');
35+
fs.writeFileSync(path.join(project.rootDir, '.glintrc'), 'environment: glimmerx\n');
3436
fs.writeFileSync(
3537
path.join(project.rootDir, 'tsconfig.json'),
3638
JSON.stringify(tsconfig, null, 2)
3739
);
38-
fs.writeFileSync(path.join(project.rootDir, 'package.json'), '{}');
39-
40-
project.linkPackage('@glint/template');
41-
project.linkPackage('@glimmerx/component');
42-
project.linkPackage('typescript');
4340

4441
return project;
4542
}
@@ -66,14 +63,6 @@ export default class Project {
6663
public watch(options?: Options): Watch {
6764
return new Watch(this.check({ ...options, flags: ['--watch'], reject: false }));
6865
}
69-
70-
private linkPackage(name: string): void {
71-
let linkPath = path.join(this.rootDir, 'node_modules', name);
72-
let linkTarget = path.dirname(require.resolve(`${name}/package.json`));
73-
74-
fs.mkdirSync(path.dirname(linkPath), { recursive: true });
75-
fs.symlinkSync(linkTarget, linkPath, 'dir');
76-
}
7766
}
7867

7968
class Watch {

packages/cli/src/perform-check.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ function collectDiagnostics(
3636
...program.getSyntacticDiagnostics(),
3737
...transformManager.getTransformDiagnostics(),
3838
...program.getSemanticDiagnostics(),
39+
...program.getDeclarationDiagnostics(),
3940
];
4041
}
4142

packages/cli/src/transform-manager.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,16 @@ export default class TransformManager {
3636

3737
public readFile(filename: string, encoding?: string): string | undefined {
3838
let source = this.ts.sys.readFile(filename, encoding);
39+
let config = this.glintConfig;
3940

40-
// TODO: don't hard-code the relevant import we're interested in
4141
if (
42+
source &&
4243
filename.endsWith('.ts') &&
4344
!filename.endsWith('.d.ts') &&
44-
source?.includes('@glimmerx/component') &&
45-
this.glintConfig.includesFile(filename)
45+
config.includesFile(filename) &&
46+
config.environment.moduleMayHaveTagImports(source)
4647
) {
47-
let transformedModule = rewriteModule(filename, source);
48+
let transformedModule = rewriteModule(filename, source, config.environment);
4849
if (transformedModule) {
4950
this.transformedModules.set(filename, transformedModule);
5051
return transformedModule.transformedSource;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { GlintEnvironment } from '../src';
2+
3+
describe('Environments', () => {
4+
describe('moduleMayHaveTagImports', () => {
5+
test('locating a single tag', () => {
6+
let env = new GlintEnvironment({
7+
tags: {
8+
'my-cool-environment': { hbs: { typesSource: 'whatever' } },
9+
},
10+
});
11+
12+
expect(env.moduleMayHaveTagImports('import foo from "my-cool-environment"\n')).toBe(true);
13+
});
14+
15+
test('locating one of several tags', () => {
16+
let env = new GlintEnvironment({
17+
tags: {
18+
'my-cool-environment': { hbs: { typesSource: 'whatever' } },
19+
'another-env': { tagMe: { typesSource: 'over-here' } },
20+
'and-this-one': { hbs: { typesSource: '✨' } },
21+
},
22+
});
23+
24+
expect(env.moduleMayHaveTagImports('import foo from "another-env"\n')).toBe(true);
25+
});
26+
27+
test('checking a definitely-unused module', () => {
28+
let env = new GlintEnvironment({
29+
tags: {
30+
'my-cool-environment': { hbs: { typesSource: 'whatever' } },
31+
},
32+
});
33+
34+
expect(env.moduleMayHaveTagImports('import { hbs } from "another-env"\n')).toBe(false);
35+
});
36+
});
37+
38+
describe('getConfiguredTemplateTags', () => {
39+
test('returns the given tag config', () => {
40+
let tags = {
41+
'@glimmerx/component': { hbs: { typesSource: '@glint/environment-glimmerx/types' } },
42+
};
43+
44+
let env = new GlintEnvironment({ tags });
45+
46+
expect(env.getConfiguredTemplateTags()).toBe(tags);
47+
});
48+
});
49+
});

packages/config/__tests__/include-exclude.test.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import path from 'path';
21
import { GlintConfig } from '../src';
32

43
describe('include/exclude configuration', () => {
5-
const root = path.resolve('/foo/bar');
4+
const root = process.cwd();
5+
const environment = 'glimmerx';
66

77
describe('defaults', () => {
8-
const config = new GlintConfig(root, {});
8+
const config = new GlintConfig(root, { environment });
99

1010
test('includes all .ts files within the root', () => {
1111
expect(config.includesFile(`${root}/file.ts`)).toBe(true);
@@ -30,34 +30,38 @@ describe('include/exclude configuration', () => {
3030

3131
describe('custom configuration', () => {
3232
test('include glob', () => {
33-
let config = new GlintConfig(root, { include: 'src/**/*.txt' });
33+
let config = new GlintConfig(root, { environment, include: 'src/**/*.txt' });
3434
expect(config.includesFile(`${root}/src/file.txt`)).toBe(true);
3535
expect(config.includesFile(`${root}/file.txt`)).toBe(false);
3636
expect(config.includesFile(`${root}/src/index.ts`)).toBe(false);
3737
});
3838

3939
test('include array', () => {
40-
let config = new GlintConfig(root, { include: ['**/*.txt', '**/*.ts'] });
40+
let config = new GlintConfig(root, { environment, include: ['**/*.txt', '**/*.ts'] });
4141
expect(config.includesFile(`${root}/hello/there.txt`)).toBe(true);
4242
expect(config.includesFile(`${root}/index.ts`)).toBe(true);
4343
expect(config.includesFile(`${root}/file.js`)).toBe(false);
4444
});
4545

4646
test('exclude glob', () => {
47-
let config = new GlintConfig(root, { exclude: 'dist/**/*.ts' });
47+
let config = new GlintConfig(root, { environment, exclude: 'dist/**/*.ts' });
4848
expect(config.includesFile(`${root}/dist/file.ts`)).toBe(false);
4949
expect(config.includesFile(`${root}/file.ts`)).toBe(true);
5050
});
5151

5252
test('exclude array', () => {
53-
let config = new GlintConfig(root, { exclude: ['dist/**/*.ts', 'vendor/**/*.ts'] });
53+
let config = new GlintConfig(root, {
54+
environment,
55+
exclude: ['dist/**/*.ts', 'vendor/**/*.ts'],
56+
});
5457
expect(config.includesFile(`${root}/dist/file.ts`)).toBe(false);
5558
expect(config.includesFile(`${root}/vendor/file.ts`)).toBe(false);
5659
expect(config.includesFile(`${root}/file.ts`)).toBe(true);
5760
});
5861

5962
test('excludes override includes', () => {
6063
let config = new GlintConfig(root, {
64+
environment,
6165
include: 'src/**/*.ts',
6266
exclude: 'src/**/*.generated.ts',
6367
});

packages/config/__tests__/load-config.test.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,40 @@
11
import os from 'os';
22
import fs from 'fs';
3-
import { loadConfig, normalizePath } from '../src';
3+
import { loadConfig } from '../src';
4+
import { normalizePath } from '../src/config';
45

56
describe('loadConfig', () => {
67
const testDir = `${os.tmpdir()}/glint-config-test-${process.pid}`;
78

89
beforeEach(() => {
910
fs.rmdirSync(testDir, { recursive: true });
1011
fs.mkdirSync(testDir);
12+
fs.writeFileSync(
13+
`${testDir}/local-env.js`,
14+
`module.exports = () => ({ tags: { test: true } });\n`
15+
);
1116
});
1217

1318
afterEach(() => {
1419
fs.rmdirSync(testDir, { recursive: true });
1520
});
1621

17-
test('returns a default config if none is found', () => {
18-
let config = loadConfig(testDir);
19-
20-
expect(config.rootDir).toBe(normalizePath(testDir));
21-
expect(config.includesFile(`${testDir}/index.ts`)).toBe(true);
22-
expect(config.includesFile(__filename)).toBe(false);
22+
test('throws an error if no config is found', () => {
23+
expect(() => loadConfig(testDir)).toThrow(`Unable to find Glint configuration for ${testDir}`);
2324
});
2425

2526
test('locating config in a parent directory', () => {
2627
fs.mkdirSync(`${testDir}/deeply/nested/directory`, { recursive: true });
27-
fs.writeFileSync(`${testDir}/.glintrc`, `include: '**/*.root.ts'`);
28-
fs.writeFileSync(`${testDir}/deeply/.glintrc`, `include: '**/*.nested.ts'`);
28+
fs.writeFileSync(`${testDir}/.glintrc`, `environment: kaboom\ninclude: '**/*.root.ts'`);
29+
fs.writeFileSync(
30+
`${testDir}/deeply/.glintrc`,
31+
`environment: '../local-env'\ninclude: '**/*.nested.ts'`
32+
);
2933

3034
let config = loadConfig(`${testDir}/deeply/nested/directory`);
3135

3236
expect(config.rootDir).toBe(normalizePath(`${testDir}/deeply`));
37+
expect(config.environment.getConfiguredTemplateTags()).toEqual({ test: true });
3338
expect(config.includesFile(`${testDir}/deeply/index.ts`)).toBe(false);
3439
expect(config.includesFile(`${testDir}/deeply/index.root.ts`)).toBe(false);
3540
expect(config.includesFile(`${testDir}/deeply/index.nested.ts`)).toBe(true);
@@ -47,43 +52,54 @@ describe('loadConfig', () => {
4752
name: 'my-package',
4853
private: true,
4954
glint: {
55+
environment: './local-env',
5056
include: '**/*.from-pkg.ts',
5157
},
5258
})
5359
);
5460

5561
let config = loadConfig(testDir);
5662

63+
expect(config.environment.getConfiguredTemplateTags()).toEqual({ test: true });
5764
expect(config.includesFile(`${testDir}/index.ts`)).toBe(false);
5865
expect(config.includesFile(`${testDir}/index.from-pkg.ts`)).toBe(true);
5966
});
6067

6168
test('reads config from .glintrc', () => {
62-
fs.writeFileSync(`${testDir}/.glintrc`, `include: '**/*.extensionless.ts'`);
69+
fs.writeFileSync(
70+
`${testDir}/.glintrc`,
71+
`environment: './local-env'\ninclude: '**/*.extensionless.ts'`
72+
);
6373

6474
let config = loadConfig(testDir);
6575

76+
expect(config.environment.getConfiguredTemplateTags()).toEqual({ test: true });
6677
expect(config.includesFile(`${testDir}/index.ts`)).toBe(false);
6778
expect(config.includesFile(`${testDir}/index.extensionless.ts`)).toBe(true);
6879
});
6980

7081
test('reads config from .glintrc.js', () => {
71-
fs.writeFileSync(`${testDir}/.glintrc.js`, `module.exports = { include: '**/*.jsrc.ts' };`);
82+
fs.writeFileSync(
83+
`${testDir}/.glintrc.js`,
84+
`module.exports = { environment: "./local-env", include: '**/*.jsrc.ts' };`
85+
);
7286

7387
let config = loadConfig(testDir);
7488

89+
expect(config.environment.getConfiguredTemplateTags()).toEqual({ test: true });
7590
expect(config.includesFile(`${testDir}/index.ts`)).toBe(false);
7691
expect(config.includesFile(`${testDir}/index.jsrc.ts`)).toBe(true);
7792
});
7893

7994
test('reads config from glint.config.js', () => {
8095
fs.writeFileSync(
8196
`${testDir}/glint.config.js`,
82-
`module.exports = { include: '**/*.config.ts' };`
97+
`module.exports = { environment: './local-env', include: '**/*.config.ts' };`
8398
);
8499

85100
let config = loadConfig(testDir);
86101

102+
expect(config.environment.getConfiguredTemplateTags()).toEqual({ test: true });
87103
expect(config.includesFile(`${testDir}/index.ts`)).toBe(false);
88104
expect(config.includesFile(`${testDir}/index.config.ts`)).toBe(true);
89105
});

packages/config/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@
1919
},
2020
"dependencies": {
2121
"cosmiconfig": "^6.0.0",
22-
"minimatch": "^3.0.4"
22+
"escape-string-regexp": "^4.0.0",
23+
"minimatch": "^3.0.4",
24+
"resolve": "^1.17.0"
2325
},
2426
"devDependencies": {
25-
"@types/minimatch": "^3.0.3",
2627
"@types/jest": "^25.2.1",
28+
"@types/minimatch": "^3.0.3",
29+
"@types/resolve": "^1.17.1",
2730
"jest": "^25.4.0",
2831
"ts-jest": "^25.4.0"
2932
}

0 commit comments

Comments
 (0)