mirror of
https://github.com/sbrow/envr.git
synced 2026-08-26 18:03:32 -04:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf62869f3b | |||
| 86a4da6cba | |||
| 222a0a3452 |
@@ -15,5 +15,6 @@ envr-prof
|
|||||||
findr/findr
|
findr/findr
|
||||||
findr/findr-prof
|
findr/findr-prof
|
||||||
findr/bench-*.md
|
findr/bench-*.md
|
||||||
|
gendocs
|
||||||
result
|
result
|
||||||
version.odin
|
version.odin
|
||||||
|
|||||||
@@ -1,5 +1,38 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [1.0.0](https://github.com/sbrow/envr/compare/v0.4.0...v1.0.0) (2026-07-27)
|
||||||
|
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* Renamed `nushell-completion` command to `completion nushell`.
|
||||||
|
* Databases with a JSON formatted remotes column will no longer parse correctly. If you have an old database, make sure you upgrade to envr 0.4.0 and run `envr list` before upgrading to this version.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Added `uninstall` command. ([222a0a3](https://github.com/sbrow/envr/commit/222a0a3452b978d9bd14d6d2b91e40cd8f4959e3))
|
||||||
|
* Added bash completion support. ([e0a339e](https://github.com/sbrow/envr/commit/e0a339e8ec996c0e91e27357854abd9a78bd695a))
|
||||||
|
* Brought back the docs generator. ([86a4da6](https://github.com/sbrow/envr/commit/86a4da6cbaae698379c73b8345e6d238b2a11a46))
|
||||||
|
* Improved nushell wrapper output. ([209ec89](https://github.com/sbrow/envr/commit/209ec89addbed4718c5aed845ab20b386d1e425d))
|
||||||
|
* Scan results can now be filtered during selection. ([ae42d53](https://github.com/sbrow/envr/commit/ae42d53f029dd185143a645fb3f3a787051c1bb4))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Removed irrelevent flags from `nushell-completion` command help text. ([af1860c](https://github.com/sbrow/envr/commit/af1860c970604470992182bbfe9ecb15609a0acf))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* Added `#no_bounds_check` to ssh parsers. ([f5624e9](https://github.com/sbrow/envr/commit/f5624e91f1236eecb263f28600ce7f4b2fda149f))
|
||||||
|
* Added a pre-alloc opportunity. ([997f11b](https://github.com/sbrow/envr/commit/997f11b257f1c981f73c6ae97d6e821147b5e2fc))
|
||||||
|
* Removed support for JSON formatted remotes. ([5282a44](https://github.com/sbrow/envr/commit/5282a4414b9a0211604553f2cb9434025aa5296b))
|
||||||
|
|
||||||
|
|
||||||
|
### Code Refactoring
|
||||||
|
|
||||||
|
* Renamed `nushell-completion` command to `completion nushell`. ([b0635e0](https://github.com/sbrow/envr/commit/b0635e035c44fb20f9b02265cff1ed8db30aa9d0))
|
||||||
|
|
||||||
## [0.4.0](https://github.com/sbrow/envr/compare/v0.3.0...v0.4.0) (2026-06-29)
|
## [0.4.0](https://github.com/sbrow/envr/compare/v0.3.0...v0.4.0) (2026-06-29)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,9 @@
|
|||||||
|
|
||||||
4. Test all command branches.
|
4. Test all command branches.
|
||||||
|
|
||||||
5. Generate md and man pages again.
|
|
||||||
|
|
||||||
6. Add tests for untested commands.
|
6. Add tests for untested commands.
|
||||||
|
|
||||||
7. Add uninstall command.
|
7. Add purge command?
|
||||||
|
|
||||||
8. Add purge command?
|
|
||||||
|
|
||||||
|
|
||||||
## Double-check AI output
|
## Double-check AI output
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ Positional_Arg :: struct {
|
|||||||
ntype: string, // nushell type: "path", "string". "" defaults to "path"
|
ntype: string, // nushell type: "path", "string". "" defaults to "path"
|
||||||
completion: string,
|
completion: string,
|
||||||
optional: bool,
|
optional: bool,
|
||||||
|
desc: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandInfo :: struct {
|
CommandInfo :: struct {
|
||||||
@@ -96,14 +97,14 @@ key somewhere, otherwise your data could be lost forever.`,
|
|||||||
short = "Import a .env file into envr",
|
short = "Import a .env file into envr",
|
||||||
aliases = {"add"},
|
aliases = {"add"},
|
||||||
flags = GLOBAL_FLAGS,
|
flags = GLOBAL_FLAGS,
|
||||||
args = {{name = "path", completion = "untracked-paths"}},
|
args = {{name = "path", completion = "untracked-paths", desc = "Path to .env file to backup"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "restore",
|
name = "restore",
|
||||||
usage = "envr restore <path>",
|
usage = "envr restore <path>",
|
||||||
short = "Restore a .env file from the database",
|
short = "Restore a .env file from the database",
|
||||||
flags = GLOBAL_FLAGS,
|
flags = GLOBAL_FLAGS,
|
||||||
args = {{name = "path", completion = "tracked-paths"}},
|
args = {{name = "path", completion = "tracked-paths", desc = "Path to .env file to restore"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "list",
|
name = "list",
|
||||||
@@ -116,14 +117,14 @@ key somewhere, otherwise your data could be lost forever.`,
|
|||||||
usage = "envr remove <path>",
|
usage = "envr remove <path>",
|
||||||
short = "Remove a .env file from your database",
|
short = "Remove a .env file from your database",
|
||||||
flags = GLOBAL_FLAGS,
|
flags = GLOBAL_FLAGS,
|
||||||
args = {{name = "path", completion = "tracked-paths"}},
|
args = {{name = "path", completion = "tracked-paths", desc = "Path to .env file to remove"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "check",
|
name = "check",
|
||||||
usage = "envr check [path]",
|
usage = "envr check [path]",
|
||||||
short = "Check if files are backed up",
|
short = "Check if files are backed up",
|
||||||
flags = GLOBAL_FLAGS,
|
flags = GLOBAL_FLAGS,
|
||||||
args = {{name = "path", optional = true}},
|
args = {{name = "path", optional = true, desc = "Path to check (defaults to current directory)"}},
|
||||||
},
|
},
|
||||||
{name = "version", usage = "envr version", short = "Show envr's version", flags = {.Help}},
|
{name = "version", usage = "envr version", short = "Show envr's version", flags = {.Help}},
|
||||||
{
|
{
|
||||||
@@ -141,7 +142,14 @@ key somewhere, otherwise your data could be lost forever.`,
|
|||||||
nushell
|
nushell
|
||||||
bash`,
|
bash`,
|
||||||
flags = {.Help},
|
flags = {.Help},
|
||||||
args = {{name = "shell", ntype = "string", completion = "shells"}},
|
args = {{name = "shell", ntype = "string", completion = "shells", desc = "Shell to generate completions for"}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "uninstall",
|
||||||
|
usage = "envr uninstall",
|
||||||
|
short = "Remove envr configuration and database",
|
||||||
|
long = "This will remove all files generated by envr from your system.",
|
||||||
|
flags = GLOBAL_FLAGS + {.Force},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,11 +388,7 @@ find_command :: proc(name: string) -> (CommandInfo, bool) {
|
|||||||
return CommandInfo{}, false
|
return CommandInfo{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: command args should be shown in usage.
|
ENVR_DESCRIPTION :: `envr keeps your .env synced to a local, encrypted database.
|
||||||
write_usage :: proc(w: io.Writer) {
|
|
||||||
fmt.wprintf(
|
|
||||||
w,
|
|
||||||
`envr keeps your .env synced to a local, encrypted database.
|
|
||||||
Is a safe and easy way to gather all your .env files in one place where they can
|
Is a safe and easy way to gather all your .env files in one place where they can
|
||||||
easily be backed by another tool such as restic or git.
|
easily be backed by another tool such as restic or git.
|
||||||
|
|
||||||
@@ -413,13 +417,14 @@ Select the files you want to back up from the interactive list.
|
|||||||
5. If you lose a repository, after re-cloning the repo into the same path it was
|
5. If you lose a repository, after re-cloning the repo into the same path it was
|
||||||
at before, restore your backup with:
|
at before, restore your backup with:
|
||||||
|
|
||||||
> envr restore ~/<path to repository>/.env
|
> envr restore ~/<path to repository>/.env`
|
||||||
|
|
||||||
%s
|
// TODO: command args should be shown in usage.
|
||||||
|
write_usage :: proc(w: io.Writer) {
|
||||||
%s [command]
|
fmt.wprintf(
|
||||||
|
w,
|
||||||
`,
|
"%s\n\n%s\n\n %s [command]\n\n",
|
||||||
|
ENVR_DESCRIPTION,
|
||||||
colorize(.Heading, "Usage:"),
|
colorize(.Heading, "Usage:"),
|
||||||
colorize(.Flag, "envr"),
|
colorize(.Flag, "envr"),
|
||||||
flush = false,
|
flush = false,
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "core:bufio"
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:os"
|
||||||
|
import "core:path/filepath"
|
||||||
|
import "core:strings"
|
||||||
|
import "core:terminal"
|
||||||
|
|
||||||
|
cmd_uninstall :: proc(cmd: ^Command) {
|
||||||
|
envr_d := envr_dir(cmd.flags.config_file)
|
||||||
|
|
||||||
|
if !os.exists(envr_d) {
|
||||||
|
fmt.wprintln(cmd.out, "Nothing to remove.", flush = false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
entries, err := os.read_all_directory_by_path(envr_d, context.temp_allocator)
|
||||||
|
if err != nil {
|
||||||
|
fmt.wprintf(cmd.err, "Error reading %s: %v\n", envr_d, err, flush = false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
paths := make([]string, len(entries), context.temp_allocator)
|
||||||
|
for entry, i in entries {
|
||||||
|
paths[i], _ = filepath.join([]string{envr_d, entry.name}, context.temp_allocator)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.wprintln(cmd.out, "This will remove:", flush = false)
|
||||||
|
for path in paths {
|
||||||
|
fmt.wprintf(cmd.out, " %s\n", path, flush = false)
|
||||||
|
}
|
||||||
|
fmt.wprintf(cmd.out, " %s\n", envr_d, flush = false)
|
||||||
|
|
||||||
|
if !cmd.flags.force {
|
||||||
|
if !terminal.is_terminal(os.stdin) {
|
||||||
|
fmt.wprintln(cmd.err, "Run with --force to skip confirmation.", flush = false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.wprintf(cmd.out, "\nAre you sure? [y/N] ", flush = false)
|
||||||
|
bufio.writer_flush(cmd.out_buf)
|
||||||
|
|
||||||
|
buf: [128]u8
|
||||||
|
n, _ := os.read(os.stdin, buf[:])
|
||||||
|
response := strings.trim_space(string(buf[:n]))
|
||||||
|
|
||||||
|
if response != "y" && response != "Y" {
|
||||||
|
fmt.wprintln(cmd.out, "Aborted.", flush = false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_err := os.remove_all(envr_d)
|
||||||
|
if remove_err != nil {
|
||||||
|
fmt.wprintf(cmd.err, "Error removing %s: %v\n", envr_d, remove_err, flush = false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for path in paths {
|
||||||
|
fmt.wprintf(cmd.out, "Removed %s\n", path, flush = false)
|
||||||
|
}
|
||||||
|
fmt.wprintf(cmd.out, "Removed %s\n", envr_d, flush = false)
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
#+test
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "core:bufio"
|
||||||
|
import "core:os"
|
||||||
|
import "core:path/filepath"
|
||||||
|
import "core:strings"
|
||||||
|
import "core:testing"
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_cmd_uninstall_force :: proc(t: ^testing.T) {
|
||||||
|
base := test_temp_dir(t, "envr-test-uninstall-*")
|
||||||
|
|
||||||
|
cfg_path, _ := filepath.join([]string{base, ".envr", "config.json"}, context.temp_allocator)
|
||||||
|
cfg := new_config([]string{"fixtures/keys/insecure-test-key"}, cfg_path)
|
||||||
|
testing.expect(t, save_config(cfg, force = true), "save should succeed")
|
||||||
|
delete_config(&cfg)
|
||||||
|
|
||||||
|
db, db_ok := db_open(cfg_path)
|
||||||
|
testing.expect(t, db_ok, "db should open")
|
||||||
|
if !db_ok do return
|
||||||
|
f := make_test_env_file("/project/.env", "abc123", "SECRET=value")
|
||||||
|
defer delete(f.remotes)
|
||||||
|
db_insert(&db, f)
|
||||||
|
db_close(&db)
|
||||||
|
|
||||||
|
envr_d := filepath.dir(cfg_path)
|
||||||
|
testing.expect(t, os.exists(envr_d), ".envr directory should exist before uninstall")
|
||||||
|
|
||||||
|
out_b: strings.Builder
|
||||||
|
strings.builder_init(&out_b)
|
||||||
|
defer strings.builder_destroy(&out_b)
|
||||||
|
err_b: strings.Builder
|
||||||
|
strings.builder_init(&err_b)
|
||||||
|
defer strings.builder_destroy(&err_b)
|
||||||
|
|
||||||
|
cmd, ok := parse_args(
|
||||||
|
[]string{"envr", "uninstall", "--force", "--config-file", cfg_path},
|
||||||
|
strings.to_stream(&out_b),
|
||||||
|
strings.to_stream(&err_b),
|
||||||
|
)
|
||||||
|
testing.expect(t, ok, "parse_args should succeed")
|
||||||
|
if !ok do return
|
||||||
|
defer delete_command(&cmd)
|
||||||
|
|
||||||
|
cmd_uninstall(&cmd)
|
||||||
|
bufio.writer_flush(cmd.out_buf)
|
||||||
|
|
||||||
|
testing.expect(t, !os.exists(envr_d), ".envr directory should be removed")
|
||||||
|
|
||||||
|
output := strings.to_string(out_b)
|
||||||
|
testing.expect(t, strings.contains(output, "Removed"), "output should list removed files")
|
||||||
|
testing.expect(
|
||||||
|
t,
|
||||||
|
strings.contains(output, "config.json"),
|
||||||
|
"output should mention config.json",
|
||||||
|
)
|
||||||
|
testing.expect(
|
||||||
|
t,
|
||||||
|
strings.contains(output, "data.envr"),
|
||||||
|
"output should mention data.envr",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_cmd_uninstall_nothing_to_remove :: proc(t: ^testing.T) {
|
||||||
|
base := test_temp_dir(t, "envr-test-uninstall-empty-*")
|
||||||
|
defer os.remove_all(base)
|
||||||
|
|
||||||
|
cfg_path, _ := filepath.join([]string{base, ".envr", "config.json"}, context.temp_allocator)
|
||||||
|
|
||||||
|
out_b: strings.Builder
|
||||||
|
strings.builder_init(&out_b)
|
||||||
|
defer strings.builder_destroy(&out_b)
|
||||||
|
err_b: strings.Builder
|
||||||
|
strings.builder_init(&err_b)
|
||||||
|
defer strings.builder_destroy(&err_b)
|
||||||
|
|
||||||
|
cmd, ok := parse_args(
|
||||||
|
[]string{"envr", "uninstall", "--force", "--config-file", cfg_path},
|
||||||
|
strings.to_stream(&out_b),
|
||||||
|
strings.to_stream(&err_b),
|
||||||
|
)
|
||||||
|
testing.expect(t, ok, "parse_args should succeed")
|
||||||
|
if !ok do return
|
||||||
|
defer delete_command(&cmd)
|
||||||
|
|
||||||
|
cmd_uninstall(&cmd)
|
||||||
|
bufio.writer_flush(cmd.out_buf)
|
||||||
|
|
||||||
|
output := strings.to_string(out_b)
|
||||||
|
testing.expect(
|
||||||
|
t,
|
||||||
|
strings.contains(output, "Nothing to remove"),
|
||||||
|
"output should say nothing to remove",
|
||||||
|
)
|
||||||
|
}
|
||||||
+11
-10
@@ -5,7 +5,7 @@ Manage your .env files.
|
|||||||
### Synopsis
|
### Synopsis
|
||||||
|
|
||||||
envr keeps your .env synced to a local, encrypted database.
|
envr keeps your .env synced to a local, encrypted database.
|
||||||
Is a safe and eay way to gather all your .env files in one place where they can
|
Is a safe and easy way to gather all your .env files in one place where they can
|
||||||
easily be backed by another tool such as restic or git.
|
easily be backed by another tool such as restic or git.
|
||||||
|
|
||||||
All your data is stored in ~/.envr/data.envr
|
All your data is stored in ~/.envr/data.envr
|
||||||
@@ -33,25 +33,26 @@ Select the files you want to back up from the interactive list.
|
|||||||
5. If you lose a repository, after re-cloning the repo into the same path it was
|
5. If you lose a repository, after re-cloning the repo into the same path it was
|
||||||
at before, restore your backup with:
|
at before, restore your backup with:
|
||||||
|
|
||||||
> envr restore ~/<path to repository>/.env
|
> envr restore ~/<path to repository>/.env
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for envr
|
-h, --help show this documentation
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr backup](envr_backup.md) - Import a .env file into envr
|
|
||||||
* [envr check](envr_check.md) - check if files in the current directory are backed up
|
|
||||||
* [envr edit-config](envr_edit-config.md) - Edit your config with your default editor
|
|
||||||
* [envr init](envr_init.md) - Set up envr
|
* [envr init](envr_init.md) - Set up envr
|
||||||
* [envr list](envr_list.md) - View your tracked files
|
|
||||||
* [envr nushell-completion](envr_nushell-completion.md) - Generate custom completions for nushell
|
|
||||||
* [envr remove](envr_remove.md) - Remove a .env file from your database
|
|
||||||
* [envr restore](envr_restore.md) - Install a .env file from the database into your file system
|
|
||||||
* [envr scan](envr_scan.md) - Find and select .env files for backup
|
* [envr scan](envr_scan.md) - Find and select .env files for backup
|
||||||
* [envr sync](envr_sync.md) - Update or restore your env backups
|
* [envr sync](envr_sync.md) - Update or restore your env backups
|
||||||
|
* [envr backup](envr_backup.md) - Import a .env file into envr
|
||||||
|
* [envr restore](envr_restore.md) - Restore a .env file from the database
|
||||||
|
* [envr list](envr_list.md) - View your tracked files
|
||||||
|
* [envr remove](envr_remove.md) - Remove a .env file from your database
|
||||||
|
* [envr check](envr_check.md) - Check if files are backed up
|
||||||
* [envr version](envr_version.md) - Show envr's version
|
* [envr version](envr_version.md) - Show envr's version
|
||||||
|
* [envr edit-config](envr_edit-config.md) - Edit your config with your default editor
|
||||||
|
* [envr completion](envr_completion.md) - Generate shell completion scripts
|
||||||
|
* [envr uninstall](envr_uninstall.md) - Remove envr configuration and database
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,20 @@ Import a .env file into envr
|
|||||||
envr backup <path> [flags]
|
envr backup <path> [flags]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
|
||||||
|
* `path` — Path to .env file to backup
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for backup
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
*Alias: `add`*
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
## envr check
|
## envr check
|
||||||
|
|
||||||
check if files in the current directory are backed up
|
Check if files are backed up
|
||||||
|
|
||||||
```
|
```
|
||||||
envr check [path] [flags]
|
envr check [path] [flags]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
|
||||||
|
* `path` — Path to check (defaults to current directory) (optional)
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for check
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
## envr completion
|
||||||
|
|
||||||
|
Generate shell completion scripts
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Supported shells:
|
||||||
|
|
||||||
|
nushell
|
||||||
|
bash
|
||||||
|
|
||||||
|
```
|
||||||
|
envr completion <shell> [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
|
||||||
|
* `shell` — Shell to generate completions for
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help show this documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [envr](envr.md) - Manage your .env files.
|
||||||
@@ -9,10 +9,11 @@ envr edit-config [flags]
|
|||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for edit-config
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ Set up envr
|
|||||||
### Synopsis
|
### Synopsis
|
||||||
|
|
||||||
The init command generates your initial config and saves it to
|
The init command generates your initial config and saves it to
|
||||||
~/.envr/config in JSON format.
|
~/.envr/config in JSON format.\n\nDuring setup, you will be prompted to select one or more ssh keys with which to
|
||||||
|
|
||||||
During setup, you will be prompted to select one or more ssh keys with which to
|
|
||||||
encrypt your databse. **Make 100% sure** that you have **a remote copy** of this
|
encrypt your databse. **Make 100% sure** that you have **a remote copy** of this
|
||||||
key somewhere, otherwise your data could be lost forever.
|
key somewhere, otherwise your data could be lost forever.
|
||||||
|
|
||||||
@@ -18,11 +16,12 @@ envr init [flags]
|
|||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-f, --force Overwrite an existing config
|
-h, --help show this documentation
|
||||||
-h, --help help for init
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
|
-f, --force Overwrite existing config
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ envr list [flags]
|
|||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for list
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
-o, --output the format of output data (default 'table')
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
## envr nushell-completion
|
|
||||||
|
|
||||||
Generate custom completions for nushell
|
|
||||||
|
|
||||||
### Synopsis
|
|
||||||
|
|
||||||
At time of writing, cobra does not natively support nushell,
|
|
||||||
so a custom command had to be written
|
|
||||||
|
|
||||||
```
|
|
||||||
envr nushell-completion [flags]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Options
|
|
||||||
|
|
||||||
```
|
|
||||||
-h, --help help for nushell-completion
|
|
||||||
```
|
|
||||||
|
|
||||||
### SEE ALSO
|
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
|
||||||
|
|
||||||
@@ -3,16 +3,21 @@
|
|||||||
Remove a .env file from your database
|
Remove a .env file from your database
|
||||||
|
|
||||||
```
|
```
|
||||||
envr remove [flags]
|
envr remove <path> [flags]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
|
||||||
|
* `path` — Path to .env file to remove
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for remove
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
## envr restore
|
## envr restore
|
||||||
|
|
||||||
Install a .env file from the database into your file system
|
Restore a .env file from the database
|
||||||
|
|
||||||
```
|
```
|
||||||
envr restore [flags]
|
envr restore <path> [flags]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
|
||||||
|
* `path` — Path to .env file to restore
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for restore
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,11 @@ envr scan [flags]
|
|||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for scan
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ envr sync [flags]
|
|||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for sync
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
-o, --output the format of output data (default 'table')
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
## envr uninstall
|
||||||
|
|
||||||
|
Remove envr configuration and database
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
This will remove all files generated by envr from your system.
|
||||||
|
|
||||||
|
```
|
||||||
|
envr uninstall [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help show this documentation
|
||||||
|
-c, --config-file config file (default "~/.envr/config.json")
|
||||||
|
--color Whether or not to colorize output (default 'auto')
|
||||||
|
-f, --force Overwrite existing config
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [envr](envr.md) - Manage your .env files.
|
||||||
@@ -9,11 +9,9 @@ envr version [flags]
|
|||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for version
|
-h, --help show this documentation
|
||||||
-l, --long Show all version information
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [envr](envr.md) - Manage your .env files.
|
* [envr](envr.md) - Manage your .env files.
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,11 @@
|
|||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
runHook preBuild
|
runHook preBuild
|
||||||
echo '${version}' > version.txt
|
echo '${version}' > version.txt
|
||||||
|
|
||||||
|
# Generate man pages before main build (binary gets clobbered)
|
||||||
|
odin build . -define:GENDOCS=true -out:gendocs
|
||||||
|
./gendocs --man
|
||||||
|
|
||||||
odin build . -o:speed -out:${pname}
|
odin build . -o:speed -out:${pname}
|
||||||
runHook postBuild
|
runHook postBuild
|
||||||
'';
|
'';
|
||||||
@@ -98,6 +103,9 @@
|
|||||||
installPhase = ''
|
installPhase = ''
|
||||||
runHook preInstall
|
runHook preInstall
|
||||||
install -Dm755 ${pname} $out/bin/${pname}
|
install -Dm755 ${pname} $out/bin/${pname}
|
||||||
|
|
||||||
|
mkdir -p $out/share/man/man1
|
||||||
|
cp docs/man/*.1 $out/share/man/man1/
|
||||||
runHook postInstall
|
runHook postInstall
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|||||||
+289
@@ -0,0 +1,289 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:os"
|
||||||
|
import "core:strings"
|
||||||
|
import "core:time"
|
||||||
|
|
||||||
|
when #config(GENDOCS, false) {
|
||||||
|
main :: proc() {
|
||||||
|
args := os.args
|
||||||
|
if len(args) < 2 {
|
||||||
|
fmt.eprintln("Usage: gendocs --man | --md")
|
||||||
|
os.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch args[1] {
|
||||||
|
case "--man":
|
||||||
|
generate_man_pages()
|
||||||
|
case "--md":
|
||||||
|
generate_markdown()
|
||||||
|
case:
|
||||||
|
fmt.eprintf("Unknown format: %s\n", args[1])
|
||||||
|
os.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_man_pages :: proc() {
|
||||||
|
os.mkdir_all("docs/man")
|
||||||
|
|
||||||
|
now := time.now()
|
||||||
|
month_year := fmt.tprintf("%s %d", time.month(now), time.year(now))
|
||||||
|
|
||||||
|
generate_man_main(month_year)
|
||||||
|
|
||||||
|
for &c in COMMANDS {
|
||||||
|
generate_man_command(&c, month_year)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.println("Generated man pages in docs/man/")
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_man_main :: proc(month_year: string) {
|
||||||
|
sb: strings.Builder
|
||||||
|
strings.builder_init(&sb, context.temp_allocator)
|
||||||
|
defer strings.builder_destroy(&sb)
|
||||||
|
|
||||||
|
fmt.sbprintf(&sb, ".TH ENVR 1 \"%s\" \"envr\" \"envr Manual\"\n", month_year)
|
||||||
|
fmt.sbprintf(&sb, ".SH NAME\nenvr \\- keep your .env files synced to an encrypted database\n")
|
||||||
|
fmt.sbprintf(&sb, ".SH SYNOPSIS\n\\fBenvr\\fR [\\fIcommand\\fR] [\\fIflags\\fR]\n")
|
||||||
|
fmt.sbprintf(
|
||||||
|
&sb,
|
||||||
|
".SH DESCRIPTION\nenvr keeps your .env synced to a local, encrypted database.\n",
|
||||||
|
)
|
||||||
|
fmt.sbprintf(
|
||||||
|
&sb,
|
||||||
|
"Is a safe and easy way to gather all your .env files in one place where they can\n",
|
||||||
|
)
|
||||||
|
fmt.sbprintf(&sb, "easily be backed by another tool such as restic or git.\n")
|
||||||
|
fmt.sbprintf(&sb, ".PP\nAll your data is stored in ~/.envr/data.envr\n")
|
||||||
|
fmt.sbprintf(&sb, ".SH COMMANDS\n")
|
||||||
|
for c in COMMANDS {
|
||||||
|
fmt.sbprintf(&sb, ".TP\n\\fB%s\\fR\n%s\n", c.name, c.short)
|
||||||
|
for a in c.aliases {
|
||||||
|
fmt.sbprintf(&sb, ".TP\n\\fB%s\\fR (alias for %s)\n%s\n", a, c.name, c.short)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.sbprintf(&sb, ".SH GLOBAL OPTIONS\n")
|
||||||
|
for ft in Flag_Type {
|
||||||
|
if ft not_in GLOBAL_FLAGS do continue
|
||||||
|
write_man_flag(&sb, ft)
|
||||||
|
}
|
||||||
|
fmt.sbprintf(&sb, ".SH SEE ALSO\n")
|
||||||
|
for c, i in COMMANDS {
|
||||||
|
if i > 0 do fmt.sbprintf(&sb, ",\n")
|
||||||
|
fmt.sbprintf(&sb, ".BR envr-%s (1)", c.name)
|
||||||
|
}
|
||||||
|
fmt.sbprintf(&sb, "\n")
|
||||||
|
|
||||||
|
path := "docs/man/envr.1"
|
||||||
|
err := os.write_entire_file(path, transmute([]u8)strings.to_string(sb))
|
||||||
|
if err != nil {
|
||||||
|
fmt.eprintf("Error writing %s: %v\n", path, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_man_command :: proc(c: ^CommandInfo, month_year: string) {
|
||||||
|
sb: strings.Builder
|
||||||
|
strings.builder_init(&sb, context.temp_allocator)
|
||||||
|
defer strings.builder_destroy(&sb)
|
||||||
|
|
||||||
|
upper_name := strings.to_upper(fmt.tprintf("envr-%s", c.name))
|
||||||
|
|
||||||
|
fmt.sbprintf(&sb, ".TH %s 1 \"%s\" \"envr\" \"envr Manual\"\n", upper_name, month_year)
|
||||||
|
fmt.sbprintf(&sb, ".SH NAME\nenvr-%s \\- %s\n", c.name, c.short)
|
||||||
|
fmt.sbprintf(&sb, ".SH SYNOPSIS\n\\fB%s\\fR", c.usage)
|
||||||
|
|
||||||
|
has_positionals := false
|
||||||
|
for arg in c.args {
|
||||||
|
has_positionals = true
|
||||||
|
if arg.optional {
|
||||||
|
fmt.sbprintf(&sb, " [\\fI%s\\fR]", arg.name)
|
||||||
|
} else {
|
||||||
|
fmt.sbprintf(&sb, " \\fI%s\\fR", arg.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.sbprintf(&sb, "\n")
|
||||||
|
|
||||||
|
if len(c.long) > 0 {
|
||||||
|
fmt.sbprintf(&sb, ".SH DESCRIPTION\n%s\n", c.long)
|
||||||
|
}
|
||||||
|
|
||||||
|
if has_positionals {
|
||||||
|
fmt.sbprintf(&sb, ".SH ARGUMENTS\n")
|
||||||
|
for arg in c.args {
|
||||||
|
fmt.sbprintf(&sb, ".TP\n\\fB%s\\fR\n%s\n", arg.name, arg.desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.sbprintf(&sb, ".SH OPTIONS\n")
|
||||||
|
for ft in Flag_Type {
|
||||||
|
if ft not_in c.flags do continue
|
||||||
|
write_man_flag(&sb, ft)
|
||||||
|
}
|
||||||
|
|
||||||
|
path := fmt.tprintf("docs/man/envr-%s.1", c.name)
|
||||||
|
err := os.write_entire_file(path, transmute([]u8)strings.to_string(sb))
|
||||||
|
if err != nil {
|
||||||
|
fmt.eprintf("Error writing %s: %v\n", path, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write_man_flag :: proc(sb: ^strings.Builder, ft: Flag_Type) {
|
||||||
|
f := flag_field(ft)
|
||||||
|
|
||||||
|
fmt.sbprintf(sb, ".TP\n")
|
||||||
|
if len(f.short_name) > 0 {
|
||||||
|
fmt.sbprintf(sb, "\\fB-%s\\fR, \\fB--%s\\fR", f.short_name, f.long_name)
|
||||||
|
} else {
|
||||||
|
fmt.sbprintf(sb, "\\fB--%s\\fR", f.long_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
#partial switch f.kind {
|
||||||
|
case .String:
|
||||||
|
fmt.sbprintf(sb, " \\fIvalue\\fR")
|
||||||
|
case .Enum:
|
||||||
|
values, _ := strings.replace(f.enum_values, "'", "", -1)
|
||||||
|
fmt.sbprintf(sb, " \\fI%s\\fR", values)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.sbprintf(sb, "\n%s\n", f.usage)
|
||||||
|
|
||||||
|
if len(f.default_val) > 0 {
|
||||||
|
#partial switch f.kind {
|
||||||
|
case .String:
|
||||||
|
fmt.sbprintf(sb, "(default \"%s\")\n", f.default_val)
|
||||||
|
case .Enum:
|
||||||
|
fmt.sbprintf(sb, "(default '%s')\n", f.default_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_markdown :: proc() {
|
||||||
|
os.mkdir_all("docs/cli")
|
||||||
|
|
||||||
|
generate_md_main()
|
||||||
|
|
||||||
|
for &c in COMMANDS {
|
||||||
|
generate_md_command(&c)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.println("Generated markdown in docs/cli/")
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_md_main :: proc() {
|
||||||
|
sb: strings.Builder
|
||||||
|
strings.builder_init(&sb, context.temp_allocator)
|
||||||
|
defer strings.builder_destroy(&sb)
|
||||||
|
|
||||||
|
fmt.sbprintf(&sb, "## envr\n\n")
|
||||||
|
fmt.sbprintf(&sb, "Manage your .env files.\n\n")
|
||||||
|
fmt.sbprintf(&sb, "### Synopsis\n\n")
|
||||||
|
fmt.sbprint(&sb, ENVR_DESCRIPTION)
|
||||||
|
fmt.sbprintf(&sb, "\n\n### Options\n\n")
|
||||||
|
write_md_options(&sb, {.Help})
|
||||||
|
fmt.sbprintf(&sb, "\n### SEE ALSO\n\n")
|
||||||
|
for c in COMMANDS {
|
||||||
|
fmt.sbprintf(&sb, "* [envr %s](envr_%s.md)\t - %s\n", c.name, c.name, c.short)
|
||||||
|
}
|
||||||
|
fmt.sbprintf(&sb, "\n")
|
||||||
|
|
||||||
|
write_file("docs/cli/envr.md", strings.to_string(sb))
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_md_command :: proc(c: ^CommandInfo) {
|
||||||
|
sb: strings.Builder
|
||||||
|
strings.builder_init(&sb, context.temp_allocator)
|
||||||
|
defer strings.builder_destroy(&sb)
|
||||||
|
|
||||||
|
fmt.sbprintf(&sb, "## envr %s\n\n", c.name)
|
||||||
|
fmt.sbprintf(&sb, "%s\n\n", c.short)
|
||||||
|
|
||||||
|
if len(c.long) > 0 {
|
||||||
|
fmt.sbprintf(&sb, "### Synopsis\n\n")
|
||||||
|
fmt.sbprint(&sb, c.long)
|
||||||
|
fmt.sbprintf(&sb, "\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.sbprintf(&sb, "```\n%s [flags]\n```\n\n", c.usage)
|
||||||
|
|
||||||
|
if len(c.args) > 0 {
|
||||||
|
fmt.sbprintf(&sb, "**Arguments:**\n\n")
|
||||||
|
for arg in c.args {
|
||||||
|
optional := arg.optional ? " (optional)" : ""
|
||||||
|
fmt.sbprintf(&sb, "* `%s` — %s%s\n", arg.name, arg.desc, optional)
|
||||||
|
}
|
||||||
|
fmt.sbprintf(&sb, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.sbprintf(&sb, "### Options\n\n")
|
||||||
|
write_md_options(&sb, c.flags)
|
||||||
|
|
||||||
|
for a in c.aliases {
|
||||||
|
fmt.sbprintf(&sb, "\n*Alias: `%s`*\n", a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.sbprintf(&sb, "\n### SEE ALSO\n\n")
|
||||||
|
fmt.sbprintf(&sb, "* [envr](envr.md)\t - Manage your .env files.\n")
|
||||||
|
|
||||||
|
path := fmt.tprintf("docs/cli/envr_%s.md", c.name)
|
||||||
|
write_file(path, strings.to_string(sb))
|
||||||
|
}
|
||||||
|
|
||||||
|
write_md_options :: proc(sb: ^strings.Builder, flags: bit_set[Flag_Type]) {
|
||||||
|
displays := make([dynamic]string, 0, 5, context.temp_allocator)
|
||||||
|
defer delete(displays)
|
||||||
|
|
||||||
|
descs := make([dynamic]string, 0, 5, context.temp_allocator)
|
||||||
|
defer delete(descs)
|
||||||
|
|
||||||
|
max_width := 0
|
||||||
|
|
||||||
|
for ft in Flag_Type {
|
||||||
|
if ft not_in flags do continue
|
||||||
|
f := flag_field(ft)
|
||||||
|
|
||||||
|
display: string
|
||||||
|
if len(f.short_name) > 0 {
|
||||||
|
display = fmt.tprintf("-%s, --%s", f.short_name, f.long_name)
|
||||||
|
} else {
|
||||||
|
display = fmt.tprintf(" --%s", f.long_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
desc := f.usage
|
||||||
|
if len(f.default_val) > 0 {
|
||||||
|
#partial switch f.kind {
|
||||||
|
case .String:
|
||||||
|
desc = fmt.tprintf(`%s (default "%s")`, f.usage, f.default_val)
|
||||||
|
case .Enum:
|
||||||
|
desc = fmt.tprintf("%s (default '%s')", f.usage, f.default_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
append(&displays, display)
|
||||||
|
append(&descs, desc)
|
||||||
|
if len(display) > max_width {
|
||||||
|
max_width = len(display)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.sbprintf(sb, "```\n")
|
||||||
|
pad_buf: [64]u8
|
||||||
|
for i in 0..<len(displays) {
|
||||||
|
padding := max_width - len(displays[i]) + 3
|
||||||
|
for j in 0..<padding {
|
||||||
|
pad_buf[j] = ' '
|
||||||
|
}
|
||||||
|
fmt.sbprintf(sb, " %s%s%s\n", displays[i], string(pad_buf[:padding]), descs[i])
|
||||||
|
}
|
||||||
|
fmt.sbprintf(sb, "```\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
write_file :: proc(path: string, content: string) {
|
||||||
|
err := os.write_entire_file(path, transmute([]u8)content)
|
||||||
|
if err != nil {
|
||||||
|
fmt.eprintf("Error writing %s: %v\n", path, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -14,77 +14,81 @@ when SPALL {
|
|||||||
spall_buffer: spall.Buffer
|
spall_buffer: spall.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: proc() {
|
when !#config(GENDOCS, false) {
|
||||||
when SPALL {
|
main :: proc() {
|
||||||
ctx, spall_ok := spall.context_create_with_scale("envr.spall", false, 1.0)
|
when SPALL {
|
||||||
if !spall_ok {
|
ctx, spall_ok := spall.context_create_with_scale("envr.spall", false, 1.0)
|
||||||
fmt.eprintln("Failed to create spall trace file")
|
if !spall_ok {
|
||||||
|
fmt.eprintln("Failed to create spall trace file")
|
||||||
|
os.exit(1)
|
||||||
|
}
|
||||||
|
spall_ctx = ctx
|
||||||
|
defer spall.context_destroy(&spall_ctx)
|
||||||
|
|
||||||
|
spall_backing := make([]u8, spall.BUFFER_DEFAULT_SIZE)
|
||||||
|
defer delete(spall_backing)
|
||||||
|
|
||||||
|
spall_buffer = spall.buffer_create(spall_backing, u32(sync.current_thread_id()))
|
||||||
|
defer spall.buffer_destroy(&spall_ctx, &spall_buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
when ODIN_DEBUG {
|
||||||
|
heap_track: mem.Tracking_Allocator
|
||||||
|
mem.tracking_allocator_init(&heap_track, context.allocator)
|
||||||
|
defer mem.tracking_allocator_destroy(&heap_track)
|
||||||
|
defer if len(heap_track.allocation_map) > 0 {
|
||||||
|
for _, leak in heap_track.allocation_map {
|
||||||
|
fmt.eprintf("LEAK: %v leaked %m\n", leak.location, leak.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.allocator = mem.tracking_allocator(&heap_track)
|
||||||
|
|
||||||
|
temp_track: mem.Tracking_Allocator
|
||||||
|
mem.tracking_allocator_init(&temp_track, context.temp_allocator)
|
||||||
|
defer mem.tracking_allocator_destroy(&temp_track)
|
||||||
|
context.temp_allocator = mem.tracking_allocator(&temp_track)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer free_all(context.temp_allocator)
|
||||||
|
|
||||||
|
cmd, ok := parse_args(os.args, os.to_writer(os.stdout), os.to_writer(os.stderr))
|
||||||
|
defer delete_command(&cmd) // delete flushes automatically
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch cmd.name {
|
||||||
|
case "init":
|
||||||
|
cmd_init(&cmd)
|
||||||
|
case "version":
|
||||||
|
cmd_version(&cmd)
|
||||||
|
case "list":
|
||||||
|
cmd_list(&cmd)
|
||||||
|
case "backup", "add":
|
||||||
|
cmd_backup(&cmd)
|
||||||
|
case "remove":
|
||||||
|
cmd_remove(&cmd)
|
||||||
|
case "restore":
|
||||||
|
cmd_restore(&cmd)
|
||||||
|
case "edit-config":
|
||||||
|
cmd_edit_config(&cmd)
|
||||||
|
case "check":
|
||||||
|
cmd_check(&cmd)
|
||||||
|
case "scan":
|
||||||
|
cmd_scan(&cmd)
|
||||||
|
case "sync":
|
||||||
|
cmd_sync(&cmd)
|
||||||
|
case "completion":
|
||||||
|
cmd_completion(&cmd)
|
||||||
|
case "uninstall":
|
||||||
|
cmd_uninstall(&cmd)
|
||||||
|
case:
|
||||||
|
fmt.wprintf(cmd.err, "Unknown command: %s\n", cmd.name)
|
||||||
|
write_usage(cmd.out)
|
||||||
os.exit(1)
|
os.exit(1)
|
||||||
}
|
}
|
||||||
spall_ctx = ctx
|
|
||||||
defer spall.context_destroy(&spall_ctx)
|
|
||||||
|
|
||||||
spall_backing := make([]u8, spall.BUFFER_DEFAULT_SIZE)
|
|
||||||
defer delete(spall_backing)
|
|
||||||
|
|
||||||
spall_buffer = spall.buffer_create(spall_backing, u32(sync.current_thread_id()))
|
|
||||||
defer spall.buffer_destroy(&spall_ctx, &spall_buffer)
|
|
||||||
}
|
}
|
||||||
|
} // !GENDOCS
|
||||||
when ODIN_DEBUG {
|
|
||||||
heap_track: mem.Tracking_Allocator
|
|
||||||
mem.tracking_allocator_init(&heap_track, context.allocator)
|
|
||||||
defer mem.tracking_allocator_destroy(&heap_track)
|
|
||||||
defer if len(heap_track.allocation_map) > 0 {
|
|
||||||
for _, leak in heap_track.allocation_map {
|
|
||||||
fmt.eprintf("LEAK: %v leaked %m\n", leak.location, leak.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
context.allocator = mem.tracking_allocator(&heap_track)
|
|
||||||
|
|
||||||
temp_track: mem.Tracking_Allocator
|
|
||||||
mem.tracking_allocator_init(&temp_track, context.temp_allocator)
|
|
||||||
defer mem.tracking_allocator_destroy(&temp_track)
|
|
||||||
context.temp_allocator = mem.tracking_allocator(&temp_track)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer free_all(context.temp_allocator)
|
|
||||||
|
|
||||||
cmd, ok := parse_args(os.args, os.to_writer(os.stdout), os.to_writer(os.stderr))
|
|
||||||
defer delete_command(&cmd) // delete flushes automatically
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch cmd.name {
|
|
||||||
case "init":
|
|
||||||
cmd_init(&cmd)
|
|
||||||
case "version":
|
|
||||||
cmd_version(&cmd)
|
|
||||||
case "list":
|
|
||||||
cmd_list(&cmd)
|
|
||||||
case "backup", "add":
|
|
||||||
cmd_backup(&cmd)
|
|
||||||
case "remove":
|
|
||||||
cmd_remove(&cmd)
|
|
||||||
case "restore":
|
|
||||||
cmd_restore(&cmd)
|
|
||||||
case "edit-config":
|
|
||||||
cmd_edit_config(&cmd)
|
|
||||||
case "check":
|
|
||||||
cmd_check(&cmd)
|
|
||||||
case "scan":
|
|
||||||
cmd_scan(&cmd)
|
|
||||||
case "sync":
|
|
||||||
cmd_sync(&cmd)
|
|
||||||
case "completion":
|
|
||||||
cmd_completion(&cmd)
|
|
||||||
case:
|
|
||||||
fmt.wprintf(cmd.err, "Unknown command: %s\n", cmd.name)
|
|
||||||
write_usage(cmd.out)
|
|
||||||
os.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when SPALL {
|
when SPALL {
|
||||||
@(instrumentation_enter)
|
@(instrumentation_enter)
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
0.4.0
|
1.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user