Skip to content
This repository has been archived by the owner on Jan 5, 2022. It is now read-only.

Commit

Permalink
refactor init logic into its own class
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamie Lynch committed Feb 1, 2021
1 parent ddf8150 commit 00384af
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 58 deletions.
63 changes: 5 additions & 58 deletions src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
import {
copyFileSync,
existsSync,
lstatSync,
mkdirSync,
readdirSync,
} from "fs";
import { join } from "path";
import { Command, flags } from "@oclif/command";
import { checkDirectoryIsEmpty } from "../utils/args";
import { buildDirectory } from "../utils/init";
import type { InitConfig } from "../utils/init";

interface InitCommandConfig {
outputDir: string;
}

interface InitCommandArgs {
export interface InitCommandArgs {
output: string;
}

Expand All @@ -37,67 +26,25 @@ export class InitCommand extends Command {
},
];

static getConfig = ({
args,
}: {
args: InitCommandArgs;
}): InitCommandConfig => {
static getConfig = ({ args }: { args: InitCommandArgs }): InitConfig => {
const config = {
outputDir: args.output,
};

InitCommand.validateConfig(config);

return config;
};

static validateConfig = (config: InitCommandConfig): void => {
checkDirectoryIsEmpty(config.outputDir);
};

templateDir = `${__dirname}/../template`;

// eslint-disable-next-line @typescript-eslint/require-await -- The Command class requires Promise<any> but we don't do anything async here
async run(): Promise<void> {
this.log("Starting CDK generator");

const config = InitCommand.getConfig(this.parse(InitCommand));

if (!existsSync(config.outputDir)) {
this.log(`Creating ${config.outputDir}`);
mkdirSync(config.outputDir);
}

this.log("Copying template files");
// TODO: Replace any params in files with .template extensions
this.copyFiles(this.templateDir, config.outputDir);
buildDirectory(config, this);

this.log("Success!");
// TODO: Can we do this here?
this.log("Run ./script/setup to get started");
this.log(
"To migrate existing stacks into your new directory you can run cdk-cli migrate"
);
this.log("To create a new stack run cdk-cli new");
}

copyFiles(sourcePath: string, targetPath: string): void {
for (const file of readdirSync(sourcePath)) {
const path = join(sourcePath, file);

if (path.endsWith(".ignore")) {
continue;
} else if (lstatSync(path).isDirectory()) {
const nestedTargetPath = join(targetPath, file);
if (!existsSync(nestedTargetPath)) {
mkdirSync(nestedTargetPath);
}
this.copyFiles(path, nestedTargetPath);
} else if (path.endsWith(".template")) {
copyFileSync(path, join(targetPath, file.replace(".template", "")));
} else {
copyFileSync(path, join(targetPath, file));
}
}
}
}
17 changes: 17 additions & 0 deletions src/utils/init.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ProjectBuilder } from "./init";

describe("The ProjectBuilder class", () => {
describe("validateConfig function", () => {
test("throws an error if the directory is not empty", () => {
expect(() =>
ProjectBuilder.validateConfig({ outputDir: "./src" })
).toThrow();
});

test("does not throw an error if the directory is empty", () => {
expect(() =>
ProjectBuilder.validateConfig({ outputDir: "./src/empty" })
).not.toThrow();
});
});
});
73 changes: 73 additions & 0 deletions src/utils/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
copyFileSync,
existsSync,
lstatSync,
mkdirSync,
readdirSync,
} from "fs";
import { join } from "path";
import type Command from "@oclif/command";
import { checkDirectoryIsEmpty } from "../utils/args";

export interface InitConfig {
outputDir: string;
}

// TODO: Add yarn or npm flag
// TODO: Add project name flag
export class ProjectBuilder {
templateDir = `${__dirname}/../template`;
config: InitConfig;
command: Command;

static validateConfig = (config: InitConfig): void => {
checkDirectoryIsEmpty(config.outputDir);
};

constructor(config: InitConfig, command: Command) {
this.config = config;
this.command = command;
}

buildDirectory(): void {
ProjectBuilder.validateConfig(this.config);

if (!existsSync(this.config.outputDir)) {
this.command.log(`Creating ${this.config.outputDir}`);
mkdirSync(this.config.outputDir);
}

this.command.log("Copying template files");
// TODO: Replace any params in files with .template extensions
this.copyFiles(this.templateDir, this.config.outputDir);

this.command.log("Success!");
// TODO: Can we do this here?
this.command.log("Run ./script/setup to install dependencies");
}

copyFiles(sourcePath: string, targetPath: string): void {
for (const file of readdirSync(sourcePath)) {
const path = join(sourcePath, file);

if (path.endsWith(".ignore")) {
continue;
} else if (lstatSync(path).isDirectory()) {
const nestedTargetPath = join(targetPath, file);
if (!existsSync(nestedTargetPath)) {
mkdirSync(nestedTargetPath);
}
this.copyFiles(path, nestedTargetPath);
} else if (path.endsWith(".template")) {
copyFileSync(path, join(targetPath, file.replace(".template", "")));
} else {
copyFileSync(path, join(targetPath, file));
}
}
}
}

export const buildDirectory = (config: InitConfig, command: Command): void => {
const builder = new ProjectBuilder(config, command);
builder.buildDirectory();
};

0 comments on commit 00384af

Please sign in to comment.