terraguardian-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +7 -0
- package/.eslintrc.yaml +12 -0
- package/.gitlab-ci.yml +5 -0
- package/.prettierrc +6 -0
- package/README.md +48 -0
- package/jest.config.js +21 -0
- package/package.json +41 -0
- package/src/common/constants.js +22 -0
- package/src/common/helpers.js +84 -0
- package/src/features/deploy.js +65 -0
- package/src/features/scan/tfModulesScanner.js +50 -0
- package/src/fs-utils/DirHandler.js +0 -0
- package/src/fs-utils/FileHandler.js +45 -0
- package/src/fs-utils/TfFileHandler.js +43 -0
- package/src/index.js +46 -0
- package/test/main.test.js +3 -0
package/.babelrc
ADDED
package/.eslintrc.yaml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
extends:
|
|
2
|
+
- airbnb-base
|
|
3
|
+
- plugin:import/errors
|
|
4
|
+
- plugin:import/warnings
|
|
5
|
+
rules:
|
|
6
|
+
prefer-destructuring: off
|
|
7
|
+
no-template-curly-in-string: warn
|
|
8
|
+
no-return-await: off
|
|
9
|
+
no-await-in-loop: warn
|
|
10
|
+
no-plusplus: off
|
|
11
|
+
import/extensions: off
|
|
12
|
+
import/no-unresolved: "off"
|
package/.gitlab-ci.yml
ADDED
package/.prettierrc
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# terraguardian-cli
|
|
2
|
+
|
|
3
|
+
# Working with the
|
|
4
|
+
|
|
5
|
+
## Step 1: Install the Package
|
|
6
|
+
|
|
7
|
+
Navigate to the root directory of your package in the terminal:
|
|
8
|
+
cd /path/to/your-package-name
|
|
9
|
+
Install the package dependencies:
|
|
10
|
+
npm install
|
|
11
|
+
|
|
12
|
+
## Step 2: Link the Package Globally
|
|
13
|
+
|
|
14
|
+
Run the following command to create a global symbolic link for your package:
|
|
15
|
+
npm link
|
|
16
|
+
This command will create a symbolic link to your package in the global node_modules directory, making it accessible from anywhere on your system.
|
|
17
|
+
|
|
18
|
+
## Step 3: Link the Package Locally
|
|
19
|
+
|
|
20
|
+
Navigate to the directory of your project where you want to use the package:
|
|
21
|
+
cd /path/to/your-project
|
|
22
|
+
Link the package to your project using its name:
|
|
23
|
+
npm link your-package-name
|
|
24
|
+
Replace your-package-name with the actual name of your package.
|
|
25
|
+
|
|
26
|
+
## Step 4: Use the Package in Your Project
|
|
27
|
+
|
|
28
|
+
Now you can use the package in your project as if it were installed from npm. For example, you can import it into your code:
|
|
29
|
+
|
|
30
|
+
const yourPackage = require('your-package-name');
|
|
31
|
+
|
|
32
|
+
## Step 5: Test the Package
|
|
33
|
+
|
|
34
|
+
You can test the package locally by running the tests located in the test/ directory. Use the following command:
|
|
35
|
+
npm test
|
|
36
|
+
This will execute the test suite for your package and provide feedback on its functionality.
|
|
37
|
+
|
|
38
|
+
## Step 6: Make Changes and Iterate
|
|
39
|
+
|
|
40
|
+
You can make changes to your package code and repeat the testing process as needed. Since you've linked the package globally, any changes you make to the package code will be reflected immediately in your project without the need to reinstall it.
|
|
41
|
+
|
|
42
|
+
## Step 7: Cleanup (Optional)
|
|
43
|
+
|
|
44
|
+
Once you're done testing and no longer need the global link, you can remove it using:
|
|
45
|
+
npm unlink
|
|
46
|
+
This will remove the global symbolic link created for your package.
|
|
47
|
+
|
|
48
|
+
That's it! You've successfully installed, tested, and used your package locally using npm link.
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
roots: ['<rootDir>'],
|
|
3
|
+
moduleFileExtensions: ['js', 'json'],
|
|
4
|
+
testEnvironment: 'node',
|
|
5
|
+
testRegex: '\\.test\\.js$',
|
|
6
|
+
transform: {
|
|
7
|
+
'^.+\\.js$': 'babel-jest',
|
|
8
|
+
},
|
|
9
|
+
collectCoverage: true,
|
|
10
|
+
coverageDirectory: 'test/coverage',
|
|
11
|
+
collectCoverageFrom: ['<rootDir>/src/**/*.js'],
|
|
12
|
+
coveragePathIgnorePatterns: ['/node_modules/', '/build/', '/dist/'], // Add paths to ignore here
|
|
13
|
+
coverageThreshold: {
|
|
14
|
+
global: {
|
|
15
|
+
branches: 0,
|
|
16
|
+
functions: 0,
|
|
17
|
+
lines: 0,
|
|
18
|
+
statements: 0,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "terraguardian-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI that helps with projects that are built with terraform and helps with deployments of lambda src code",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"tg-cli": "src/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "jest",
|
|
11
|
+
"lint": "eslint src",
|
|
12
|
+
"format": "prettier --write ."
|
|
13
|
+
},
|
|
14
|
+
"scope": "@urbangemfinder",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://gitlab.com/grp-development-utils/terraguardian-cli.git"
|
|
18
|
+
},
|
|
19
|
+
"author": "Martin Colmenero",
|
|
20
|
+
"license": "ISC",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://gitlab.com/grp-development-utils/terraguardian-cli/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://gitlab.com/grp-development-utils/terraguardian-cli#readme",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"archiver": "^7.0.0",
|
|
27
|
+
"chalk": "^4.0.0",
|
|
28
|
+
"inquirer": "^8.0.0",
|
|
29
|
+
"yargs": "^17.7.2"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@babel/core": "^7.24.0",
|
|
33
|
+
"@babel/preset-env": "^7.24.0",
|
|
34
|
+
"babel-jest": "^29.7.0",
|
|
35
|
+
"eslint": "^8.57.0",
|
|
36
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
37
|
+
"eslint-plugin-import": "^2.29.1",
|
|
38
|
+
"jest": "^29.7.0",
|
|
39
|
+
"prettier": "^3.2.5"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const NODE_ENTRY_POINT = process.env.NODE_ENTRY_POINT || 'index.js';
|
|
2
|
+
const WEBPACK_FILE_PATH = process.env.WEBPACK_FILE_PATH || 'webpack.config.js';
|
|
3
|
+
const NODE_LIBARY_TYPE = process.env.NODE_LIBARY_TYPE || 'commonjs2';
|
|
4
|
+
const DEFAULT_WEBPACK_MODE = process.env.DEFAULT_WEBPACK_MODE || 'production';
|
|
5
|
+
const NODE_BUILD_FILE_NAME = process.env.NODE_BUILD_FILE_NAME || 'index.js';
|
|
6
|
+
|
|
7
|
+
const NODE_RUNTIME_TF_VAR = 'node_runtime';
|
|
8
|
+
const GO_RUNTIME_TF_VAR = 'go_runtime';
|
|
9
|
+
const LAMBDA_BUILD_DIR = 'build';
|
|
10
|
+
const GO_ENTRY_POINT = process.env.GO_ENTRY_POINT || 'main.go';
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
DEFAULT_WEBPACK_MODE,
|
|
14
|
+
GO_ENTRY_POINT,
|
|
15
|
+
GO_RUNTIME_TF_VAR,
|
|
16
|
+
LAMBDA_BUILD_DIR,
|
|
17
|
+
NODE_BUILD_FILE_NAME,
|
|
18
|
+
NODE_ENTRY_POINT,
|
|
19
|
+
NODE_LIBARY_TYPE,
|
|
20
|
+
NODE_RUNTIME_TF_VAR,
|
|
21
|
+
WEBPACK_FILE_PATH,
|
|
22
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const util = require('util');
|
|
2
|
+
const FileHandler = require('../fs-utils/FileHandler');
|
|
3
|
+
const exec = util.promisify(require('child_process').exec);
|
|
4
|
+
|
|
5
|
+
async function executeCommand(command) {
|
|
6
|
+
const { stdout, stderr } = await exec(command);
|
|
7
|
+
if (stderr) {
|
|
8
|
+
throw new Error(stderr);
|
|
9
|
+
}
|
|
10
|
+
return stdout;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getLineOfInterest(
|
|
14
|
+
fileLines,
|
|
15
|
+
keyword,
|
|
16
|
+
checkForEndOfCodeBlock,
|
|
17
|
+
checkForLineOfInterest,
|
|
18
|
+
) {
|
|
19
|
+
let keywordFound;
|
|
20
|
+
let lineOfInterest;
|
|
21
|
+
let indexOfInterest;
|
|
22
|
+
// eslint-disable-next-line
|
|
23
|
+
for (const [index, line] of fileLines.entries()) {
|
|
24
|
+
if (line.incluedes(keyword)) {
|
|
25
|
+
keywordFound = true;
|
|
26
|
+
} else if (keywordFound) {
|
|
27
|
+
if (checkForEndOfCodeBlock(line)) {
|
|
28
|
+
break;
|
|
29
|
+
} else if (checkForLineOfInterest(line)) {
|
|
30
|
+
lineOfInterest = line;
|
|
31
|
+
indexOfInterest = index;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { line: lineOfInterest, index: indexOfInterest };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function checkVarEndOfBlock(line) {
|
|
40
|
+
return line.trim() === '}';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function checkVarMatch(line) {
|
|
44
|
+
return line.split('=')[0].trim() === 'default';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getTfVarsDefaultValueLine(tfVarsFileLines, varName) {
|
|
48
|
+
return getLineOfInterest(
|
|
49
|
+
tfVarsFileLines,
|
|
50
|
+
`variable "${varName}"`,
|
|
51
|
+
checkVarEndOfBlock,
|
|
52
|
+
checkVarMatch,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function getProjectShortName() {
|
|
57
|
+
const varsTfFilesLines = await FileHandler.getFileLines('./src/vars.tf');
|
|
58
|
+
const { line } = getTfVarsDefaultValueLine(
|
|
59
|
+
varsTfFilesLines,
|
|
60
|
+
'project_short_name',
|
|
61
|
+
);
|
|
62
|
+
if (line) {
|
|
63
|
+
const projShortNameWithQuotes = line.split('default')[1].split('= ')[1];
|
|
64
|
+
return projShortNameWithQuotes.replace(/['"]+/g, '');
|
|
65
|
+
}
|
|
66
|
+
throw new Error('Could not find project short name');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function getFormattedGitBranch() {
|
|
70
|
+
const { stdout } = await executeCommand('git branch --show-current');
|
|
71
|
+
return stdout.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function getBranchPrefix() {
|
|
75
|
+
return `${await getProjectShortName()}${await getFormattedGitBranch()}`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = {
|
|
79
|
+
executeCommand,
|
|
80
|
+
getTfVarsDefaultValueLine,
|
|
81
|
+
getBranchPrefix,
|
|
82
|
+
getProjectShortName,
|
|
83
|
+
getFormattedGitBranch,
|
|
84
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
const { getDetailedLambdaInfo } = require('./scan/tfModulesScanner');
|
|
6
|
+
const { zipLambdas } = require('./build/zip');
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
NODE_RUNTIME_TF_VAR,
|
|
10
|
+
GO_RUNTIME_TF_VAR,
|
|
11
|
+
LAMBDA_BUILD_DIR,
|
|
12
|
+
NODE_ENTRY_POINT,
|
|
13
|
+
GO_ENTRY_POINT,
|
|
14
|
+
} = require('../common/constants');
|
|
15
|
+
const { getBranchPrefix, executeCommand } = require('../common/helpers');
|
|
16
|
+
const { findEntryPoints } = require('./build/helpers');
|
|
17
|
+
const { buildNodeLambda } = require('./build/node-build');
|
|
18
|
+
const { buildGoLambda } = require('./build/go-build');
|
|
19
|
+
|
|
20
|
+
const SUPPORTED_RUNTIMES = [NODE_RUNTIME_TF_VAR, GO_RUNTIME_TF_VAR];
|
|
21
|
+
|
|
22
|
+
async function deployToAws(zipOutputDir, awsLambdaName) {
|
|
23
|
+
console.log(chalk.blue(`Deploying ${awsLambdaName} to AWS...`));
|
|
24
|
+
|
|
25
|
+
const deployCommand = `aws lambda update-function-code --function-name ${awsLambdaName} --zip-file fileb://${zipOutputDir} 1> /dev/null`;
|
|
26
|
+
await executeCommand(deployCommand);
|
|
27
|
+
console.log(chalk.green(`Successfully deployed ${awsLambdaName} to AWS!`));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function deployLambda() {
|
|
31
|
+
const lambdaResources = await getDetailedLambdaInfo(path.resolve(), '.tf');
|
|
32
|
+
const lambdaToDeployPrompt = {
|
|
33
|
+
type: 'list',
|
|
34
|
+
name: 'lambdaToDeploy',
|
|
35
|
+
message: 'Choose a lambda to deploy to AWS',
|
|
36
|
+
choices: lambdaResources
|
|
37
|
+
.filter((res) => SUPPORTED_RUNTIMES.includes(res.runtime))
|
|
38
|
+
.map((res) => res.lambdaName),
|
|
39
|
+
};
|
|
40
|
+
const response = await inquirer.createPromptModule(lambdaToDeployPrompt);
|
|
41
|
+
const { terraformName, runtime, lambdaName } = lambdaResources.find(
|
|
42
|
+
(res) => res.lambdaName === response.lambdaToDeploy,
|
|
43
|
+
);
|
|
44
|
+
const awsLambdaName = `${await getBranchPrefix()}-${lambdaName}}`;
|
|
45
|
+
|
|
46
|
+
console.log(`Full name is ${awsLambdaName}`);
|
|
47
|
+
const runtimeEntryPoint = {
|
|
48
|
+
[NODE_RUNTIME_TF_VAR]: NODE_ENTRY_POINT,
|
|
49
|
+
[GO_RUNTIME_TF_VAR]: GO_ENTRY_POINT,
|
|
50
|
+
}[runtime];
|
|
51
|
+
const entryPointPath = findEntryPoints(runtimeEntryPoint, terraformName);
|
|
52
|
+
|
|
53
|
+
const buildFunction = {
|
|
54
|
+
[NODE_RUNTIME_TF_VAR]: buildNodeLambda,
|
|
55
|
+
[GO_RUNTIME_TF_VAR]: buildGoLambda,
|
|
56
|
+
}[runtime];
|
|
57
|
+
await buildFunction(terraformName, entryPointPath);
|
|
58
|
+
|
|
59
|
+
const zipOutputDir = await zipLambdas(LAMBDA_BUILD_DIR, [terraformName]);
|
|
60
|
+
await deployToAws(`dist/${zipOutputDir}`, awsLambdaName);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = {
|
|
64
|
+
deployLambda,
|
|
65
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const TfFileHandler = require('../../fs-utils/TfFileHandler');
|
|
3
|
+
const DirectoryHandler = require('../../fs-utils/DirHandler');
|
|
4
|
+
|
|
5
|
+
async function scanForTfModules(
|
|
6
|
+
startPath,
|
|
7
|
+
filter,
|
|
8
|
+
versionData,
|
|
9
|
+
options,
|
|
10
|
+
scanPromises = [],
|
|
11
|
+
) {
|
|
12
|
+
const files = await DirectoryHandler.readDirectory(startPath);
|
|
13
|
+
for (let i = 0; i < files.length; i++) {
|
|
14
|
+
const filename = files[i];
|
|
15
|
+
const stat = fs.lstatSync(filename);
|
|
16
|
+
if (stat.isDirectory()) {
|
|
17
|
+
await scanForTfModules(
|
|
18
|
+
filename,
|
|
19
|
+
filter,
|
|
20
|
+
versionData,
|
|
21
|
+
options,
|
|
22
|
+
scanPromises,
|
|
23
|
+
); // recurse
|
|
24
|
+
} else if (filename.endsWith(filter)) {
|
|
25
|
+
try {
|
|
26
|
+
scanPromises.push(
|
|
27
|
+
(await options) && options.getDetailedLambdaInfo
|
|
28
|
+
? TfFileHandler.parseLambdaFile(filename)
|
|
29
|
+
: TfFileHandler.parseFile(filename, versionData, options),
|
|
30
|
+
);
|
|
31
|
+
} catch (e) {
|
|
32
|
+
console.log(e);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return await scanPromises;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function getDetailedLambdaInfo(startPath) {
|
|
40
|
+
const promises = await scanForTfModules(startPath, '.tf', null, {
|
|
41
|
+
getDetailedLambdaInfo: true,
|
|
42
|
+
});
|
|
43
|
+
const scannedFiles = await Promise.all(promises);
|
|
44
|
+
return scannedFiles.filter((moduleInfo) => moduleInfo);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = {
|
|
48
|
+
getDetailedLambdaInfo,
|
|
49
|
+
scanForTfModules,
|
|
50
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const fsp = require('fs').promises;
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
|
|
6
|
+
class FileHandler {
|
|
7
|
+
static async readFile(filePath) {
|
|
8
|
+
try {
|
|
9
|
+
return await fsp.readFile(filePath, 'utf-8');
|
|
10
|
+
} catch (error) {
|
|
11
|
+
console.error(`Error reading file ${filePath}: ${error.message}`);
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static async writeFile(filePath, fileData, successMessage, failMessage) {
|
|
17
|
+
try {
|
|
18
|
+
const content = await fsp.writeFiile(filePath, fileData, 'utf8');
|
|
19
|
+
if (successMessage) console.log(chalk.green(successMessage));
|
|
20
|
+
return content;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
console.log(chalk.red(failMessage));
|
|
23
|
+
throw err;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static async stat(filePath) {
|
|
28
|
+
return fsp.stat(filePath);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static doesPathExist(path) {
|
|
32
|
+
return fs.existsSync(path);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static doesFileExist(filename) {
|
|
36
|
+
return fs.existsSync(filename);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static async getFileLines(filePath) {
|
|
40
|
+
const content = await this.readFile(filePath);
|
|
41
|
+
return content.split(/\r?\n/);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = FileHandler;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const FileHandler = require('./FileHandler');
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line
|
|
5
|
+
class TfFileHandler {
|
|
6
|
+
static async parseLambdaFile(filename) {
|
|
7
|
+
const lambdaDetails = {};
|
|
8
|
+
const fileLines = await FileHandler.getFileLines(filename);
|
|
9
|
+
|
|
10
|
+
fileLines.forEach((line) => {
|
|
11
|
+
const isModuleLine = line.includes('module');
|
|
12
|
+
const isRuntimeLine = line.includes('runtime');
|
|
13
|
+
const isLambdaNameLine = line.includes('Lambda_name =');
|
|
14
|
+
if (isModuleLine) {
|
|
15
|
+
const terraformName = line.split(' ')[1].replace(/"|'/g, '');
|
|
16
|
+
if (terraformName.includes('lambda')) {
|
|
17
|
+
lambdaDetails.terraformName = terraformName;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (isLambdaNameLine) {
|
|
21
|
+
const splitBranchPrefix = line.split('${local.branch_prefix}-')[1]; // estint-disable-line no-template-curly-in-string
|
|
22
|
+
if (splitBranchPrefix) {
|
|
23
|
+
lambdaDetails.lambdaName = splitBranchPrefix.replace('"', '').trim();
|
|
24
|
+
} else {
|
|
25
|
+
const trimmedLambdaName = line
|
|
26
|
+
.split('lambda_name')[1]
|
|
27
|
+
.split('=')[1]
|
|
28
|
+
.replace(/['"]+/g, '')
|
|
29
|
+
.trim();
|
|
30
|
+
console.log(
|
|
31
|
+
chalk.red(
|
|
32
|
+
`Lambda "${trimmedLambdaName}" does not follow required naming convention using branch_prefix. Lambda will be excluded.`,
|
|
33
|
+
),
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (isRuntimeLine) {
|
|
38
|
+
lambdaDetails.runtime = line.split('= var.')[1] && line.split('= var.')[1].trim();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return lambdaDetails;
|
|
42
|
+
}
|
|
43
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const yargs = require('yargs');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const { zipAndMoveFolders } = require('./features/build/zip');
|
|
6
|
+
const { buildNodeLambdas } = require('./features/build/node-build');
|
|
7
|
+
const { deployLambda } = require('./features/deploy');
|
|
8
|
+
|
|
9
|
+
const usage = chalk.keyword('violet')('\nUsage: tg-cli [<command> [, options]]');
|
|
10
|
+
const argv = yargs
|
|
11
|
+
.version('1.0.0')
|
|
12
|
+
.usage(usage)
|
|
13
|
+
.option('z', {
|
|
14
|
+
alias: 'zip',
|
|
15
|
+
describe: 'Zip folders found in the build folder and move to dist',
|
|
16
|
+
type: 'boolean',
|
|
17
|
+
})
|
|
18
|
+
.option('N', {
|
|
19
|
+
alias: 'node-build',
|
|
20
|
+
describe: 'Build Node Lambdas',
|
|
21
|
+
type: 'boolean',
|
|
22
|
+
})
|
|
23
|
+
.option('d', {
|
|
24
|
+
alias: 'deploy',
|
|
25
|
+
describe: 'deploy a lambda',
|
|
26
|
+
type: 'boolean',
|
|
27
|
+
})
|
|
28
|
+
.help(true)
|
|
29
|
+
.alias('h', 'help').argv;
|
|
30
|
+
|
|
31
|
+
async function executeUserCommand(userCommands) {
|
|
32
|
+
if (userCommands.z || userCommands.zip) {
|
|
33
|
+
zipAndMoveFolders('build', 'dist');
|
|
34
|
+
console.log('zipping');
|
|
35
|
+
} else if (userCommands.d || userCommands.deploy) {
|
|
36
|
+
console.log('deploying');
|
|
37
|
+
await deployLambda();
|
|
38
|
+
} else if (userCommands.N || userCommands['node-build']) {
|
|
39
|
+
console.log('building node lambda');
|
|
40
|
+
await buildNodeLambdas();
|
|
41
|
+
} else {
|
|
42
|
+
yargs.showHelp();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
executeUserCommand(argv);
|