diff --git a/.gitignore b/.gitignore index b9651a9..5a0c5b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ coverage node_modules *.log +tmp diff --git a/README.md b/README.md index 796a15e..45ae730 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,23 @@ plugins: That's it! You can now type `serverless dotenv` in your terminal to generate the `.env` file based on your serverless configuration. Alternative you can just start `serverless offline` to generate it. +### Setting a custom path + +If you want to customize the output location of the `.env` file, you can set a custom `path` option. + +Via the CLI: +```sh +serverless dotenv --path /some/custom/path +``` + +Or via the `serverless.yaml` file: +```yaml +service: some-service +custom: + dotenv: + path: some/custom/path +``` + ## Contribution Feel free to contribute to this project! Our JavaScript is written based on [standardJS](https://standardjs.com). We recommend to use a `standardJS` [plugin](https://standardjs.com/index.html#are-there-text-editor-plugins) for your Editor, but you can also lint your code with `yarn run lint` - respectively `npm run lint`. Please don't forget to add unit and/or integration tests. Thanks <3 diff --git a/src/index.js b/src/index.js index 09f889a..2f15d9a 100644 --- a/src/index.js +++ b/src/index.js @@ -12,19 +12,31 @@ class ServerlessDotenvPlugin { constructor (serverless, options) { this.serverless = serverless this.options = options + this.custom = this.serverless.service.custom || {}; + this.custom.dotenv = this.custom.dotenv || {}; this.commands = { dotenv: { usage: 'Create .env file with serverless environment variables', lifecycleEvents: [ 'dotenvHandler' - ] + ], + options: { + path: { + usage: 'Specify an output path for the .env file. Defaults to .serverless/', + shortcut: 'p', + required: false + } + } } } this.hooks = { 'before:offline:start:init': this.initOfflineHook.bind(this), 'before:offline:start': this.initOfflineHook.bind(this), + 'before:invoke:local:invoke': this.dotenvHandler.bind(this), + 'before:package:function:package': this.dotenvHandler.bind(this), + 'before:package:createDeploymentArtifacts': this.dotenvHandler.bind(this), 'dotenv:dotenvHandler': this.dotenvHandler.bind(this) } @@ -55,8 +67,10 @@ class ServerlessDotenvPlugin { } // write .env file - const dotEnvPath = path.join(this.serverless.config.servicePath, '.serverless') - const dotEnvFile = path.join(this.serverless.config.servicePath, '.serverless/.env') + const dotEnvPath = this.options.path || this.custom.dotenv.path || + path.join(this.serverless.config.servicePath, '.serverless') + + const dotEnvFile = path.join(dotEnvPath, '.env') const dotEnvDocument = transformEnvVarsToString(this.environmentVariables) mkdirp.sync(dotEnvPath) diff --git a/test/index.spec.js b/test/index.spec.js index d8f4e95..440adbf 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -45,7 +45,7 @@ describe('serverless dotenv plugin', () => { expectedEnvVars += 'TEST1_ENV_VAR=value123\r\n' expectedEnvVars += 'TEST2_ENV_VAR=value123\r\n' - pluginInstance = new ServerlessDotenvPlugin(serverless) + pluginInstance = new ServerlessDotenvPlugin(serverless, {}) }) describe('starting plugin', () => { @@ -66,6 +66,26 @@ describe('serverless dotenv plugin', () => { expect(dotEnvDocument.toString('ascii')).toEqual(expectedEnvVars) }) + it('should write .env file to a custom location', () => { + pluginInstance.options.path = 'tmp/custom/path' + pluginInstance.dotenvHandler() + + const dotEnvFile = path.join('tmp/custom/path', '.env') + const dotEnvDocument = fs.readFileSync(dotEnvFile) + + expect(dotEnvDocument.toString('ascii')).toEqual(expectedEnvVars) + }) + + it('should write .env file to a custom location set in serverless.yaml custom config', () => { + serverless.service.custom = {dotenv: 'tmp/custom/path'} + pluginInstance.dotenvHandler() + + const dotEnvFile = path.join('tmp/custom/path', '.env') + const dotEnvDocument = fs.readFileSync(dotEnvFile) + + expect(dotEnvDocument.toString('ascii')).toEqual(expectedEnvVars) + }) + it('should append offline variables when hooked', () => { serverless.pluginManager = { run: () => pluginInstance.dotenvHandler()