From ba96710f52e8ae06b66cb232fc9c77ce45e8e5c5 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 08:47:11 -0600 Subject: [PATCH 01/77] Initialize npm project --- package.json | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 09700df..9ade701 100644 --- a/package.json +++ b/package.json @@ -2,5 +2,56 @@ "dependencies": { "aws-sdk": "^2.724.0", "minimist": "^1.2.5" - } + }, + "name": "maestro-framework", + "description": "Maestro is a framework for quickly bootstrapping serverless orchestration workflows with AWS Step Functions", + "version": "1.0.0", + "bin": { + "maestro-deploy": "./bin/deploy.js", + "maestro-teardown": "./bin/teardown.js" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/maestro-framework/maestro.git" + }, + "keywords": [ + "lambda", + "aws", + "amazon web services", + "serverless", + "faas", + "maestro", + "orchestration", + "orchestrator", + "framework", + "maestro-framework" + ], + "author": "maestro-framework", + "contributors": [ + { + "name": "Torrel Moseley", + "email": "trrl.mo@hotmail.com" + }, + { + "name": "Zac Klammer", + "email": "zklamm@gmail.com" + }, + { + "name": "John Isom", + "email": "john@johnisom.dev" + } + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/maestro-framework/maestro/issues" + }, + "preferGlobal": true, + "engines": { + "node": ">=10" + }, + "homepage": "https://github.com/maestro-framework/maestro#readme" } From f71ac8363e089906c7efd4f88aa86f9f1b3efae7 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 14:50:25 -0600 Subject: [PATCH 02/77] Add post-install hook to display helpful message --- bin/setup.sh | 13 +++++++++++++ package.json | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100755 bin/setup.sh diff --git a/bin/setup.sh b/bin/setup.sh new file mode 100755 index 0000000..8099737 --- /dev/null +++ b/bin/setup.sh @@ -0,0 +1,13 @@ +#!/usr/bin/bash + +# TODO: install man/info pages (if/when we create them) here, and other post-install tasks + +cat <<'EOF' ++--------------------------------------------------------------+ +| Welcome to Maestro! | +| Run `maestro setup` to configure Maestro for first-time use. | +| Or run `maestro help` for instructions for use. | +| Happy coding! | ++--------------------------------------------------------------+ + +EOF diff --git a/package.json b/package.json index 9ade701..74476cb 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ }, "devDependencies": {}, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "postinstall": "./bin/setup.sh" }, "repository": { "type": "git", From d1f50d2bfd7716a6a2e1e86443cd4eab051116e7 Mon Sep 17 00:00:00 2001 From: mo mac Date: Fri, 7 Aug 2020 16:21:08 -0600 Subject: [PATCH 03/77] Add 'maestro' command. Create 'deploy' command and export. Remove unnecessary references from package.json Co-authored-by: Zac Klammer Co-authored-by: John Isom --- bin/deploy.js | 30 +++++++++++++++++------------- bin/maestro.js | 18 ++++++++++++++++++ package.json | 6 ++---- 3 files changed, 37 insertions(+), 17 deletions(-) create mode 100755 bin/maestro.js diff --git a/bin/deploy.js b/bin/deploy.js index 6537d71..e2ed3af 100755 --- a/bin/deploy.js +++ b/bin/deploy.js @@ -11,18 +11,22 @@ const createStepFunction = require("../src/aws/createStepFunction"); const basenamesAndZipBuffers = getBasenamesAndZipBuffers("lambdas"); const { lambdaRoleName, statesRoleName } = require("../src/config/roleNames"); -establishIAMRole(lambdaRoleName) - .then(() => - generateMultipleFunctionParams( - basenamesAndZipBuffers, - lambdaRoleName +const deploy = () => { + establishIAMRole(lambdaRoleName) + .then(() => + generateMultipleFunctionParams( + basenamesAndZipBuffers, + lambdaRoleName + ) ) - ) - .then(createLambdaFunctions) - .then(() => console.log("Successfully created function(s)")); + .then(createLambdaFunctions) + .then(() => console.log("Successfully created function(s)")); -establishIAMRole(statesRoleName) - .then(() => generateStateMachineParams(statesRoleName)) - .then(createStepFunction) - .then(() => console.log("Successfully created state machine")) - .catch(() => {}); + establishIAMRole(statesRoleName) + .then(() => generateStateMachineParams(statesRoleName)) + .then(createStepFunction) + .then(() => console.log("Successfully created state machine")) + .catch(() => {}); +} + +module.exports = deploy; \ No newline at end of file diff --git a/bin/maestro.js b/bin/maestro.js new file mode 100755 index 0000000..dd0d6d5 --- /dev/null +++ b/bin/maestro.js @@ -0,0 +1,18 @@ +#!/usr/bin/env node + +const minimist = require("minimist"); +const argv = minimist(process.argv.slice(2), { + boolean: ["f", "force"], + string: ["roles"], + default: { + roles: "", + }, +}); +const deploy = require('./deploy'); + +switch(argv._[0]) { + case 'deploy': + deploy(); + break; + default: +} diff --git a/package.json b/package.json index 74476cb..2df979f 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,11 @@ "description": "Maestro is a framework for quickly bootstrapping serverless orchestration workflows with AWS Step Functions", "version": "1.0.0", "bin": { - "maestro-deploy": "./bin/deploy.js", - "maestro-teardown": "./bin/teardown.js" + "maestro": "./bin/maestro.js" }, "devDependencies": {}, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "postinstall": "./bin/setup.sh" + "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", From 4d4f37ccf46c430eac5386023ae506e69d650281 Mon Sep 17 00:00:00 2001 From: mo mac Date: Fri, 7 Aug 2020 16:51:13 -0600 Subject: [PATCH 04/77] Create a teardown function and export it. Add the teardown command as a sub-command of maestro command. Delete unnecessary variable in deploy.js and teardown.js. Co-authored-by: Zac Klammer Co-authored-by: John Isom --- bin/deploy.js | 3 ++- bin/maestro.js | 5 +++++ bin/teardown.js | 54 +++++++++++++++++++------------------------------ 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/bin/deploy.js b/bin/deploy.js index e2ed3af..79565d7 100755 --- a/bin/deploy.js +++ b/bin/deploy.js @@ -8,10 +8,11 @@ const createLambdaFunctions = require("../src/aws/createLambdaFunctions"); const createStepFunction = require("../src/aws/createStepFunction"); // TODO: Separate the retrieving of file basenames and creating zip buffers // Specify files to retrieve by a workflow name -const basenamesAndZipBuffers = getBasenamesAndZipBuffers("lambdas"); const { lambdaRoleName, statesRoleName } = require("../src/config/roleNames"); const deploy = () => { + const basenamesAndZipBuffers = getBasenamesAndZipBuffers("lambdas"); + establishIAMRole(lambdaRoleName) .then(() => generateMultipleFunctionParams( diff --git a/bin/maestro.js b/bin/maestro.js index dd0d6d5..11fa8e7 100755 --- a/bin/maestro.js +++ b/bin/maestro.js @@ -9,10 +9,15 @@ const argv = minimist(process.argv.slice(2), { }, }); const deploy = require('./deploy'); +const teardown = require('./teardown'); switch(argv._[0]) { case 'deploy': deploy(); break; + case 'teardown': + teardown(argv); + break; default: + console.log(`See documentation for commands (i.e. deploy, teardown).\n https://github.com/maestro-framework/maestro`); } diff --git a/bin/teardown.js b/bin/teardown.js index 1562949..521d1ff 100755 --- a/bin/teardown.js +++ b/bin/teardown.js @@ -1,40 +1,16 @@ #!/usr/bin/env node const fs = require("fs"); -const minimist = require("minimist"); -const childProcess = require("child_process"); -const retryAsync = require("../src/util/retryAsync"); -const { lambdaRoleName, statesRoleName } = require("../src/config/roleNames"); -const { - lambdaPolicyArns, - statesPolicyArns, -} = require("../src/config/policy-arn"); const deleteLambdas = require("../src/aws/deleteLambdas"); const deleteStateMachine = require("../src/aws/deleteStateMachine"); const teardownRoleByName = require("../src/aws/teardownRoleByName"); const getStateMachineArn = require("../src/aws/getStateMachineArn"); const basename = require("../src/util/basename"); const promptAsyncYesNoAndExec = require("../src/util/promptAsyncYesNoAndExec"); - -const argv = minimist(process.argv.slice(2), { - boolean: ["f", "force"], - string: ["roles"], - default: { - roles: "", - }, -}); const stateMachineName = require("../src/util/workflowName"); -const rolesToDelete = argv.roles.split(",").filter((role) => role.length > 0); - -const lambdaNames = fs - .readdirSync("lambdas") - .map(basename) - .map((lambdaName) => { - return stateMachineName + "_" + lambdaName; - }); -const main = async () => { +const deleteResources = async (rolesToDelete, lambdaNames) => { const deleteLambdasPromise = deleteLambdas(lambdaNames).catch(console.log); const deleteStateMachinePromise = getStateMachineArn(stateMachineName) .then(deleteStateMachine) @@ -44,11 +20,23 @@ const main = async () => { rolesToDelete.forEach(teardownRoleByName); }; -if (argv.force || argv.f) { - main(); -} else { - promptAsyncYesNoAndExec( - `Are you sure you want to delete ${stateMachineName}?`, - main - ); -} +const teardown = (argv) => { + const lambdaNames = fs + .readdirSync("lambdas") + .map(basename) + .map((lambdaName) => { + return stateMachineName + "_" + lambdaName; + }); + const rolesToDelete = argv.roles.split(",").filter((role) => role.length > 0); + + if (argv.force || argv.f) { + deleteResources(rolesToDelete, lambdaNames); + } else { + promptAsyncYesNoAndExec( + `Are you sure you want to delete ${stateMachineName}?`, + () => deleteResources(rolesToDelete, lambdaNames) + ); + } +}; + +module.exports = teardown; From bf59de3b867c975b65f5c1d3996e6771bfd15bb5 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 17:27:54 -0600 Subject: [PATCH 05/77] Move files to better places --- src/aws/{ => iam}/deleteRole.js | 0 src/aws/{ => iam}/detachPolicies.js | 0 src/aws/{ => iam}/establishIAMRole.js | 0 src/aws/{ => iam}/generateRoleParams.js | 0 src/aws/{ => iam}/generateRolePolicy.js | 0 src/aws/{ => iam}/getAttachedPolicyArnsByRoleName.js | 0 src/aws/{ => iam}/teardownRoleByName.js | 0 src/aws/{ => lambda}/createLambdaFunctions.js | 0 src/aws/{ => lambda}/deleteLambdas.js | 0 src/aws/{ => lambda}/generateMultipleFunctionParams.js | 0 src/aws/{ => step-function}/createStepFunction.js | 0 src/aws/{ => step-function}/deleteStateMachine.js | 0 src/aws/{ => step-function}/generateStateMachineParams.js | 0 src/aws/{ => step-function}/getStateMachineArn.js | 0 {bin => src/commands}/deploy.js | 2 -- {bin => src/commands}/teardown.js | 2 -- 16 files changed, 4 deletions(-) rename src/aws/{ => iam}/deleteRole.js (100%) rename src/aws/{ => iam}/detachPolicies.js (100%) rename src/aws/{ => iam}/establishIAMRole.js (100%) rename src/aws/{ => iam}/generateRoleParams.js (100%) rename src/aws/{ => iam}/generateRolePolicy.js (100%) rename src/aws/{ => iam}/getAttachedPolicyArnsByRoleName.js (100%) rename src/aws/{ => iam}/teardownRoleByName.js (100%) rename src/aws/{ => lambda}/createLambdaFunctions.js (100%) rename src/aws/{ => lambda}/deleteLambdas.js (100%) rename src/aws/{ => lambda}/generateMultipleFunctionParams.js (100%) rename src/aws/{ => step-function}/createStepFunction.js (100%) rename src/aws/{ => step-function}/deleteStateMachine.js (100%) rename src/aws/{ => step-function}/generateStateMachineParams.js (100%) rename src/aws/{ => step-function}/getStateMachineArn.js (100%) rename {bin => src/commands}/deploy.js (98%) mode change 100755 => 100644 rename {bin => src/commands}/teardown.js (98%) mode change 100755 => 100644 diff --git a/src/aws/deleteRole.js b/src/aws/iam/deleteRole.js similarity index 100% rename from src/aws/deleteRole.js rename to src/aws/iam/deleteRole.js diff --git a/src/aws/detachPolicies.js b/src/aws/iam/detachPolicies.js similarity index 100% rename from src/aws/detachPolicies.js rename to src/aws/iam/detachPolicies.js diff --git a/src/aws/establishIAMRole.js b/src/aws/iam/establishIAMRole.js similarity index 100% rename from src/aws/establishIAMRole.js rename to src/aws/iam/establishIAMRole.js diff --git a/src/aws/generateRoleParams.js b/src/aws/iam/generateRoleParams.js similarity index 100% rename from src/aws/generateRoleParams.js rename to src/aws/iam/generateRoleParams.js diff --git a/src/aws/generateRolePolicy.js b/src/aws/iam/generateRolePolicy.js similarity index 100% rename from src/aws/generateRolePolicy.js rename to src/aws/iam/generateRolePolicy.js diff --git a/src/aws/getAttachedPolicyArnsByRoleName.js b/src/aws/iam/getAttachedPolicyArnsByRoleName.js similarity index 100% rename from src/aws/getAttachedPolicyArnsByRoleName.js rename to src/aws/iam/getAttachedPolicyArnsByRoleName.js diff --git a/src/aws/teardownRoleByName.js b/src/aws/iam/teardownRoleByName.js similarity index 100% rename from src/aws/teardownRoleByName.js rename to src/aws/iam/teardownRoleByName.js diff --git a/src/aws/createLambdaFunctions.js b/src/aws/lambda/createLambdaFunctions.js similarity index 100% rename from src/aws/createLambdaFunctions.js rename to src/aws/lambda/createLambdaFunctions.js diff --git a/src/aws/deleteLambdas.js b/src/aws/lambda/deleteLambdas.js similarity index 100% rename from src/aws/deleteLambdas.js rename to src/aws/lambda/deleteLambdas.js diff --git a/src/aws/generateMultipleFunctionParams.js b/src/aws/lambda/generateMultipleFunctionParams.js similarity index 100% rename from src/aws/generateMultipleFunctionParams.js rename to src/aws/lambda/generateMultipleFunctionParams.js diff --git a/src/aws/createStepFunction.js b/src/aws/step-function/createStepFunction.js similarity index 100% rename from src/aws/createStepFunction.js rename to src/aws/step-function/createStepFunction.js diff --git a/src/aws/deleteStateMachine.js b/src/aws/step-function/deleteStateMachine.js similarity index 100% rename from src/aws/deleteStateMachine.js rename to src/aws/step-function/deleteStateMachine.js diff --git a/src/aws/generateStateMachineParams.js b/src/aws/step-function/generateStateMachineParams.js similarity index 100% rename from src/aws/generateStateMachineParams.js rename to src/aws/step-function/generateStateMachineParams.js diff --git a/src/aws/getStateMachineArn.js b/src/aws/step-function/getStateMachineArn.js similarity index 100% rename from src/aws/getStateMachineArn.js rename to src/aws/step-function/getStateMachineArn.js diff --git a/bin/deploy.js b/src/commands/deploy.js old mode 100755 new mode 100644 similarity index 98% rename from bin/deploy.js rename to src/commands/deploy.js index 83eb1e5..9d2000e --- a/bin/deploy.js +++ b/src/commands/deploy.js @@ -1,5 +1,3 @@ -#!/usr/bin/env node - const getBasenamesAndZipBuffers = require("../src/util/getBasenamesAndZipBuffers"); const generateMultipleFunctionParams = require("../src/aws/generateMultipleFunctionParams"); const generateStateMachineParams = require("../src/aws/generateStateMachineParams"); diff --git a/bin/teardown.js b/src/commands/teardown.js old mode 100755 new mode 100644 similarity index 98% rename from bin/teardown.js rename to src/commands/teardown.js index 521d1ff..2bd4037 --- a/bin/teardown.js +++ b/src/commands/teardown.js @@ -1,5 +1,3 @@ -#!/usr/bin/env node - const fs = require("fs"); const deleteLambdas = require("../src/aws/deleteLambdas"); From 5ef10ba1adfbd4785fd1693b004737fc4db09186 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 17:36:29 -0600 Subject: [PATCH 06/77] Change the `require` statements to match new file structure --- bin/maestro.js | 4 ++-- src/aws/iam/deleteRole.js | 2 +- src/aws/iam/detachPolicies.js | 2 +- src/aws/iam/establishIAMRole.js | 6 +++--- src/aws/iam/getAttachedPolicyArnsByRoleName.js | 2 +- src/aws/lambda/createLambdaFunctions.js | 4 ++-- src/aws/lambda/deleteLambdas.js | 2 +- src/aws/lambda/generateMultipleFunctionParams.js | 4 ++-- src/aws/services.js | 6 ++++-- src/aws/step-function/createStepFunction.js | 2 +- src/aws/step-function/deleteStateMachine.js | 2 +- .../step-function/generateStateMachineParams.js | 4 ++-- src/aws/step-function/getStateMachineArn.js | 2 +- src/commands/deploy.js | 14 +++++++------- src/commands/teardown.js | 14 +++++++------- 15 files changed, 36 insertions(+), 34 deletions(-) diff --git a/bin/maestro.js b/bin/maestro.js index 11fa8e7..03437ff 100755 --- a/bin/maestro.js +++ b/bin/maestro.js @@ -8,8 +8,8 @@ const argv = minimist(process.argv.slice(2), { roles: "", }, }); -const deploy = require('./deploy'); -const teardown = require('./teardown'); +const deploy = require('../src/commands/deploy'); +const teardown = require('../src/commands/teardown'); switch(argv._[0]) { case 'deploy': diff --git a/src/aws/iam/deleteRole.js b/src/aws/iam/deleteRole.js index b0b8a4b..097188c 100644 --- a/src/aws/iam/deleteRole.js +++ b/src/aws/iam/deleteRole.js @@ -1,4 +1,4 @@ -const { iam } = require("./services"); +const { iam } = require("../services"); const deleteRole = (name) => { return iam.deleteRole({ RoleName: name }).promise(); diff --git a/src/aws/iam/detachPolicies.js b/src/aws/iam/detachPolicies.js index 9277b9f..ff4d96a 100644 --- a/src/aws/iam/detachPolicies.js +++ b/src/aws/iam/detachPolicies.js @@ -1,4 +1,4 @@ -const { iam } = require("./services"); +const { iam } = require("../services"); const detachPolicies = (policyArns, roleName) => { const detachPolicyPromises = policyArns.map((arn) => { diff --git a/src/aws/iam/establishIAMRole.js b/src/aws/iam/establishIAMRole.js index b4b9dae..b21d7b8 100644 --- a/src/aws/iam/establishIAMRole.js +++ b/src/aws/iam/establishIAMRole.js @@ -1,6 +1,6 @@ -const { iam } = require("./services"); -const { lambdaPolicyArns, statesPolicyArns } = require("../config/policy-arn"); -const sleep = require("../util/sleep"); +const { iam } = require("../services"); +const { lambdaPolicyArns, statesPolicyArns } = require("../../config/policy-arn"); +const sleep = require("../../util/sleep"); const generateRoleParams = require("./generateRoleParams"); const attachPolicies = (policyArns, roleName) => { diff --git a/src/aws/iam/getAttachedPolicyArnsByRoleName.js b/src/aws/iam/getAttachedPolicyArnsByRoleName.js index 50dd2e2..4e5525e 100644 --- a/src/aws/iam/getAttachedPolicyArnsByRoleName.js +++ b/src/aws/iam/getAttachedPolicyArnsByRoleName.js @@ -1,4 +1,4 @@ -const { iam } = require("./services"); +const { iam } = require("../services"); const getAttachedPolicyArnsByRoleName = async (name) => { const attachedPolicies = ( diff --git a/src/aws/lambda/createLambdaFunctions.js b/src/aws/lambda/createLambdaFunctions.js index 0daefd6..eab78f4 100644 --- a/src/aws/lambda/createLambdaFunctions.js +++ b/src/aws/lambda/createLambdaFunctions.js @@ -1,5 +1,5 @@ -const retryAsync = require("../util/retryAsync"); -const { lambda } = require("./services"); +const retryAsync = require("../../util/retryAsync"); +const { lambda } = require("../services"); const createLambdaFunctions = (allParams) => { const createFunctionPromises = allParams.map((params) => diff --git a/src/aws/lambda/deleteLambdas.js b/src/aws/lambda/deleteLambdas.js index 6ddb01c..b4d7511 100644 --- a/src/aws/lambda/deleteLambdas.js +++ b/src/aws/lambda/deleteLambdas.js @@ -1,4 +1,4 @@ -const { lambda } = require("./services"); +const { lambda } = require("../services"); const deleteLambdas = (names) => { const deleteLambdaPromises = names.map((name) => { diff --git a/src/aws/lambda/generateMultipleFunctionParams.js b/src/aws/lambda/generateMultipleFunctionParams.js index e332858..c2d35ea 100644 --- a/src/aws/lambda/generateMultipleFunctionParams.js +++ b/src/aws/lambda/generateMultipleFunctionParams.js @@ -1,5 +1,5 @@ -const { iam } = require("./services.js"); -const stateMachineName = require("../util/workflowName"); +const { iam } = require("../services.js"); +const stateMachineName = require("../../util/workflowName"); const generateFunctionParams = (basename, zipBuffer, role) => { return { diff --git a/src/aws/services.js b/src/aws/services.js index 9e76749..68c94f3 100644 --- a/src/aws/services.js +++ b/src/aws/services.js @@ -2,11 +2,13 @@ const fs = require("fs"); const homedir = require("os").homedir(); const AWS = require("aws-sdk"); AWS.config.logger = console; -const iam = new AWS.IAM(); + +const apiVersion = "latest"; const region = JSON.parse( fs.readFileSync(homedir + "/.config/maestro/aws_account_info.json") ).region; -const apiVersion = "latest"; + +const iam = new AWS.IAM(); const lambda = new AWS.Lambda({ apiVersion, region }); const stepFunctions = new AWS.StepFunctions({ apiVersion, region }); diff --git a/src/aws/step-function/createStepFunction.js b/src/aws/step-function/createStepFunction.js index ffec873..36261da 100644 --- a/src/aws/step-function/createStepFunction.js +++ b/src/aws/step-function/createStepFunction.js @@ -1,4 +1,4 @@ -const { stepFunctions } = require("./services"); +const { stepFunctions } = require("../services"); const createStepFunction = (params) => { return stepFunctions.createStateMachine(params).promise(); diff --git a/src/aws/step-function/deleteStateMachine.js b/src/aws/step-function/deleteStateMachine.js index 51c7205..fdcb4bc 100644 --- a/src/aws/step-function/deleteStateMachine.js +++ b/src/aws/step-function/deleteStateMachine.js @@ -1,4 +1,4 @@ -const { stepFunctions } = require("./services"); +const { stepFunctions } = require("../services"); const deleteStateMachine = (arn) => { return stepFunctions.deleteStateMachine({ stateMachineArn: arn }).promise(); diff --git a/src/aws/step-function/generateStateMachineParams.js b/src/aws/step-function/generateStateMachineParams.js index d2c03de..de84354 100644 --- a/src/aws/step-function/generateStateMachineParams.js +++ b/src/aws/step-function/generateStateMachineParams.js @@ -1,8 +1,8 @@ -const { iam } = require("./services"); +const { iam } = require("../services"); const fs = require("fs"); const os = require("os"); const account_info_path = "/.config/maestro/aws_account_info.json"; -const stateMachineName = require("../util/workflowName"); +const stateMachineName = require("../../util/workflowName"); const readConfigFileFromHome = (path) => { const homedir = os.homedir(); diff --git a/src/aws/step-function/getStateMachineArn.js b/src/aws/step-function/getStateMachineArn.js index c44eee8..5ba7038 100644 --- a/src/aws/step-function/getStateMachineArn.js +++ b/src/aws/step-function/getStateMachineArn.js @@ -1,4 +1,4 @@ -const { stepFunctions } = require("./services.js"); +const { stepFunctions } = require("../services.js"); const getStateMachineArn = async (name) => { const stateMachines = (await stepFunctions.listStateMachines().promise()) diff --git a/src/commands/deploy.js b/src/commands/deploy.js index 9d2000e..c9ed60f 100644 --- a/src/commands/deploy.js +++ b/src/commands/deploy.js @@ -1,12 +1,12 @@ -const getBasenamesAndZipBuffers = require("../src/util/getBasenamesAndZipBuffers"); -const generateMultipleFunctionParams = require("../src/aws/generateMultipleFunctionParams"); -const generateStateMachineParams = require("../src/aws/generateStateMachineParams"); -const establishIAMRole = require("../src/aws/establishIAMRole"); -const createLambdaFunctions = require("../src/aws/createLambdaFunctions"); -const createStepFunction = require("../src/aws/createStepFunction"); +const getBasenamesAndZipBuffers = require("../util/getBasenamesAndZipBuffers"); +const generateMultipleFunctionParams = require("../aws/lambda/generateMultipleFunctionParams"); +const createLambdaFunctions = require("../aws/lambda/createLambdaFunctions"); +const generateStateMachineParams = require("../aws/step-function/generateStateMachineParams"); +const createStepFunction = require("../aws/step-function/createStepFunction"); +const establishIAMRole = require("../aws/iam/establishIAMRole"); // TODO: Separate the retrieving of file basenames and creating zip buffers // Specify files to retrieve by a workflow name -const { lambdaRoleName, statesRoleName } = require("../src/config/roleNames"); +const { lambdaRoleName, statesRoleName } = require("../config/roleNames"); const deploy = () => { const basenamesAndZipBuffers = getBasenamesAndZipBuffers("lambdas"); diff --git a/src/commands/teardown.js b/src/commands/teardown.js index 2bd4037..b1e258d 100644 --- a/src/commands/teardown.js +++ b/src/commands/teardown.js @@ -1,12 +1,12 @@ const fs = require("fs"); -const deleteLambdas = require("../src/aws/deleteLambdas"); -const deleteStateMachine = require("../src/aws/deleteStateMachine"); -const teardownRoleByName = require("../src/aws/teardownRoleByName"); -const getStateMachineArn = require("../src/aws/getStateMachineArn"); -const basename = require("../src/util/basename"); -const promptAsyncYesNoAndExec = require("../src/util/promptAsyncYesNoAndExec"); -const stateMachineName = require("../src/util/workflowName"); +const deleteLambdas = require("../aws/lambda/deleteLambdas"); +const deleteStateMachine = require("../aws/step-function/deleteStateMachine"); +const teardownRoleByName = require("../aws/iam/teardownRoleByName"); +const getStateMachineArn = require("../aws/iam/getStateMachineArn"); +const basename = require("../util/basename"); +const promptAsyncYesNoAndExec = require("../util/promptAsyncYesNoAndExec"); +const stateMachineName = require("../util/workflowName"); const deleteResources = async (rolesToDelete, lambdaNames) => { const deleteLambdasPromise = deleteLambdas(lambdaNames).catch(console.log); From 8e1d2d421a6e8ea5a58fbddb6698cfebe71f3e57 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 17:40:04 -0600 Subject: [PATCH 07/77] Move `getStateMachineArn` to `iam` from `step-function` --- src/aws/{step-function => iam}/getStateMachineArn.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/aws/{step-function => iam}/getStateMachineArn.js (100%) diff --git a/src/aws/step-function/getStateMachineArn.js b/src/aws/iam/getStateMachineArn.js similarity index 100% rename from src/aws/step-function/getStateMachineArn.js rename to src/aws/iam/getStateMachineArn.js From cb1b23542d6f567c9a388208d75c8f550031c968 Mon Sep 17 00:00:00 2001 From: mo mac Date: Fri, 7 Aug 2020 18:04:14 -0600 Subject: [PATCH 08/77] Add boilerplacte for 'maestro config' cmd in 'src/commands/config.js'; Update setup prompt to reflect referencing docs for help and using 'maestro config'; add 'config' command as sub-command of 'maestro' cmd --- bin/maestro.js | 4 ++++ bin/setup.sh | 5 +++-- src/commands/config.js | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 src/commands/config.js diff --git a/bin/maestro.js b/bin/maestro.js index 03437ff..9fe3e39 100755 --- a/bin/maestro.js +++ b/bin/maestro.js @@ -10,6 +10,7 @@ const argv = minimist(process.argv.slice(2), { }); const deploy = require('../src/commands/deploy'); const teardown = require('../src/commands/teardown'); +const config = require('../src/commands/config'); switch(argv._[0]) { case 'deploy': @@ -18,6 +19,9 @@ switch(argv._[0]) { case 'teardown': teardown(argv); break; + case 'config'; + config(); + break; default: console.log(`See documentation for commands (i.e. deploy, teardown).\n https://github.com/maestro-framework/maestro`); } diff --git a/bin/setup.sh b/bin/setup.sh index 8099737..34e35f3 100755 --- a/bin/setup.sh +++ b/bin/setup.sh @@ -5,8 +5,9 @@ cat <<'EOF' +--------------------------------------------------------------+ | Welcome to Maestro! | -| Run `maestro setup` to configure Maestro for first-time use. | -| Or run `maestro help` for instructions for use. | +| Run `maestro config` to configure Maestro for first-time use.| +| Or see the documentation for instructions for use. | +| https://github.com/maestro-framework/maestro | | Happy coding! | +--------------------------------------------------------------+ diff --git a/src/commands/config.js b/src/commands/config.js new file mode 100644 index 0000000..ede338f --- /dev/null +++ b/src/commands/config.js @@ -0,0 +1,6 @@ +const config = () => { + +}; + + +module.exports = config; \ No newline at end of file From 4532be68c8b7195df1661e86f4b178a83656f10f Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 18:05:41 -0600 Subject: [PATCH 09/77] Add directory-creating logic to newProject.js --- bin/maestro.js | 4 ++++ src/commands/newProject.js | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/commands/newProject.js diff --git a/bin/maestro.js b/bin/maestro.js index 03437ff..fd1bf84 100755 --- a/bin/maestro.js +++ b/bin/maestro.js @@ -10,6 +10,7 @@ const argv = minimist(process.argv.slice(2), { }); const deploy = require('../src/commands/deploy'); const teardown = require('../src/commands/teardown'); +const newProject = require('../src/commands/newProject'); switch(argv._[0]) { case 'deploy': @@ -18,6 +19,9 @@ switch(argv._[0]) { case 'teardown': teardown(argv); break; + case 'new': + newProject(argv) + break; default: console.log(`See documentation for commands (i.e. deploy, teardown).\n https://github.com/maestro-framework/maestro`); } diff --git a/src/commands/newProject.js b/src/commands/newProject.js new file mode 100644 index 0000000..6ac0d38 --- /dev/null +++ b/src/commands/newProject.js @@ -0,0 +1,23 @@ +const fs = require("fs"); + +const newProject = (argv) => { + const projectName = argv._[1]; + + if (!projectName) { + console.log("Please provide a project name"); + return; + } + + try { + fs.mkdirSync(projectName); + } catch { + console.log( + `Can't create project with name "${projectName}": directory with same name already exists!` + ); + return; + } + + console.log(`Created project "${projectName}"!`); +}; + +module.exports = newProject; From 1c1c54847c6670d0f01258f8226fc178b10189f8 Mon Sep 17 00:00:00 2001 From: mo mac Date: Fri, 7 Aug 2020 18:30:08 -0600 Subject: [PATCH 10/77] Create helper functions createHiddenMaestroDir and promptForAccountInfo in 'src/commands/config.js' --- src/commands/config.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/commands/config.js b/src/commands/config.js index ede338f..aecc992 100644 --- a/src/commands/config.js +++ b/src/commands/config.js @@ -1,3 +1,23 @@ +const fs = require('fs'); +const os = require('os'); +const promptAsync = require('../util/promptAsync'); + +const createHiddenMaestroDir = () => { + const homedir = os.homedir(); + const dir = '/.maestro'; + + if (!fs.existsSync(dir)){ + fs.mkdirSync(homedir + dir); + } +}; + +const promptForAccountInfo = async () => { + const accountNum = await promptAsync('Please enter your AWS Account Number'); + const reqion = await promptAsync('Please enter the region for you AWS servises'); + + return { accountNum, region }; +} + const config = () => { }; From 8a4587626aecf411b3418d58dc90238d9338a32d Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 18:47:38 -0600 Subject: [PATCH 11/77] Create basic prompt for 'new' command that actually does nothing --- src/commands/newProject.js | 11 +++++++++++ src/util/capitalize.js | 7 +++++++ src/util/configDir.js | 5 +++++ 3 files changed, 23 insertions(+) create mode 100644 src/util/capitalize.js create mode 100644 src/util/configDir.js diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 6ac0d38..8126721 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -1,5 +1,8 @@ const fs = require("fs"); +const configDir = require("../util/configDir"); +const capitalize = require("../util/capitalize"); + const newProject = (argv) => { const projectName = argv._[1]; @@ -17,6 +20,14 @@ const newProject = (argv) => { return; } + // has structure of [["Example workflow", "example-workflow"], ...] + const templateNames = fs.readdirSync(`${configDir}/templates`).map((name) => { + const cleanedName = name.replace(/[-_]/,' '); + return [capitalize(cleanedName), name]; + }); + + console.log('Template names:', templateNames); + console.log(`Created project "${projectName}"!`); }; diff --git a/src/util/capitalize.js b/src/util/capitalize.js new file mode 100644 index 0000000..63c7e6c --- /dev/null +++ b/src/util/capitalize.js @@ -0,0 +1,7 @@ +const capitalize = (str) => { + if (str === '') return ''; + + return str[0].toUpperCase() + str.slice(1).toLowerCase(); +}; + +module.exports = capitalize; diff --git a/src/util/configDir.js b/src/util/configDir.js new file mode 100644 index 0000000..ae8a27c --- /dev/null +++ b/src/util/configDir.js @@ -0,0 +1,5 @@ +const os = require('os'); +const homedir = os.homedir(); +const configDir = '.maestro'; + +module.exports = `${homedir}/${configDir}`; From 22c2422df502c8a2edac61a022bc280b0c091d71 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 19:37:24 -0600 Subject: [PATCH 12/77] Allow user to pick template to base new project off of (still doesn't copy any files) --- src/commands/newProject.js | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 8126721..d40254a 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -2,8 +2,27 @@ const fs = require("fs"); const configDir = require("../util/configDir"); const capitalize = require("../util/capitalize"); +const promptAsync = require("../util/promptAsync"); -const newProject = (argv) => { +const selectTemplateIdx = async (templateNames) => { + console.log('Select a template to base your project off of (defaults to no template)'); + console.log('-----------------------------------------------------------------------'); + + templateNames.forEach(([prettyName, rawName], idx) => { + console.log(`${`[${idx + 1}]`.padStart(5)} ${prettyName} (${rawName})`); + }); + + console.log('-----------------------------------------------------------------------'); + const selectedIdx = Number(await promptAsync(`Select template 1-${templateNames.length}`, 'none')) - 1; + + if (Number.isNaN(selectedIdx) || !templateNames[selectedIdx]) { + return -1; + } else { + return selectedIdx; + } +}; + +const newProject = async (argv) => { const projectName = argv._[1]; if (!projectName) { @@ -26,7 +45,17 @@ const newProject = (argv) => { return [capitalize(cleanedName), name]; }); - console.log('Template names:', templateNames); + const selectedTemplateIdx = await selectTemplateIdx(templateNames); + let selectedTemplate; + + if (selectedTemplateIdx !== -1) { + const cleanSelectedTemplateName = templateNames[selectedTemplateIdx][0]; + selectedTemplate = templateNames[selectedTemplateIdx][1]; + + console.log(`Creating project based off of template ${cleanSelectedTemplateName}...`); + } else { + console.log("Creating project without template..."); + } console.log(`Created project "${projectName}"!`); }; From c96460a8d7544163905d189d2b32b57fd180c713 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 19:37:54 -0600 Subject: [PATCH 13/77] Fix regexp bug --- src/commands/newProject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index d40254a..31373c8 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -41,7 +41,7 @@ const newProject = async (argv) => { // has structure of [["Example workflow", "example-workflow"], ...] const templateNames = fs.readdirSync(`${configDir}/templates`).map((name) => { - const cleanedName = name.replace(/[-_]/,' '); + const cleanedName = name.replace(/[-_]/g,' '); return [capitalize(cleanedName), name]; }); From 3db31564446f024313896e3ae9b8b563a56ba212 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 19:46:55 -0600 Subject: [PATCH 14/77] Copy template files over when creating new project with template --- src/commands/newProject.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 31373c8..669847a 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -1,3 +1,4 @@ +const childProcess = require("child_process"); const fs = require("fs"); const configDir = require("../util/configDir"); @@ -22,6 +23,10 @@ const selectTemplateIdx = async (templateNames) => { } }; +const copyTemplateToProject = (templateName, projectName) => { + childProcess.execSync(`cp -r ${configDir}/templates/${templateName}/* ${projectName}`); +}; + const newProject = async (argv) => { const projectName = argv._[1]; @@ -57,6 +62,8 @@ const newProject = async (argv) => { console.log("Creating project without template..."); } + copyTemplateToProject(selectedTemplate, projectName); + console.log(`Created project "${projectName}"!`); }; From 0ae6da21a2b3f1b370e79851a4e06682bd57f0c2 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 19:48:55 -0600 Subject: [PATCH 15/77] Initialize empty git repository in new project directory --- src/commands/newProject.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 669847a..98a7926 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -27,6 +27,10 @@ const copyTemplateToProject = (templateName, projectName) => { childProcess.execSync(`cp -r ${configDir}/templates/${templateName}/* ${projectName}`); }; +const initializeProjectGitRepository = (projectName) => { + childProcess.execSync(`git init ${projectName}`); +}; + const newProject = async (argv) => { const projectName = argv._[1]; @@ -63,6 +67,7 @@ const newProject = async (argv) => { } copyTemplateToProject(selectedTemplate, projectName); + initializeProjectGitRepository(projectName); console.log(`Created project "${projectName}"!`); }; From cf17b918ed868939a3fbc3200f8b35948d2d6f85 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 19:51:11 -0600 Subject: [PATCH 16/77] Rename template copying and git repo instantiating functions to be more generic --- src/commands/newProject.js | 12 ++++++------ src/util/copyTemplateToDir.js | 0 src/util/initializeGitRepository.js | 0 3 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 src/util/copyTemplateToDir.js create mode 100644 src/util/initializeGitRepository.js diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 98a7926..a82d037 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -23,12 +23,12 @@ const selectTemplateIdx = async (templateNames) => { } }; -const copyTemplateToProject = (templateName, projectName) => { - childProcess.execSync(`cp -r ${configDir}/templates/${templateName}/* ${projectName}`); +const copyTemplateToDir = (templateName, dirname) => { + childProcess.execSync(`cp -r ${configDir}/templates/${templateName}/* ${dirname}`); }; -const initializeProjectGitRepository = (projectName) => { - childProcess.execSync(`git init ${projectName}`); +const initializeGitRepository = (dirname) => { + childProcess.execSync(`git init ${dirname}`); }; const newProject = async (argv) => { @@ -66,8 +66,8 @@ const newProject = async (argv) => { console.log("Creating project without template..."); } - copyTemplateToProject(selectedTemplate, projectName); - initializeProjectGitRepository(projectName); + copyTemplateToDir(selectedTemplate, projectName); + initializeGitRepository(projectName); console.log(`Created project "${projectName}"!`); }; diff --git a/src/util/copyTemplateToDir.js b/src/util/copyTemplateToDir.js new file mode 100644 index 0000000..e69de29 diff --git a/src/util/initializeGitRepository.js b/src/util/initializeGitRepository.js new file mode 100644 index 0000000..e69de29 From 72a0716a4ad90cad2ca0b259b82df5bc31d281e4 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 19:53:55 -0600 Subject: [PATCH 17/77] Extract creation of git repo to own file --- src/commands/newProject.js | 5 +---- src/util/initializeGitRepository.js | 7 +++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index a82d037..01fdbf8 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -4,6 +4,7 @@ const fs = require("fs"); const configDir = require("../util/configDir"); const capitalize = require("../util/capitalize"); const promptAsync = require("../util/promptAsync"); +const initializeGitRepository = require("../util/initializeGitRepository"); const selectTemplateIdx = async (templateNames) => { console.log('Select a template to base your project off of (defaults to no template)'); @@ -27,10 +28,6 @@ const copyTemplateToDir = (templateName, dirname) => { childProcess.execSync(`cp -r ${configDir}/templates/${templateName}/* ${dirname}`); }; -const initializeGitRepository = (dirname) => { - childProcess.execSync(`git init ${dirname}`); -}; - const newProject = async (argv) => { const projectName = argv._[1]; diff --git a/src/util/initializeGitRepository.js b/src/util/initializeGitRepository.js index e69de29..d5fe215 100644 --- a/src/util/initializeGitRepository.js +++ b/src/util/initializeGitRepository.js @@ -0,0 +1,7 @@ +const childProcess = require("child_process"); + +const initializeGitRepository = (dirname) => { + childProcess.execSync(`git init ${dirname}`); +}; + +module.exports = initializeGitRepository; From 0d57ed781c10454db87377f46e2c80c9c2f70288 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 19:56:15 -0600 Subject: [PATCH 18/77] Extract copying template to own file --- src/commands/newProject.js | 5 +---- src/util/copyTemplateToDir.js | 8 ++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 01fdbf8..782f791 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -5,6 +5,7 @@ const configDir = require("../util/configDir"); const capitalize = require("../util/capitalize"); const promptAsync = require("../util/promptAsync"); const initializeGitRepository = require("../util/initializeGitRepository"); +const copyTemplateToDir = require("../util/copyTemplateToDir"); const selectTemplateIdx = async (templateNames) => { console.log('Select a template to base your project off of (defaults to no template)'); @@ -24,10 +25,6 @@ const selectTemplateIdx = async (templateNames) => { } }; -const copyTemplateToDir = (templateName, dirname) => { - childProcess.execSync(`cp -r ${configDir}/templates/${templateName}/* ${dirname}`); -}; - const newProject = async (argv) => { const projectName = argv._[1]; diff --git a/src/util/copyTemplateToDir.js b/src/util/copyTemplateToDir.js index e69de29..e526193 100644 --- a/src/util/copyTemplateToDir.js +++ b/src/util/copyTemplateToDir.js @@ -0,0 +1,8 @@ +const childProcess = require("child_process"); +const configDir = require("../util/configDir"); + +const copyTemplateToDir = (templateName, dirname) => { + childProcess.execSync(`cp -r ${configDir}/templates/${templateName}/* ${dirname}`); +}; + +module.exports = copyTemplateToDir; From 2e53f0fe0203e9b5d6d2d61d323051dfa3073e40 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:05:09 -0600 Subject: [PATCH 19/77] Fix bug --- src/commands/newProject.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 782f791..6cb0057 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -56,11 +56,12 @@ const newProject = async (argv) => { selectedTemplate = templateNames[selectedTemplateIdx][1]; console.log(`Creating project based off of template ${cleanSelectedTemplateName}...`); + + copyTemplateToDir(selectedTemplate, projectName); } else { console.log("Creating project without template..."); } - copyTemplateToDir(selectedTemplate, projectName); initializeGitRepository(projectName); console.log(`Created project "${projectName}"!`); From 9654f81fafe3b5e43f5f9e73e2d051045bd3caeb Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:09:29 -0600 Subject: [PATCH 20/77] Create empty files and dirs upon creation of project without template --- src/commands/newProject.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 6cb0057..11dd69b 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -25,6 +25,12 @@ const selectTemplateIdx = async (templateNames) => { } }; +const createEmptyProject = (name) => { + fs.writeFileSync(`${name}/README.md`,''); + fs.writeFileSync(`${name}/definition.asl.json`,'{}'); + fs.mkdirSync(`${name}/lambdas`); +}; + const newProject = async (argv) => { const projectName = argv._[1]; @@ -60,6 +66,8 @@ const newProject = async (argv) => { copyTemplateToDir(selectedTemplate, projectName); } else { console.log("Creating project without template..."); + + createEmptyProject(projectName); } initializeGitRepository(projectName); From 3fd4e590637112d262cea01b69700aac2e209eb8 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:12:35 -0600 Subject: [PATCH 21/77] Create `cleanupAndCapitalize` and extract from `templateNames.map` --- src/commands/newProject.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 11dd69b..311b551 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -31,6 +31,11 @@ const createEmptyProject = (name) => { fs.mkdirSync(`${name}/lambdas`); }; +const cleanupAndCapitalize = (str) => { + const cleaned = str.replace(/[-_]/g,' '); + return capitalize(cleaned); +}; + const newProject = async (argv) => { const projectName = argv._[1]; @@ -50,8 +55,7 @@ const newProject = async (argv) => { // has structure of [["Example workflow", "example-workflow"], ...] const templateNames = fs.readdirSync(`${configDir}/templates`).map((name) => { - const cleanedName = name.replace(/[-_]/g,' '); - return [capitalize(cleanedName), name]; + return [cleanupAndCapitalize(name), name]; }); const selectedTemplateIdx = await selectTemplateIdx(templateNames); From 750a32a0bf7baf0ba67f063d10e15521a0a2b677 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:13:33 -0600 Subject: [PATCH 22/77] Run `prettier` on src/commands/newProject.js --- src/commands/newProject.js | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 311b551..8bcdb7f 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -8,15 +8,24 @@ const initializeGitRepository = require("../util/initializeGitRepository"); const copyTemplateToDir = require("../util/copyTemplateToDir"); const selectTemplateIdx = async (templateNames) => { - console.log('Select a template to base your project off of (defaults to no template)'); - console.log('-----------------------------------------------------------------------'); + console.log( + "Select a template to base your project off of (defaults to no template)" + ); + console.log( + "-----------------------------------------------------------------------" + ); templateNames.forEach(([prettyName, rawName], idx) => { console.log(`${`[${idx + 1}]`.padStart(5)} ${prettyName} (${rawName})`); }); - console.log('-----------------------------------------------------------------------'); - const selectedIdx = Number(await promptAsync(`Select template 1-${templateNames.length}`, 'none')) - 1; + console.log( + "-----------------------------------------------------------------------" + ); + const selectedIdx = + Number( + await promptAsync(`Select template 1-${templateNames.length}`, "none") + ) - 1; if (Number.isNaN(selectedIdx) || !templateNames[selectedIdx]) { return -1; @@ -26,13 +35,13 @@ const selectTemplateIdx = async (templateNames) => { }; const createEmptyProject = (name) => { - fs.writeFileSync(`${name}/README.md`,''); - fs.writeFileSync(`${name}/definition.asl.json`,'{}'); + fs.writeFileSync(`${name}/README.md`, ""); + fs.writeFileSync(`${name}/definition.asl.json`, "{}"); fs.mkdirSync(`${name}/lambdas`); }; const cleanupAndCapitalize = (str) => { - const cleaned = str.replace(/[-_]/g,' '); + const cleaned = str.replace(/[-_]/g, " "); return capitalize(cleaned); }; @@ -65,7 +74,9 @@ const newProject = async (argv) => { const cleanSelectedTemplateName = templateNames[selectedTemplateIdx][0]; selectedTemplate = templateNames[selectedTemplateIdx][1]; - console.log(`Creating project based off of template ${cleanSelectedTemplateName}...`); + console.log( + `Creating project based off of template ${cleanSelectedTemplateName}...` + ); copyTemplateToDir(selectedTemplate, projectName); } else { From e7d388db39ca078dc79c8565c3aa8d1d124f7d26 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:36:46 -0600 Subject: [PATCH 23/77] Insert titleized version of project name into README.md when no template selected --- src/commands/newProject.js | 18 +++++++++++------ src/util/titleize.js | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 src/util/titleize.js diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 8bcdb7f..2d5e641 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -3,6 +3,7 @@ const fs = require("fs"); const configDir = require("../util/configDir"); const capitalize = require("../util/capitalize"); +const titleize = require("../util/titleize"); const promptAsync = require("../util/promptAsync"); const initializeGitRepository = require("../util/initializeGitRepository"); const copyTemplateToDir = require("../util/copyTemplateToDir"); @@ -34,17 +35,22 @@ const selectTemplateIdx = async (templateNames) => { } }; -const createEmptyProject = (name) => { - fs.writeFileSync(`${name}/README.md`, ""); - fs.writeFileSync(`${name}/definition.asl.json`, "{}"); - fs.mkdirSync(`${name}/lambdas`); -}; - const cleanupAndCapitalize = (str) => { const cleaned = str.replace(/[-_]/g, " "); return capitalize(cleaned); }; +const cleanupAndTitleize = (str) => { + const cleaned = str.replace(/[-_]/g, " "); + return titleize(cleaned); +}; + +const createEmptyProject = (name) => { + fs.writeFileSync(`${name}/README.md`, `# ${cleanupAndTitleize(name)}\n`); + fs.writeFileSync(`${name}/definition.asl.json`, "{}"); + fs.mkdirSync(`${name}/lambdas`); +}; + const newProject = async (argv) => { const projectName = argv._[1]; diff --git a/src/util/titleize.js b/src/util/titleize.js new file mode 100644 index 0000000..98f536d --- /dev/null +++ b/src/util/titleize.js @@ -0,0 +1,41 @@ +const capitalize = require("./capitalize"); + +const special = new Set(); +const specialArray = [ + 'and', + 'or', + 'to', + 'of', + 'for', + 'in', + 'the', + 'a', + 'an', + 'nor', + 'but', +]; + +specialArray.forEach((word) => special.add(word)); + +const titleize = (str) => { + if (str === '') return ''; + + const words = str.split(/\s/); + const middleWords = words.slice(1, words.length - 1); + const firstWord = words[0]; + const lastWord = words[words.length - 1]; + const resultWords = []; + + resultWords.push(capitalize(firstWord)); + + middleWords.forEach((word) => { + word = word.toLowerCase(); + resultWords.push(special.has(word) ? word : capitalize(word)); + }); + + resultWords.push(capitalize(lastWord)); + + return resultWords.join(' '); +}; + +module.exports = titleize; From 30ef2153f72fd85b02db3caba2dd85ed6f3b30ca Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:40:48 -0600 Subject: [PATCH 24/77] Fix inconsistencies --- src/commands/newProject.js | 2 +- src/util/titleize.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 2d5e641..b32356b 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -46,7 +46,7 @@ const cleanupAndTitleize = (str) => { }; const createEmptyProject = (name) => { - fs.writeFileSync(`${name}/README.md`, `# ${cleanupAndTitleize(name)}\n`); + fs.writeFileSync(`${name}/README.md`, `# ${cleanupAndTitleize(name)}\n\n`); fs.writeFileSync(`${name}/definition.asl.json`, "{}"); fs.mkdirSync(`${name}/lambdas`); }; diff --git a/src/util/titleize.js b/src/util/titleize.js index 98f536d..918da94 100644 --- a/src/util/titleize.js +++ b/src/util/titleize.js @@ -21,6 +21,10 @@ const titleize = (str) => { if (str === '') return ''; const words = str.split(/\s/); + if (words.length === 1) { + return capitalize(words[0]); + } + const middleWords = words.slice(1, words.length - 1); const firstWord = words[0]; const lastWord = words[words.length - 1]; From 46f09048567636980194e585da27eb952657c22d Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:41:46 -0600 Subject: [PATCH 25/77] Fix quoting issue in `initializeGitRepository` --- src/util/initializeGitRepository.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/initializeGitRepository.js b/src/util/initializeGitRepository.js index d5fe215..ec497de 100644 --- a/src/util/initializeGitRepository.js +++ b/src/util/initializeGitRepository.js @@ -1,7 +1,7 @@ const childProcess = require("child_process"); const initializeGitRepository = (dirname) => { - childProcess.execSync(`git init ${dirname}`); + childProcess.execSync(`git init '${dirname}'`); }; module.exports = initializeGitRepository; From b092d01ce6dac1e83f8f837affcf2c22c8d87708 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:50:57 -0600 Subject: [PATCH 26/77] Extract `selectTemplateIdx` to own file --- src/commands/newProject.js | 29 +---------------------------- src/util/selectTemplateIdx.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 28 deletions(-) create mode 100644 src/util/selectTemplateIdx.js diff --git a/src/commands/newProject.js b/src/commands/newProject.js index b32356b..8ea3071 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -4,36 +4,9 @@ const fs = require("fs"); const configDir = require("../util/configDir"); const capitalize = require("../util/capitalize"); const titleize = require("../util/titleize"); -const promptAsync = require("../util/promptAsync"); const initializeGitRepository = require("../util/initializeGitRepository"); const copyTemplateToDir = require("../util/copyTemplateToDir"); - -const selectTemplateIdx = async (templateNames) => { - console.log( - "Select a template to base your project off of (defaults to no template)" - ); - console.log( - "-----------------------------------------------------------------------" - ); - - templateNames.forEach(([prettyName, rawName], idx) => { - console.log(`${`[${idx + 1}]`.padStart(5)} ${prettyName} (${rawName})`); - }); - - console.log( - "-----------------------------------------------------------------------" - ); - const selectedIdx = - Number( - await promptAsync(`Select template 1-${templateNames.length}`, "none") - ) - 1; - - if (Number.isNaN(selectedIdx) || !templateNames[selectedIdx]) { - return -1; - } else { - return selectedIdx; - } -}; +const selectTemplateIdx = require("../util/selectTemplateIdx"); const cleanupAndCapitalize = (str) => { const cleaned = str.replace(/[-_]/g, " "); diff --git a/src/util/selectTemplateIdx.js b/src/util/selectTemplateIdx.js new file mode 100644 index 0000000..ac0087f --- /dev/null +++ b/src/util/selectTemplateIdx.js @@ -0,0 +1,30 @@ +const promptAsync = require("../util/promptAsync"); + +const selectTemplateIdx = async (templateNames) => { + console.log( + "Select a template to base your project off of (defaults to no template)" + ); + console.log( + "-----------------------------------------------------------------------" + ); + + templateNames.forEach(([prettyName, rawName], idx) => { + console.log(`${`[${idx + 1}]`.padStart(5)} ${prettyName} (${rawName})`); + }); + + console.log( + "-----------------------------------------------------------------------" + ); + const selectedIdx = + Number( + await promptAsync(`Select template 1-${templateNames.length}`, "none") + ) - 1; + + if (Number.isNaN(selectedIdx) || !templateNames[selectedIdx]) { + return -1; + } else { + return selectedIdx; + } +}; + +module.exports = selectTemplateIdx; From 117a3ac7e3be51f394d22bbb1689f45c38d07c56 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 20:55:04 -0600 Subject: [PATCH 27/77] Extract `createEmptyProject` to own file --- src/commands/newProject.js | 13 +------------ src/util/createEmptyProject.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 src/util/createEmptyProject.js diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 8ea3071..009bca5 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -3,27 +3,16 @@ const fs = require("fs"); const configDir = require("../util/configDir"); const capitalize = require("../util/capitalize"); -const titleize = require("../util/titleize"); const initializeGitRepository = require("../util/initializeGitRepository"); const copyTemplateToDir = require("../util/copyTemplateToDir"); const selectTemplateIdx = require("../util/selectTemplateIdx"); +const createEmptyProject = require("../util/createEmptyProject"); const cleanupAndCapitalize = (str) => { const cleaned = str.replace(/[-_]/g, " "); return capitalize(cleaned); }; -const cleanupAndTitleize = (str) => { - const cleaned = str.replace(/[-_]/g, " "); - return titleize(cleaned); -}; - -const createEmptyProject = (name) => { - fs.writeFileSync(`${name}/README.md`, `# ${cleanupAndTitleize(name)}\n\n`); - fs.writeFileSync(`${name}/definition.asl.json`, "{}"); - fs.mkdirSync(`${name}/lambdas`); -}; - const newProject = async (argv) => { const projectName = argv._[1]; diff --git a/src/util/createEmptyProject.js b/src/util/createEmptyProject.js new file mode 100644 index 0000000..fa1344f --- /dev/null +++ b/src/util/createEmptyProject.js @@ -0,0 +1,15 @@ +const fs = require("fs"); +const titleize = require("../util/titleize"); + +const cleanupAndTitleize = (str) => { + const cleaned = str.replace(/[-_]/g, " "); + return titleize(cleaned); +}; + +const createEmptyProject = (name) => { + fs.writeFileSync(`${name}/README.md`, `# ${cleanupAndTitleize(name)}\n\n`); + fs.writeFileSync(`${name}/definition.asl.json`, "{}"); + fs.mkdirSync(`${name}/lambdas`); +}; + +module.exports = createEmptyProject; From 560d3bf0d049abde3cfc1cd618144f2359cbf64c Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 21:14:17 -0600 Subject: [PATCH 28/77] Run `prettier --write .` on project root --- bin/maestro.js | 20 +++++++++++--------- src/aws/iam/establishIAMRole.js | 5 ++++- src/commands/deploy.js | 7 ++----- src/util/capitalize.js | 2 +- src/util/configDir.js | 4 ++-- src/util/copyTemplateToDir.js | 4 +++- src/util/titleize.js | 26 +++++++++++++------------- 7 files changed, 36 insertions(+), 32 deletions(-) diff --git a/bin/maestro.js b/bin/maestro.js index fd1bf84..6c5a4df 100755 --- a/bin/maestro.js +++ b/bin/maestro.js @@ -8,20 +8,22 @@ const argv = minimist(process.argv.slice(2), { roles: "", }, }); -const deploy = require('../src/commands/deploy'); -const teardown = require('../src/commands/teardown'); -const newProject = require('../src/commands/newProject'); +const deploy = require("../src/commands/deploy"); +const teardown = require("../src/commands/teardown"); +const newProject = require("../src/commands/newProject"); -switch(argv._[0]) { - case 'deploy': +switch (argv._[0]) { + case "deploy": deploy(); break; - case 'teardown': + case "teardown": teardown(argv); break; - case 'new': - newProject(argv) + case "new": + newProject(argv); break; default: - console.log(`See documentation for commands (i.e. deploy, teardown).\n https://github.com/maestro-framework/maestro`); + console.log( + `See documentation for commands (i.e. deploy, teardown).\n https://github.com/maestro-framework/maestro` + ); } diff --git a/src/aws/iam/establishIAMRole.js b/src/aws/iam/establishIAMRole.js index b21d7b8..29a65b6 100644 --- a/src/aws/iam/establishIAMRole.js +++ b/src/aws/iam/establishIAMRole.js @@ -1,5 +1,8 @@ const { iam } = require("../services"); -const { lambdaPolicyArns, statesPolicyArns } = require("../../config/policy-arn"); +const { + lambdaPolicyArns, + statesPolicyArns, +} = require("../../config/policy-arn"); const sleep = require("../../util/sleep"); const generateRoleParams = require("./generateRoleParams"); diff --git a/src/commands/deploy.js b/src/commands/deploy.js index c9ed60f..9ba0430 100644 --- a/src/commands/deploy.js +++ b/src/commands/deploy.js @@ -13,10 +13,7 @@ const deploy = () => { establishIAMRole(lambdaRoleName) .then(() => - generateMultipleFunctionParams( - basenamesAndZipBuffers, - lambdaRoleName - ) + generateMultipleFunctionParams(basenamesAndZipBuffers, lambdaRoleName) ) .then(createLambdaFunctions) .then(() => console.log("Successfully created function(s)")); @@ -26,6 +23,6 @@ const deploy = () => { .then(createStepFunction) .then(() => console.log("Successfully created state machine")) .catch(() => {}); -} +}; module.exports = deploy; diff --git a/src/util/capitalize.js b/src/util/capitalize.js index 63c7e6c..9059f48 100644 --- a/src/util/capitalize.js +++ b/src/util/capitalize.js @@ -1,5 +1,5 @@ const capitalize = (str) => { - if (str === '') return ''; + if (str === "") return ""; return str[0].toUpperCase() + str.slice(1).toLowerCase(); }; diff --git a/src/util/configDir.js b/src/util/configDir.js index ae8a27c..f529ff3 100644 --- a/src/util/configDir.js +++ b/src/util/configDir.js @@ -1,5 +1,5 @@ -const os = require('os'); +const os = require("os"); const homedir = os.homedir(); -const configDir = '.maestro'; +const configDir = ".maestro"; module.exports = `${homedir}/${configDir}`; diff --git a/src/util/copyTemplateToDir.js b/src/util/copyTemplateToDir.js index e526193..1dbcdcf 100644 --- a/src/util/copyTemplateToDir.js +++ b/src/util/copyTemplateToDir.js @@ -2,7 +2,9 @@ const childProcess = require("child_process"); const configDir = require("../util/configDir"); const copyTemplateToDir = (templateName, dirname) => { - childProcess.execSync(`cp -r ${configDir}/templates/${templateName}/* ${dirname}`); + childProcess.execSync( + `cp -r ${configDir}/templates/${templateName}/* ${dirname}` + ); }; module.exports = copyTemplateToDir; diff --git a/src/util/titleize.js b/src/util/titleize.js index 918da94..1516ca2 100644 --- a/src/util/titleize.js +++ b/src/util/titleize.js @@ -2,23 +2,23 @@ const capitalize = require("./capitalize"); const special = new Set(); const specialArray = [ - 'and', - 'or', - 'to', - 'of', - 'for', - 'in', - 'the', - 'a', - 'an', - 'nor', - 'but', + "and", + "or", + "to", + "of", + "for", + "in", + "the", + "a", + "an", + "nor", + "but", ]; specialArray.forEach((word) => special.add(word)); const titleize = (str) => { - if (str === '') return ''; + if (str === "") return ""; const words = str.split(/\s/); if (words.length === 1) { @@ -39,7 +39,7 @@ const titleize = (str) => { resultWords.push(capitalize(lastWord)); - return resultWords.join(' '); + return resultWords.join(" "); }; module.exports = titleize; From 17840f28efe2db914cf836c51cfcbb77e5b70fb5 Mon Sep 17 00:00:00 2001 From: John Isom Date: Fri, 7 Aug 2020 21:20:00 -0600 Subject: [PATCH 29/77] Add TODO section to newProject.js --- src/commands/newProject.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 009bca5..c2296b2 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -13,6 +13,9 @@ const cleanupAndCapitalize = (str) => { return capitalize(cleaned); }; +// TODO: add support for a `--no-template`/`-n` boolean flag +// and a `--template=`/`--template`/`-t` string flag, + const newProject = async (argv) => { const projectName = argv._[1]; From 6eea26b630a03d762290d17c0df43f9b21cea78a Mon Sep 17 00:00:00 2001 From: John Isom Date: Sat, 8 Aug 2020 08:25:53 -0600 Subject: [PATCH 30/77] Add `-n` and `--template`/`--no-template` flags for creating project without template prompts --- bin/maestro.js | 10 +++++----- src/commands/newProject.js | 12 ++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/bin/maestro.js b/bin/maestro.js index 6c5a4df..8d7cee9 100755 --- a/bin/maestro.js +++ b/bin/maestro.js @@ -1,16 +1,16 @@ #!/usr/bin/env node +const deploy = require("../src/commands/deploy"); +const teardown = require("../src/commands/teardown"); +const newProject = require("../src/commands/newProject"); const minimist = require("minimist"); const argv = minimist(process.argv.slice(2), { - boolean: ["f", "force"], - string: ["roles"], + boolean: ["f", "force", "n"], + string: ["roles", "template"], default: { roles: "", }, }); -const deploy = require("../src/commands/deploy"); -const teardown = require("../src/commands/teardown"); -const newProject = require("../src/commands/newProject"); switch (argv._[0]) { case "deploy": diff --git a/src/commands/newProject.js b/src/commands/newProject.js index c2296b2..afec52d 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -33,6 +33,18 @@ const newProject = async (argv) => { return; } + if (argv.n || argv.template === false) { + console.log("Creating project without template..."); + + createEmptyProject(projectName); + + initializeGitRepository(projectName); + + console.log(`Created project "${projectName}"!`); + + return; + } + // has structure of [["Example workflow", "example-workflow"], ...] const templateNames = fs.readdirSync(`${configDir}/templates`).map((name) => { return [cleanupAndCapitalize(name), name]; From 028f6923df2ad4c9add9e6fcf023abaefda5c804 Mon Sep 17 00:00:00 2001 From: John Isom Date: Sat, 8 Aug 2020 08:45:52 -0600 Subject: [PATCH 31/77] Add aliases for command line argument parsing --- bin/maestro.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/maestro.js b/bin/maestro.js index 8d7cee9..4c83246 100755 --- a/bin/maestro.js +++ b/bin/maestro.js @@ -5,8 +5,12 @@ const teardown = require("../src/commands/teardown"); const newProject = require("../src/commands/newProject"); const minimist = require("minimist"); const argv = minimist(process.argv.slice(2), { - boolean: ["f", "force", "n"], + boolean: ["force", "n"], string: ["roles", "template"], + alias: { + f: "force", + t: "template", + }, default: { roles: "", }, From ae9f0486d3908ae28813ba6c408e9da32ba09ecc Mon Sep 17 00:00:00 2001 From: John Isom Date: Sat, 8 Aug 2020 08:46:22 -0600 Subject: [PATCH 32/77] Allow specifying specific template from command line --- src/commands/newProject.js | 61 +++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index afec52d..ca04349 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -13,9 +13,6 @@ const cleanupAndCapitalize = (str) => { return capitalize(cleaned); }; -// TODO: add support for a `--no-template`/`-n` boolean flag -// and a `--template=`/`--template`/`-t` string flag, - const newProject = async (argv) => { const projectName = argv._[1]; @@ -33,44 +30,54 @@ const newProject = async (argv) => { return; } - if (argv.n || argv.template === false) { - console.log("Creating project without template..."); + const templateNames = fs.readdirSync(`${configDir}/templates`); - createEmptyProject(projectName); + if (argv.template && templateNames.includes(argv.template)) { + const cleanSelectedTemplateName = cleanupAndCapitalize(argv.template); + + console.log( + `Creating project based off of template ${cleanSelectedTemplateName}...` + ); + copyTemplateToDir(argv.template, projectName); initializeGitRepository(projectName); console.log(`Created project "${projectName}"!`); + } else if (argv.n || argv.template === false) { + console.log("Creating project without template..."); - return; - } + createEmptyProject(projectName); + initializeGitRepository(projectName); - // has structure of [["Example workflow", "example-workflow"], ...] - const templateNames = fs.readdirSync(`${configDir}/templates`).map((name) => { - return [cleanupAndCapitalize(name), name]; - }); + console.log(`Created project "${projectName}"!`); + } else { + const displayTemplateNames = templateNames.map((name) => { + // has structure of [["Example workflow", "example-workflow"], ...] + return [cleanupAndCapitalize(name), name]; + }); - const selectedTemplateIdx = await selectTemplateIdx(templateNames); - let selectedTemplate; + const selectedTemplateIdx = await selectTemplateIdx(displayTemplateNames); + let selectedTemplate; - if (selectedTemplateIdx !== -1) { - const cleanSelectedTemplateName = templateNames[selectedTemplateIdx][0]; - selectedTemplate = templateNames[selectedTemplateIdx][1]; + if (selectedTemplateIdx !== -1) { + const cleanSelectedTemplateName = templateNames[selectedTemplateIdx][0]; + selectedTemplate = templateNames[selectedTemplateIdx][1]; - console.log( - `Creating project based off of template ${cleanSelectedTemplateName}...` - ); + console.log( + `Creating project based off of template ${cleanSelectedTemplateName}...` + ); - copyTemplateToDir(selectedTemplate, projectName); - } else { - console.log("Creating project without template..."); + copyTemplateToDir(selectedTemplate, projectName); + } else { + console.log("Creating project without template..."); - createEmptyProject(projectName); - } + createEmptyProject(projectName); + } - initializeGitRepository(projectName); + initializeGitRepository(projectName); - console.log(`Created project "${projectName}"!`); + console.log(`Created project "${projectName}"!`); + } }; module.exports = newProject; From afd924f61109b686a14c99d4b1ec896b67949a61 Mon Sep 17 00:00:00 2001 From: John Isom Date: Sat, 8 Aug 2020 10:31:33 -0600 Subject: [PATCH 33/77] Extract common logic for creating projects to separate functions --- src/commands/newProject.js | 65 +++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index ca04349..e1b00ee 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -13,6 +13,28 @@ const cleanupAndCapitalize = (str) => { return capitalize(cleaned); }; +const createProjectFromTemplate = (projectName, templateName) => { + const cleanSelectedTemplateName = cleanupAndCapitalize(templateName); + + console.log( + `Creating project based off of template ${cleanSelectedTemplateName}...` + ); + + copyTemplateToDir(templateName, projectName); + initializeGitRepository(projectName); + + console.log(`Created project "${projectName}"!`); +}; + +const createProjectWithoutTemplate = (projectName) => { + console.log("Creating project without template..."); + + createEmptyProject(projectName); + initializeGitRepository(projectName); + + console.log(`Created project "${projectName}"!`); +}; + const newProject = async (argv) => { const projectName = argv._[1]; @@ -33,50 +55,21 @@ const newProject = async (argv) => { const templateNames = fs.readdirSync(`${configDir}/templates`); if (argv.template && templateNames.includes(argv.template)) { - const cleanSelectedTemplateName = cleanupAndCapitalize(argv.template); - - console.log( - `Creating project based off of template ${cleanSelectedTemplateName}...` - ); - - copyTemplateToDir(argv.template, projectName); - initializeGitRepository(projectName); - - console.log(`Created project "${projectName}"!`); + createProjectFromTemplate(projectName, argv.template); } else if (argv.n || argv.template === false) { - console.log("Creating project without template..."); - - createEmptyProject(projectName); - initializeGitRepository(projectName); - - console.log(`Created project "${projectName}"!`); + createProjectWithoutTemplate(projectName); } else { - const displayTemplateNames = templateNames.map((name) => { - // has structure of [["Example workflow", "example-workflow"], ...] - return [cleanupAndCapitalize(name), name]; - }); + // has structure of [["Example workflow", "example-workflow"], ...] + const displayTemplateNames = templateNames.map((name) => [cleanupAndCapitalize(name), name]); const selectedTemplateIdx = await selectTemplateIdx(displayTemplateNames); - let selectedTemplate; if (selectedTemplateIdx !== -1) { - const cleanSelectedTemplateName = templateNames[selectedTemplateIdx][0]; - selectedTemplate = templateNames[selectedTemplateIdx][1]; - - console.log( - `Creating project based off of template ${cleanSelectedTemplateName}...` - ); - - copyTemplateToDir(selectedTemplate, projectName); + const selectedTemplate = displayTemplateNames[selectedTemplateIdx][1]; + createProjectFromTemplate(projectName, selectedTemplate); } else { - console.log("Creating project without template..."); - - createEmptyProject(projectName); + createProjectWithoutTemplate(projectName); } - - initializeGitRepository(projectName); - - console.log(`Created project "${projectName}"!`); } }; From 7e2c9d378c9f3635511fa41156b94785b8c05caf Mon Sep 17 00:00:00 2001 From: John Isom Date: Sat, 8 Aug 2020 10:36:22 -0600 Subject: [PATCH 34/77] Extract cleanupAndCapitalize to own file --- src/commands/newProject.js | 7 +------ src/util/cleanupAndCapitalize.js | 8 ++++++++ 2 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 src/util/cleanupAndCapitalize.js diff --git a/src/commands/newProject.js b/src/commands/newProject.js index e1b00ee..5e634ab 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -2,16 +2,11 @@ const childProcess = require("child_process"); const fs = require("fs"); const configDir = require("../util/configDir"); -const capitalize = require("../util/capitalize"); const initializeGitRepository = require("../util/initializeGitRepository"); const copyTemplateToDir = require("../util/copyTemplateToDir"); const selectTemplateIdx = require("../util/selectTemplateIdx"); const createEmptyProject = require("../util/createEmptyProject"); - -const cleanupAndCapitalize = (str) => { - const cleaned = str.replace(/[-_]/g, " "); - return capitalize(cleaned); -}; +const cleanupAndCapitalize = require("../util/cleanupAndCapitalize"); const createProjectFromTemplate = (projectName, templateName) => { const cleanSelectedTemplateName = cleanupAndCapitalize(templateName); diff --git a/src/util/cleanupAndCapitalize.js b/src/util/cleanupAndCapitalize.js new file mode 100644 index 0000000..bef158e --- /dev/null +++ b/src/util/cleanupAndCapitalize.js @@ -0,0 +1,8 @@ +const capitalize = require("../util/capitalize"); + +const cleanupAndCapitalize = (str) => { + const cleaned = str.replace(/[-_]/g, " "); + return capitalize(cleaned); +}; + +module.exports = cleanupAndCapitalize; From bb74cb6be8f07c4334427a09499e3badeb8eaac7 Mon Sep 17 00:00:00 2001 From: John Isom Date: Sat, 8 Aug 2020 10:40:16 -0600 Subject: [PATCH 35/77] Extract createProjectFromTemplate/createProjectWithoutTemplate to own files --- src/commands/newProject.js | 27 ++---------------------- src/util/createProjectFromTemplate.js | 18 ++++++++++++++++ src/util/createProjectWithoutTemplate.js | 13 ++++++++++++ 3 files changed, 33 insertions(+), 25 deletions(-) create mode 100644 src/util/createProjectFromTemplate.js create mode 100644 src/util/createProjectWithoutTemplate.js diff --git a/src/commands/newProject.js b/src/commands/newProject.js index 5e634ab..a3dd6bc 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -2,33 +2,10 @@ const childProcess = require("child_process"); const fs = require("fs"); const configDir = require("../util/configDir"); -const initializeGitRepository = require("../util/initializeGitRepository"); -const copyTemplateToDir = require("../util/copyTemplateToDir"); const selectTemplateIdx = require("../util/selectTemplateIdx"); -const createEmptyProject = require("../util/createEmptyProject"); const cleanupAndCapitalize = require("../util/cleanupAndCapitalize"); - -const createProjectFromTemplate = (projectName, templateName) => { - const cleanSelectedTemplateName = cleanupAndCapitalize(templateName); - - console.log( - `Creating project based off of template ${cleanSelectedTemplateName}...` - ); - - copyTemplateToDir(templateName, projectName); - initializeGitRepository(projectName); - - console.log(`Created project "${projectName}"!`); -}; - -const createProjectWithoutTemplate = (projectName) => { - console.log("Creating project without template..."); - - createEmptyProject(projectName); - initializeGitRepository(projectName); - - console.log(`Created project "${projectName}"!`); -}; +const createProjectFromTemplate = require("../util/createProjectFromTemplate"); +const createProjectWithoutTemplate = require("../util/createProjectWithoutTemplate"); const newProject = async (argv) => { const projectName = argv._[1]; diff --git a/src/util/createProjectFromTemplate.js b/src/util/createProjectFromTemplate.js new file mode 100644 index 0000000..19bff8a --- /dev/null +++ b/src/util/createProjectFromTemplate.js @@ -0,0 +1,18 @@ +const initializeGitRepository = require("../util/initializeGitRepository"); +const copyTemplateToDir = require("../util/copyTemplateToDir"); +const cleanupAndCapitalize = require("../util/cleanupAndCapitalize"); + +const createProjectFromTemplate = (projectName, templateName) => { + const cleanSelectedTemplateName = cleanupAndCapitalize(templateName); + + console.log( + `Creating project based off of template ${cleanSelectedTemplateName}...` + ); + + copyTemplateToDir(templateName, projectName); + initializeGitRepository(projectName); + + console.log(`Created project "${projectName}"!`); +}; + +module.exports = createProjectFromTemplate; diff --git a/src/util/createProjectWithoutTemplate.js b/src/util/createProjectWithoutTemplate.js new file mode 100644 index 0000000..2a1d29e --- /dev/null +++ b/src/util/createProjectWithoutTemplate.js @@ -0,0 +1,13 @@ +const initializeGitRepository = require("../util/initializeGitRepository"); +const createEmptyProject = require("../util/createEmptyProject"); + +const createProjectWithoutTemplate = (projectName) => { + console.log("Creating project without template..."); + + createEmptyProject(projectName); + initializeGitRepository(projectName); + + console.log(`Created project "${projectName}"!`); +}; + +module.exports = createProjectWithoutTemplate; From 151106b0718c97247c85bd09056212a63a18fe48 Mon Sep 17 00:00:00 2001 From: John Isom Date: Sat, 8 Aug 2020 11:40:00 -0600 Subject: [PATCH 36/77] Run `prettier --write .` on project root --- src/commands/newProject.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/commands/newProject.js b/src/commands/newProject.js index a3dd6bc..0b4218d 100644 --- a/src/commands/newProject.js +++ b/src/commands/newProject.js @@ -32,7 +32,10 @@ const newProject = async (argv) => { createProjectWithoutTemplate(projectName); } else { // has structure of [["Example workflow", "example-workflow"], ...] - const displayTemplateNames = templateNames.map((name) => [cleanupAndCapitalize(name), name]); + const displayTemplateNames = templateNames.map((name) => [ + cleanupAndCapitalize(name), + name, + ]); const selectedTemplateIdx = await selectTemplateIdx(displayTemplateNames); From e723cc657dba53a6998ed8f6f1e0ade868bdeabe Mon Sep 17 00:00:00 2001 From: John Isom Date: Sat, 8 Aug 2020 11:53:50 -0600 Subject: [PATCH 37/77] Update README.md --- README.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b998319..7e05813 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,20 @@ In the `templates` directory lie an assortment of template Maestro projects to h To use, you must have the [AWS CLI][aws-cli] installed and set up. -1. Clone this repository (`git clone https://github.com/maestro-framework/maestro.git`) -2. Change directory into the newly cloned repo (`cd maestro`) -3. Install npm packages (`npm install`) -4. Place all lambda files (directories not supported yet) into the `lambdas` directory -5. Place state machine definition(s) into the `state-machines` directory -6. Create a file called `aws_account_info.json` under `~/.config/maestro/` that looks like this (change info to your specific needs): +1. Clone this repository (`git clone https://github.com/maestro-framework/maestro.git /path/to/maestro`) +2. Install the npm package globally (`sudo npm -g install /path/to/maestro`) +3. Create a new project with `maestro new [-n|--no-template|--template=