Skip to content
This repository was archived by the owner on Jun 28, 2022. It is now read-only.

Commit

Permalink
fix: issue #13 (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
arantespp authored Feb 2, 2021
1 parent 07527bd commit f7e6f72
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 27 deletions.
4 changes: 3 additions & 1 deletion packages/cli/jest.config.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
module.exports = require('../../config/jest.config.base')(__dirname);
const config = require('../../config/jest.config.base')(__dirname);

module.exports = { ...config, collectCoverage: false };
56 changes: 56 additions & 0 deletions packages/cli/src/cli.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* eslint-disable import/first */
import * as faker from 'faker';

const optionsFromConfigFiles = {
option: faker.random.word(),
optionEnv: faker.random.word(),
environments: {
Production: {
optionEnv: faker.random.word(),
},
},
};

jest.mock('deepmerge', () => ({
all: jest.fn().mockReturnValue(optionsFromConfigFiles),
}));

import cli from './cli';

describe('handle options correctly', () => {
test('argv must have the options passed to CLI', () => {
const options = {
region: faker.random.word(),
};
cli.parse('print-args', options, (_err, argv) => {
expect(argv).toMatchObject(options);
expect(argv).toMatchObject(options);
});
});

test('argv must have the environment option', () => {
cli.parse(
'print-args',
{ environment: 'Production' },
(_err: any, argv: any) => {
expect(argv.optionEnv).toEqual(
optionsFromConfigFiles.environments.Production.optionEnv,
);
},
);
});

test('argv must have the CLI optionEnv', () => {
const newOptionEnv = faker.random.word();
cli.parse(
'print-args',
{
environment: 'Production',
optionEnv: newOptionEnv,
},
(_err: any, argv: any) => {
expect(argv.optionEnv).toEqual(newOptionEnv);
},
);
});
});
20 changes: 13 additions & 7 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import { NAME } from './config';
import { deployCommand } from './deploy/command';
import { setEnvironment, readObjectFile } from './utils';

let finalConfig: any;

/**
* Get all carlin configs from directories.
*/
const getConfig = () => {
export const getConfig = () => {
const names = ['js', 'yml', 'yaml', 'json'].map((ext) => `${NAME}.${ext}`);
const paths = [];
let currentPath = process.cwd();
Expand All @@ -32,7 +34,7 @@ const getConfig = () => {
* Using configs.reverser() to get the most far config first. This way the
* nearest configs will replace others.
*/
const finalConfig: any = deepmerge.all(configs.reverse());
finalConfig = deepmerge.all(configs.reverse());

return finalConfig;
};
Expand All @@ -57,19 +59,23 @@ yargs
},
type: 'string',
},
environments: {
type: 'string',
},
environments: {},
})
.middleware((argv) => {
const { environment, environments } = argv as any;

/**
* Create final options with environment and environments.
*/
if (environment && environments && environments[environment as string]) {
Object.entries(environments[environment]).forEach(([key, value]) => {
// eslint-disable-next-line no-param-reassign
argv[key] = value;
/**
* Fixes #13 https://github.com/ttoss/carlin/issues/13
*/
if (!argv[key] || argv[key] === finalConfig[key]) {
// eslint-disable-next-line no-param-reassign
argv[key] = value;
}
});
}
})
Expand Down
18 changes: 10 additions & 8 deletions packages/cli/src/deploy/staticApp/staticApp.template.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
getStaticAppTemplate,
generateCspString,
getLambdaEdgeOriginResponseZipFile,
CLOUDFRONT_DISTRIBUTION_LOGICAL_ID,
} from './staticApp.template';
/* eslint-disable import/first */

/**
* Mock to snapshots don't fail.
Expand All @@ -12,11 +7,18 @@ Date.now = jest.fn(() => 1487076708000);
const PACKAGE_VERSION = '10.40.23';

jest.mock('../../utils', () => ({
getPackageVersion: jest.fn().mockReturnValue('10.40.23'),
getPackageVersion: jest.fn().mockReturnValue(PACKAGE_VERSION),
}));

import {
getStaticAppTemplate,
generateCspString,
getLambdaEdgeOriginResponseZipFile,
CLOUDFRONT_DISTRIBUTION_LOGICAL_ID,
} from './staticApp.template';

const defaultCspString =
"default-src 'self'; connect-src 'self' https:; img-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/; font-src 'self' https://fonts.gstatic.com/; object-src 'none'";
"default-src 'self'; connect-src 'self' https:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/; font-src 'self' https://fonts.gstatic.com/; object-src 'none'";

describe("fix issue 'Filter CSP directives' #11 https://github.com/ttoss/carlin/issues/11", () => {
test('generate default CSP', () => {
Expand Down
32 changes: 32 additions & 0 deletions packages/website/docs/CLI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: CLI
---

## Environments

**carlin** was projected to work with environments. As we've been building a lot of Apps, we realized that we commonly have some environments, like production and staging. The difference between these environments was some options values that we passed to the deploy command. To handle these options, we've created the `environments` option. It receives an object whose keys are the environment name and the values are an object containing the command options.

Besides `environments`, if we provide the option `-e`, `--env` or `--environment`, **carlin** searches if such environment exists inside `environments` object and assign the values to the command. For instance, suppose that we have the `carlin.yml` below.

```yaml title="carlin.yml"
region: us-east-1
environments:
Production:
region: ap-south-1
```
The `region` value will be, for each command:

| Command | `region` |
| ------------------------------------------------ | -------------- |
| `carlin deploy` | **us-east-1** |
| `carlin deploy --region eu-west-1` | **eu-west-1** |
| `carlin deploy -e production`\* | **us-east-1** |
| `carlin deploy -e Production` | **ap-south-1** |
| `carlin deploy -e Production --region eu-west-1` | **eu-west-1** |

:::note

\* `environment` is case sensitive.

:::
16 changes: 7 additions & 9 deletions packages/website/docs/deploy.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
---
title: Deploy
sidebar_label: deploy
slug: /deploy
title: deploy
---

import carlin from '../.docusaurus/carlin/default/carlin.json';
Expand Down Expand Up @@ -49,14 +47,14 @@ export const DestroyAlgorithm = () => (
export const DeployApi = () => {
return (
<pre>
<code className="js">{carlin.api.deploy}</code>
<code className="bash">{carlin.api.deploy}</code>
</pre>
);
};

## Overview

```js
```bash
carlin deploy
```

Expand Down Expand Up @@ -102,7 +100,7 @@ When this option exists, the following algorithm is executed:
<DestroyAlgorithm />
:::

:::caution
:::danger
This operation is irreversible. You must pay attention because you may destroy resources that contains your App data, like DynamoDB, using this command.
To overcome this problem, destroy will only delete the resources if termination protetion isn't enabled and if `environment` isn't defined.
:::
Expand All @@ -111,19 +109,19 @@ To overcome this problem, destroy will only delete the resources if termination

- Change the CloudFormation template path:

```
```bash
carlin deploy -t src/cloudformation.template1.yml
```

- Set environment:

```
```bash
carlin deploy -e Production
```

- Lambda exists:

```
```bash
carlin deploy --lambda-input src/lambda/index.ts --lambda-externals momentjs
```

Expand Down
1 change: 0 additions & 1 deletion packages/website/docs/doc2.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
id: doc2
title: Document Number 2
slug: /
---

This is a link to [another document.](doc3.md) This is a link to an [external page.](http://www.example.com/)
Expand Down
11 changes: 11 additions & 0 deletions packages/website/docs/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Installation
---

You can install **carlin** with NPM or Yarn.

```bash
npm install -g carlin
# or
yarn global add carlin
```
8 changes: 8 additions & 0 deletions packages/website/docs/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Overview
slug: /
---

**carlin** has been built for the last years as helpers scripts that support deploying AWS cloud resources. The first scripts were used to deploy CloudFormation templates as we've started performing numerous deployments along with staging, production, development... environments.

As the scripts grew, it was very useful put them all in a CLI and create an [NPM package](https://www.npmjs.com/package/carlin), this way it can be used by all team in all projects.
2 changes: 1 addition & 1 deletion packages/website/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = {
},
items: [
{
to: 'docs/deploy',
to: 'docs/',
activeBasePath: 'docs',
label: 'Docs',
position: 'left',
Expand Down
1 change: 1 addition & 0 deletions packages/website/sidebars.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
someSidebar: {
'Getting Started': ['overview', 'installation', 'CLI'],
Commands: ['deploy'],
},
};

0 comments on commit f7e6f72

Please sign in to comment.