aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rw-r--r--README.md67
-rw-r--r--deepenv.scm26
3 files changed, 100 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 53ae1ff..b627838 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,25 @@
+CSC ?= csc
+PREFIX ?= /usr/local
+
deepenv: deepenv.scm
- csc -o deepenv deepenv.scm
+ $(CSC) -o deepenv deepenv.scm
dispenv: dispenv.scm
- csc -o dispenv dispenv.scm
+ $(CSC) -o dispenv dispenv.scm
.PHONY: static
static: deepenv.scm
- csc -static -o deepenv.static deepenv.scm
+ $(CSC) -static -o deepenv.static deepenv.scm
.PHONY: clean
clean:
rm -f dispenv deepenv dispenv.link deepenv.link deepenv.static
+
+.PHONY: install
+install:
+ mkdir -p $(PREFIX)/bin
+ install deepenv $(PREFIX)/bin/deepenv
+
+.PHONY: uninstall
+uninstall:
+ rm $(PREFIX)/bin/deepenv
diff --git a/README.md b/README.md
index 0723c86..6d25661 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,69 @@
DEEPENV
=======
-Deepenv is a tool to run programs with their environment variables populated from all detected parent .env files merged together.
+Deepenv is a tool to run programs with their environment variables
+populated from all detected parent .env files merged together.
+
+## Installing
+
+Deepenv is written in Chicken scheme. In order to install it, you will
+need to first install Chicken, and compile deepenv.
+
+On Linux, use your package manager to install Chicken like so:
+
+```
+sudo apt install chicken-bin
+```
+
+On MacOS, install Chicken with Homebrew:
+
+```
+brew install chicken
+```
+
+Then compile and install Chicken like so:
+
+```
+make
+make install
+```
+
+### Overrides
+
+The following can be overriden by environment or make variables:
+
+- `CSC` the chicken compiler command. Usually `csc`, sometimes `chicken-csc`.
+- `PREFIX` file-system prefix where the executables will be installed. Defaults to `/usr/local`.
+
+## Usage
+
+To use deepenv, simply `cd` to the place where you want to run a
+program, and run with:
+
+```
+deepenv <program> [arguments]
+```
+
+If a `.env` file exists in this folder or any parent folder, they will
+be loaded as environment variables when `program` runs.
+
+## Environment merging strategy
+
+All `.env` files encountered from the current working directory, all
+the way to the filesystem root are loaded and merged together, with
+environment variables defined deeper in the tree shadowing their
+parent definitions. The very top level is the existing environment
+variables.
+
+For example, given the following file structure:
+
+```
+/
+/.env
++- /foo
+ +- .env
+```
+
+Assuming `/.env` defines `FOO=123` and `/foo/.env` defines `FOO=456`,
+running `deepenv <program>` in `/foo` will result in `FOO` being set
+to `456`.
diff --git a/deepenv.scm b/deepenv.scm
index 98c9400..87a5c12 100644
--- a/deepenv.scm
+++ b/deepenv.scm
@@ -22,6 +22,8 @@
(chicken string)
(chicken process)
(chicken process-context)
+ (chicken condition)
+ (chicken format)
srfi-1
srfi-13
srfi-14)
@@ -104,11 +106,21 @@
(car executables)
program)))
-(let* ((parents (path-parents (current-directory)))
- (environment (fold .env-union '() (cons (get-environment-variables) (reverse (map load-dir-.env parents)))))
- (program (resolve-program (car (command-line-arguments))))
- (arguments (cdr (command-line-arguments))))
- (if program
- (process-execute program arguments environment)
- (display "Program not found\n")))
+(define (run-with-.env directory command arguments)
+ (let* ((parents (path-parents directory))
+ (environment (fold .env-union '() (cons (get-environment-variables) (reverse (map load-dir-.env parents)))))
+ (program (resolve-program command)))
+ (condition-case
+ (process-execute program arguments environment)
+ ((exn) (printf "Program `~a' not found!~%" command)))))
+
+(let ((not-enough-args (< (length (command-line-arguments)) 1))
+ (user-asking-help (find (lambda (item) (string=? item "--help")) (command-line-arguments))))
+ (if (or not-enough-args user-asking-help)
+ (begin
+ (display "Deepenv sources .env files in the current and parent directories, then runs a program.\n")
+ (display "Usage: deepenv <program> <arguments>\n"))
+ (run-with-.env (current-directory)
+ (car (command-line-arguments))
+ (cdr (command-line-arguments)))))