Skip to content

Commit

Permalink
feat: do not produce empty deps.json and tasks.json files (#462)
Browse files Browse the repository at this point in the history
To support this, if `FileBase.synthesizeContent()` returns `undefined`, the file write is skipped.

---
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
  • Loading branch information
Elad Ben-Israel authored Jan 6, 2021
1 parent 5c6ab90 commit 7a079ea
Show file tree
Hide file tree
Showing 18 changed files with 77 additions and 30 deletions.
2 changes: 2 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -6226,6 +6226,7 @@ resolve(value: any, options?: ResolveOptions): any

* **value** (<code>any</code>) The value to resolve.
* **options** (<code>[ResolveOptions](#projen-resolveoptions)</code>) *No description*
* **args** (<code>Array<any></code>) Context arguments. __*Default*__: []
* **omitEmpty** (<code>boolean</code>) Omits empty arrays and objects. __*Default*__: false

__Returns__:
Expand Down Expand Up @@ -6747,6 +6748,7 @@ Resolve options.

Name | Type | Description
-----|------|-------------
**args**?🔹 | <code>Array<any></code> | Context arguments.<br/>__*Default*__: []
**omitEmpty**?🔹 | <code>boolean</code> | Omits empty arrays and objects.<br/>__*Default*__: false


Expand Down
3 changes: 0 additions & 3 deletions src/__tests__/__snapshots__/cli.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ Object {
node_modules/
!/.projen/tasks.json
!/.projen/deps.json",
".projen/deps.json": Object {
"//": "~~ Generated by projen. To modify, edit .projenrc.js and run \\"npx projen\\".",
},
".projen/tasks.json": Object {
"//": "~~ Generated by projen. To modify, edit .projenrc.js and run \\"npx projen\\".",
"tasks": Object {
Expand Down
12 changes: 6 additions & 6 deletions src/__tests__/deps.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { join } from 'path';
import { readFileSync } from 'fs-extra';
import { existsSync, readFileSync } from 'fs-extra';
import { Project } from '..';
import { Dependencies, DependencyType } from '../deps';
import { TestProject } from './util';

test('no dependencieds, empty manifest', () => {
test('no dependencieds, no manifest', () => {
// GIVEN
const p = new TestProject();

// THEN
expect(depsManifest(p)).toStrictEqual({
'//': '~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".',
});
expect(depsManifest(p)).toBeUndefined();
});

test('minimal case', () => {
Expand Down Expand Up @@ -205,5 +203,7 @@ describe('getDependency()', () => {

function depsManifest(p: Project) {
p.synth();
return JSON.parse(readFileSync(join(p.outdir, Dependencies.MANIFEST_FILE), 'utf-8'));
const filepath = join(p.outdir, Dependencies.MANIFEST_FILE);
if (!existsSync(filepath)) { return undefined; }
return JSON.parse(readFileSync(filepath, 'utf-8'));
}
19 changes: 18 additions & 1 deletion src/__tests__/dev-env.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ describe('dev environment enable/disable', () => {
expect(fs.existsSync(devContainerFilePath)).toBeFalsy();
});

test('no gitpod/devcontainer files if they are empty', () => {
// WHEN
const project = new TestProject({
gitpod: true,
devContainer: true,
});

// THEN
project.synth();
const gitpodFilePath = path.join(project.outdir, GITPOD_FILE);
const devContainerFilePath = path.join(project.outdir, DEVCONTAINER_FILE);
expect(fs.existsSync(gitpodFilePath)).toBeFalsy();
expect(fs.existsSync(devContainerFilePath)).toBeFalsy();
});

test('given gitpod and devContainer are true', () => {
// GIVEN
const project = new TestProject({
Expand All @@ -37,9 +52,11 @@ describe('dev environment enable/disable', () => {
});

// WHEN
project.synth();
project.gitpod?.addDockerImage({ image: 'foo' });
project.devContainer?.addPorts('1234');

// THEN
project.synth();
const gitpodFilePath = path.join(project.outdir, GITPOD_FILE);
const devContainerFilePath = path.join(project.outdir, DEVCONTAINER_FILE);
expect(fs.existsSync(gitpodFilePath)).toBeTruthy();
Expand Down
12 changes: 10 additions & 2 deletions src/__tests__/tasks/tasks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { Project } from '../..';
import { Task, Tasks, TasksManifest, TaskStep } from '../../tasks';
import { TestProject, synthSnapshot } from '../util';

test('no tasks, no tasks file', () => {
const p = new TestProject();
expect(synthTasksManifest(p)).toBeUndefined();
});

test('empty task', () => {
const p = new TestProject();

Expand Down Expand Up @@ -349,8 +354,11 @@ function shell(t: Task, env: { [k: string]: string } = {}) {
}

function expectManifest(p: Project, toStrictEqual: TasksManifest) {
const manifest = synthSnapshot(p)[Tasks.MANIFEST_FILE];
const manifest = synthTasksManifest(p);
delete manifest['//'];

expect(manifest).toStrictEqual(toStrictEqual);
}

function synthTasksManifest(p: Project) {
return synthSnapshot(p)[Tasks.MANIFEST_FILE];;
}
3 changes: 2 additions & 1 deletion src/deps/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ export class Dependencies extends Component {
return this._deps.findIndex(dep => dep.name === name && dep.type === type);
}

private toJson(): DepsManifest {
private toJson(): DepsManifest | undefined {
if (this._deps.length === 0) { return undefined; }
return {
dependencies: this._deps.sort(compareDeps),
};
Expand Down
15 changes: 13 additions & 2 deletions src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ export abstract class FileBase extends Component {
* emit.
* @param resolver Call `resolver.resolve(obj)` on any objects in order to
* resolve token functions.
* @returns the content to synthesize or undefined to skip the file
*/
protected abstract synthesizeContent(resolver: IResolver): string;
protected abstract synthesizeContent(resolver: IResolver): string | undefined;

/**
* Writes the file to the project's output directory
Expand All @@ -109,7 +110,11 @@ export abstract class FileBase extends Component {
const outdir = this.project.outdir;
const filePath = path.join(outdir, this.path);
const resolver: IResolver = { resolve: (obj, options) => resolve(obj, [outdir], options) };
writeFile(filePath, this.synthesizeContent(resolver), {
const content = this.synthesizeContent(resolver);
if (content === undefined) {
return; // skip
}
writeFile(filePath, content, {
readonly: this.readonly,
executable: this.executable,
});
Expand Down Expand Up @@ -138,4 +143,10 @@ export interface ResolveOptions {
* @default false
*/
readonly omitEmpty?: boolean;

/**
* Context arguments.
* @default []
*/
readonly args?: any[];
}
2 changes: 1 addition & 1 deletion src/github/workflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class GithubWorkflow extends FileBase {
};
}

protected synthesizeContent(resolver: IResolver) {
protected synthesizeContent(resolver: IResolver): string | undefined {
const workflow = resolver.resolve({
name: this.name,
on: this.events,
Expand Down
2 changes: 1 addition & 1 deletion src/ignore-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class IgnoreFile extends FileBase {
patterns.forEach(pattern => this.patterns[pattern.replace(/^\!/, '')] = IgnorePatternType.INCLUDE);
}

protected synthesizeContent(resolver: IResolver): string {
protected synthesizeContent(resolver: IResolver): string | undefined {
return resolver.resolve([
`# ${FileBase.PROJEN_MARKER}`,
...Object.entries(this.patterns).map(([pattern, type]) => type === IgnorePatternType.INCLUDE ? `!${pattern}`: pattern),
Expand Down
10 changes: 8 additions & 2 deletions src/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@ export class JsonFile extends ObjectFile implements IMarkableFile {
this.marker = options.marker ?? false;
}

protected synthesizeContent(resolver: IResolver) {
protected synthesizeContent(resolver: IResolver): string | undefined {
const json = super.synthesizeContent(resolver);

if (!json) {
return undefined;
}

// sanitize object references by serializing and deserializing to JSON
const sanitized = JSON.parse(super.synthesizeContent(resolver));
const sanitized = JSON.parse(json);

if (this.marker) {
sanitized['//'] = JsonFile.PROJEN_MARKER;
Expand Down
2 changes: 1 addition & 1 deletion src/license.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class License extends FileBase {
.replace('[name of copyright owner]', owner);
}

protected synthesizeContent(_: IResolver) {
protected synthesizeContent(_: IResolver): string | undefined {
return this.text;
}
}
2 changes: 1 addition & 1 deletion src/makefile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export class Makefile extends FileBase {
}
}

protected synthesizeContent(resolver: IResolver) {
protected synthesizeContent(resolver: IResolver): string | undefined {
const rules = resolver.resolve(this.rules);

const lines = [
Expand Down
6 changes: 3 additions & 3 deletions src/object-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ export abstract class ObjectFile extends FileBase {
this.omitEmpty = options.omitEmpty ?? false;
}

protected synthesizeContent(resolver: IResolver) {
protected synthesizeContent(resolver: IResolver): string | undefined {
const obj = this.obj;

const resolved = resolver.resolve(obj, {
omitEmpty: this.omitEmpty,
}) ?? {};
}) ?? undefined;

return JSON.stringify(resolved, undefined, 2);
return resolved ? JSON.stringify(resolved, undefined, 2) : undefined;
}
}
2 changes: 1 addition & 1 deletion src/textfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class TextFile extends FileBase {
this.lines.push(line);
}

protected synthesizeContent(_: IResolver): string {
protected synthesizeContent(_: IResolver): string | undefined {
return this.lines.join('\n');
}
}
2 changes: 1 addition & 1 deletion src/toml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class TomlFile extends ObjectFile implements IMarkableFile {
this.marker = options.marker ?? false;
}

protected synthesizeContent(resolver: IResolver) {
protected synthesizeContent(resolver: IResolver): string | undefined {
return [
... (this.marker ? [`# ${TomlFile.PROJEN_MARKER}`] : []),
'',
Expand Down
2 changes: 1 addition & 1 deletion src/web/next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export class NextJsTypeDef extends FileBase {
super(project, filePath, options);
}

protected synthesizeContent(_: IResolver) {
protected synthesizeContent(_: IResolver): string | undefined {
return [
'/// <reference types="next" />',
'/// <reference types="next/types/global" />',
Expand Down
2 changes: 1 addition & 1 deletion src/web/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ export class ReactTypeDef extends FileBase {
super(project, filePath, options);
}

protected synthesizeContent(_: IResolver) {
protected synthesizeContent(_: IResolver): string | undefined {
return [
'/// <reference types="react-scripts" />',
].join('\n');
Expand Down
9 changes: 7 additions & 2 deletions src/yaml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ export class YamlFile extends ObjectFile implements IMarkableFile {
this.marker = options.marker ?? false;
}

protected synthesizeContent(resolver: IResolver) {
protected synthesizeContent(resolver: IResolver): string | undefined {
const json = super.synthesizeContent(resolver);
if (!json) {
return undefined;
}

// sanitize object references by serializing and deserializing to JSON
const sanitized = JSON.parse(super.synthesizeContent(resolver));
const sanitized = JSON.parse(json);
return [
... (this.marker ? [`# ${YamlFile.PROJEN_MARKER}`] : []),
'',
Expand Down

0 comments on commit 7a079ea

Please sign in to comment.