Skip to content

Commit

Permalink
feat: add populate option when create api project
Browse files Browse the repository at this point in the history
Signed-off-by: Brian Nguyen <[email protected]>
  • Loading branch information
vanpho93 committed Jul 14, 2022
1 parent d054356 commit 63afc18
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.env
.vscode
node_modules
mydir
myadmin
Expand Down
68 changes: 57 additions & 11 deletions commands/create-project-api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mkdir, writeFile } from "fs/promises";
import { mkdir, writeFile, readFile } from "fs/promises";
import { parse, stringify } from "envfile";
import simpleGit from "simple-git";
import wget from "../utils/wget.js";
Expand All @@ -9,6 +9,20 @@ import Logger from "../utils/logger.js";

const reactionRepoRoot = "https://raw.githubusercontent.com/reactioncommerce/reaction/trunk";

/**
* @summary create the git instance
* @param {String} projectName - The name of the directory to create
* @returns {Object} - the git instance
*/
function getGitInstance(projectName) {
const gitOptions = {
baseDir: `${process.cwd()}/${projectName}`,
binary: "git",
maxConcurrentProcesses: 6
};
return simpleGit(gitOptions);
}

/**
* @summary create project directory
* @param {String} projectName - The name of the directory to create
Expand Down Expand Up @@ -68,21 +82,28 @@ async function getFileFromCore(fileName) {
/**
* @summary update dotenv file to point to local mongo
* @param {String} envData - file extracted from the reaction repo
* @param {Object} options - Any options for project creation
* @returns {String} updated env file
*/
function updateEnv(envData) {
function updateEnv(envData, options = {}) {
const env = parse(envData);
env.MONGO_URL = "mongodb://localhost:27017/reaction";

if (options.populate) {
env.LOAD_SAMPLE_DATA = true;
}

const updatedEnv = stringify(env);
return updatedEnv;
}

/**
* @summary get files directory from core repo
* @param {String} projectName - The name of the project we are creating
* @param {Object} options - Any options for project creation
* @returns {Promise<Boolean>} True if success
*/
async function getFilesFromCore(projectName) {
async function getFilesFromCore(projectName, options) {
// get files directly from repo so it's always up-to-date
const packageJson = await getFileFromCore("package.json");
const updatedPackageJson = await updatePackageJson(packageJson, projectName);
Expand All @@ -104,7 +125,7 @@ async function getFilesFromCore(projectName) {
await writeFile(`${projectName}/.nvmrc`, nvmrc);

const dotenv = await getFileFromCore(".env.example");
const updatedDotEnv = updateEnv(dotenv);
const updatedDotEnv = updateEnv(dotenv, options);
await writeFile(`${projectName}/.env`, updatedDotEnv);
return true;
}
Expand All @@ -116,19 +137,40 @@ async function getFilesFromCore(projectName) {
* @returns {Promise<Boolean>} true if success
*/
async function gitInitDirectory(projectName) {
const gitOptions = {
baseDir: `${process.cwd()}/${projectName}`,
binary: "git",
maxConcurrentProcesses: 6
};
const git = simpleGit(gitOptions);
const git = getGitInstance(projectName);
try {
await git.init();
} catch (error) {
Logger.error(error);
}
}

/**
* @summary add the sample data plugin to project
* @param {String} projectName name of the project to create
* @param {String} pluginName The plugin name
* @returns {Promise<boolean>} true for success
*/
async function addSampleDataPlugin(projectName) {
const git = getGitInstance(projectName);
try {
await git.clone("[email protected]:reactioncommerce/api-plugin-sample-data.git", "custom-packages/api-plugin-sample-data");

const pluginJsonPath = `${projectName}/plugins.json`;
const plugins = JSON.parse(await readFile(pluginJsonPath));
plugins.sampleData = "./custom-packages/api-plugin-sample-data/index.js";

await writeFile(pluginJsonPath, JSON.stringify(plugins, null, "\t"));

Logger.info("Added the sample data plugin successfully.");
return true;
} catch (error) {
Logger.error(error);
Logger.warn("Can't add the sample data plugin by error. Please add it manual.");
return false;
}
}


/**
* @summary clones projects locally from repo
Expand All @@ -148,10 +190,14 @@ export default async function createProjectApi(projectName, options) {
await getFilesFromRepo("/templates/api-project/", projectName);

// copy files directly from core that we want to be current
await getFilesFromCore(projectName);
await getFilesFromCore(projectName, options);

// git init the new project
await gitInitDirectory(projectName);

if (options.populate) {
await addSampleDataPlugin(projectName);
}

Logger.success("Project creation complete. Change to your directory and run `npm install`");
}
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ program
.description("Create a new Open Commerce project of one of several types")
.addArgument(new commander.Argument("<type>", "which project type to create").choices(["api", "storefront", "admin", "demo"]))
.argument("<name>", "what to name the project")
// .option("--populate")
.option("--populate", "Install the sample data plugin")
.option("--skip-meteor-install", "Skip Meteor install when creating admin project")
.option("--dont-start-demo", "Don't auto start the demo project after creation")
.action((type, name, options) => {
Expand Down
14 changes: 14 additions & 0 deletions tests/create-api-project.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { EOL } from "os";
import fs from "fs/promises";
import { v4 as uuidv4 } from "uuid";
import rimraf from "rimraf";
import { expect } from "chai";
Expand Down Expand Up @@ -28,6 +29,19 @@ describe("The create-project-api command", () => {
// eslint-disable-next-line jest/valid-expect
expect(responseLines[1]).to.equal("reaction-cli: Project creation complete. Change to your directory and run `npm install`");
}).timeout(5000);

it("should print the correct output when user run with --populate option", async () => {
const response = await execute("./index.js", ["create-project", "api", "myshop", "--populate"]);
const responseLines = response.trim().split(EOL);
expect(responseLines[1]).equal("reaction-cli: Added the sample data plugin successfully.");
expect(responseLines[2]).equal("reaction-cli: Project creation complete. Change to your directory and run `npm install`");

const pluginsData = JSON.parse(await fs.readFile("./myshop/plugins.json"));
expect(pluginsData.sampleData).eq("./custom-packages/api-plugin-sample-data/index.js");

const envData = await fs.readFile("./myshop/.env", { encoding: "utf-8" });
expect(envData).contain("LOAD_SAMPLE_DATA=true");
}).timeout(350000);
});

afterEach(async () => {
Expand Down

0 comments on commit 63afc18

Please sign in to comment.