Skip to content

Commit 72d9af0

Browse files
committedJun 4, 2024·
feat: initial commit
1 parent f098938 commit 72d9af0

13 files changed

+10902
-0
lines changed
 

‎.eslintignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
bin
2+
package.json
3+
./node_modules/
4+
.vscode
5+
.idea

‎.eslintrc.json

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"root": true,
3+
"parserOptions": {
4+
"ecmaVersion": "latest"
5+
},
6+
"env": {
7+
"es6": true
8+
},
9+
"plugins": ["simple-import-sort"],
10+
"overrides": [
11+
{
12+
"parserOptions": {
13+
"project": "./tsconfig.json"
14+
},
15+
"files": [
16+
"src/**/*.ts"
17+
],
18+
"extends": [
19+
"eslint:recommended",
20+
"plugin:@typescript-eslint/recommended",
21+
"plugin:prettier/recommended"
22+
],
23+
"rules": {
24+
"simple-import-sort/imports": "error",
25+
"simple-import-sort/exports": "error",
26+
"@typescript-eslint/ban-ts-comment": 0,
27+
"max-lines-per-function": [
28+
1,
29+
{
30+
"max": 40
31+
}
32+
],
33+
"max-lines": [
34+
1,
35+
{
36+
"max": 150
37+
}
38+
]
39+
}
40+
},
41+
{
42+
"parserOptions": {
43+
"project": "./tsconfig.json"
44+
},
45+
"files": [
46+
"src/**/*.ts"
47+
]
48+
}
49+
]
50+
}

‎.github/workflows/release.yml

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v2
15+
16+
- name: Set up Node.js
17+
uses: actions/setup-node@v2
18+
with:
19+
node-version: '20'
20+
21+
- name: Setup Corepack
22+
run: |
23+
corepack enable
24+
corepack prepare npm@10.8.1 --activate
25+
26+
- name: Install dependencies
27+
run: npm install
28+
29+
- name: Build project
30+
run: npm run build
31+
32+
- name: Run Semantic Release
33+
env:
34+
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
35+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36+
run: npm run release

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
bin

‎.npmignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.idea/
2+
.github
3+
.gitignore
4+
.prettierrc.json
5+
.DS_Store
6+
CONTRIBUTE.md
7+
8+
# configuration
9+
renovate.json
10+
tsconfig.json
11+
/.vscode
12+
.eslintrc.json
13+
.eslintignore

‎.prettierrc.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"singleQuote": true,
3+
"trailingComma": "all",
4+
"endOfLine": "auto",
5+
"printWidth": 100
6+
}

‎.releaserc.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @type {import('semantic-release').GlobalConfig}
3+
*/
4+
const releaseConfig = {
5+
branches: ["main"],
6+
"plugins": [
7+
"@semantic-release/commit-analyzer",
8+
"@semantic-release/release-notes-generator",
9+
"@semantic-release/changelog",
10+
"@semantic-release/npm",
11+
"@semantic-release/github",
12+
[
13+
"@semantic-release/git",
14+
{
15+
"assets": ["package.json", "CHANGELOG.md"],
16+
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
17+
}
18+
]
19+
]
20+
};
21+
22+
module.exports = releaseConfig;

‎README.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# @devmy/dotenv2shell - Load Environment Variables from .env File
2+
3+
This TypeScript CLI lets you easily load environment variables from a `.env` file into your current shell session with [@dotenv-run/core](https://www.npmjs.com/package/@dotenv-run/core). It provides flexibility through various options and supports both zsh and bash.
4+
5+
- ✅ Load environment variables from .env files
6+
- ✅ Load environment variables from .env.vault files
7+
- ✅ Expand environment variables API_URL=$API_BASE/users
8+
- ✅ Define environment variables for a specific environment (e.g. .env.production)
9+
- ✅ Load priorities of .env.* files (e.g. .env.production > .env)
10+
- ✅ Hierarchical cascading configuration in monorepo projects (Nx, Turbo, etc.) apps/next-app/.env > apps/.env > .env
11+
12+
## Usage
13+
14+
```bash
15+
npx @devmy/dotenv2shell [options]
16+
```
17+
18+
### Options
19+
20+
* `-o, --override`: Override existing environment variables on your machine with values from the `.env` file (default: false).
21+
* `-p, --prefix`: Prefix to filter environment variables to load (e.g., `MY_APP_`).
22+
* `-r, --root`: Root directory to search for the `.env` file (default: current working directory).
23+
* `-f, --files`: Comma-separated list of `.env` files to load (default: `.env`).
24+
* `-d, --dotenv_key`: Manually specify the `DOTENV_KEY` for decryption (if using `.env.vault`).
25+
26+
### Examples
27+
28+
* Load the default `.env` file from the current directory:
29+
30+
```bash
31+
eval $(npx @devmy/dotenv2shell)
32+
```
33+
34+
* Load a specific `.env` file with a prefix and override existing variable:
35+
36+
```zsh
37+
eval $(npx @devmy/dotenv2shell -f my-env.env -p MY_APP_ -o)
38+
```
39+
40+
## Handling Backslash Escapes
41+
42+
In some cases, environment variables loaded from the `.env` file may contain special characters that require backslash escapes to be interpreted correctly by the shell. This is particularly relevant when dealing with paths, file names, ssh-keys or other strings that might contain characters like spaces, commas, or backslashes themselves.
43+
44+
If you encounter issues with environment variables not behaving as expected, check for any special characters in their values and consider using backslash escapes to ensure they are treated as literal characters. For example:
45+
46+
```bash
47+
eval $(npx @devmy/dotenv2shell) &&
48+
echo -e "$DEPLOY_GITHUB_SSH_KEY" | ssh-add -
49+
```
50+
51+
52+
Remember that the -e option in echo is used to enable backslash escapes when printing strings, but it's not necessary when loading environment variables. The shell will automatically handle backslash escapes when interpreting environment variable values.

‎package-lock.json

+10,566
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"name": "@devmy/dotenv2shell",
3+
"version": "0.0.0",
4+
"description": "A CLI lets you easily load environment variables from a `.env` file into your current shell session. It provides flexibility through various options and supports both zsh and bash.",
5+
"main": "bin/index.mjs",
6+
"bin": "bin/index.mjs",
7+
"scripts": {
8+
"build": "tsup",
9+
"lint": "eslint 'src/**/*.ts'",
10+
"lint:fix": "eslint 'src/**/*.ts' --fix",
11+
"release": "semantic-release"
12+
},
13+
"keywords": [
14+
"dotenv",
15+
"environment",
16+
"config",
17+
"dotenv-run",
18+
".env.vault",
19+
"vault",
20+
"dotenv_key",
21+
"bash",
22+
"shell",
23+
"zsh"
24+
],
25+
"license": "MIT",
26+
"author": ".devmy",
27+
"publishConfig": {
28+
"access": "public"
29+
},
30+
"repository": {
31+
"type": "git",
32+
"url": "git+https://github.com/acadevmy/dotenv2shell.git"
33+
},
34+
"bugs": {
35+
"url": "https://github.com/acadevmy/dotenv2shell/issues"
36+
},
37+
"dependencies": {
38+
"@dotenv-run/core": "^1.3.5",
39+
"yargs": "^17.7.2"
40+
},
41+
"devDependencies": {
42+
"@semantic-release/changelog": "^6.0.3",
43+
"@semantic-release/commit-analyzer": "^13.0.0",
44+
"@semantic-release/git": "^10.0.1",
45+
"@semantic-release/github": "github:semantic-release/git",
46+
"@semantic-release/npm": "^12.0.1",
47+
"@semantic-release/release-notes-generator": "^14.0.0",
48+
"@types/node": "^20.14.0",
49+
"@types/yargs": "^17.0.32",
50+
"@typescript-eslint/eslint-plugin": "^7.11.0",
51+
"eslint": "8.57.0",
52+
"eslint-config-prettier": "^8.10.0",
53+
"eslint-plugin-prettier": "^5.1.3",
54+
"eslint-plugin-simple-import-sort": "^12.1.0",
55+
"prettier": "^3.2.5",
56+
"semantic-release": "^24.0.0",
57+
"tsup": "^8.1.0",
58+
"typescript": "^5.3.3"
59+
},
60+
"packageManager": "npm@10.8.1"
61+
}

‎src/index.ts

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { env } from '@dotenv-run/core';
2+
import yargs from 'yargs';
3+
import { hideBin } from 'yargs/helpers';
4+
5+
const argv = await yargs(hideBin(process.argv))
6+
.option('override', {
7+
alias: 'o',
8+
boolean: true,
9+
default: false,
10+
description:
11+
'Override any environment variables that have already been set on your machine with values from your .env file',
12+
})
13+
.option('prefix', {
14+
alias: 'p',
15+
string: true,
16+
description: 'Prefix to filter environment variables',
17+
})
18+
.option('root', {
19+
alias: 'r',
20+
string: true,
21+
description: 'Root directory to search for .env files',
22+
})
23+
.option('files', {
24+
alias: 'f',
25+
string: true,
26+
array: true,
27+
description: '.env files to load',
28+
})
29+
.option('dotenv_key', {
30+
alias: 'd',
31+
string: true,
32+
description: 'Specify manually the DOTENV_KEY to decrypt .env.vault',
33+
})
34+
.help().argv;
35+
36+
// Kill all dotenv logs 🏴‍☠️
37+
console.log = () => null;
38+
39+
const dotenvRun = env({
40+
prefix: argv.prefix,
41+
root: argv.root,
42+
files: argv.files,
43+
dotenv: {
44+
override: argv.override,
45+
DOTENV_KEY: argv.dotenv_key,
46+
},
47+
});
48+
49+
const exportStatements = Object.entries(dotenvRun.raw)
50+
.map(([key, value]) => {
51+
value = JSON.stringify(value).replaceAll(/\r\n|\r|\n/g, '\n');
52+
53+
return `export ${key}=${value}`;
54+
})
55+
.join('\n');
56+
57+
process.stdout.write(exportStatements);

‎tsconfig.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"compilerOptions": {
3+
"declaration": true,
4+
"module": "ES2022",
5+
"target": "ES2022",
6+
"moduleResolution": "node",
7+
"skipLibCheck": true,
8+
"sourceMap": true,
9+
"strict": true,
10+
"useUnknownInCatchVariables": false,
11+
"esModuleInterop": true,
12+
"outDir": "./dist"
13+
},
14+
"include": ["src"],
15+
"exclude": ["node_modules"]
16+
}

‎tsup.config.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { defineConfig } from "tsup";
2+
3+
export default defineConfig({
4+
entry: ["src/index.ts"],
5+
format: ["esm"],
6+
dts: true,
7+
splitting: true,
8+
treeshake: true,
9+
sourcemap: true,
10+
bundle: true,
11+
minify: true,
12+
clean: true,
13+
cjsInterop: true,
14+
outDir: 'bin',
15+
tsconfig: './tsconfig.json'
16+
});

0 commit comments

Comments
 (0)
Please sign in to comment.