diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 38b1608..66b9a74 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Maintaining the examples -Keep each example a small standard-library terminal program. All eight must: +Keep each example a small standard-library terminal program. All nine must: - Read `DEMO_SECRET` from the process environment without a Sotto SDK. - Reject an absent or empty value with exit code `1` and the documented stderr message. @@ -18,12 +18,13 @@ python3 scripts/check_examples.py On Windows use `py -3` in place of `python3`. To check only installed languages: ```sh -python3 scripts/check_examples.py python javascript typescript java go +python3 scripts/check_examples.py python javascript typescript java go rust ``` -The repository's maintenance workflow checks all eight languages on macOS, +The repository's maintenance workflow checks all nine languages on macOS, Linux, and Windows with synthetic environment values. A separate Linux job -checks the real `sotto init` / `set` / `run` flow with a disposable OS keyring. +checks the real `sotto` local flow (`status`, `init`, `env`, `set`, `ls`, `run`, +`import`, and `lock`/`unlock`) with a disposable OS keyring. It uses no hosted account or repository secrets. This is validation for these examples; user-facing CI integration belongs in [sotto-action](https://github.com/getsotto/sotto-action). diff --git a/README.md b/README.md index 6a0cb5e..a3069f3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Sotto examples -**One secret. Eight languages. No account required.** +**One secret. Nine languages. No account required.** Try [Sotto](https://github.com/getsotto/sotto) locally with a tiny terminal program. Store `DEMO_SECRET` in an encrypted local vault, then let `sotto run` supply it to @@ -11,7 +11,7 @@ your program. No SDK, application dependencies, server, or `.env` file needed. *Animated walkthrough; first-run prompts are summarised. Copyable steps are below.* [Python](python/) · [JavaScript](javascript/) · [TypeScript](typescript/) · -[Java](java/) · [C#](csharp/) · [PHP](php/) · [Go](go/) · [C++](cpp/) +[Java](java/) · [C#](csharp/) · [PHP](php/) · [Go](go/) · [Rust](rust/) · [C++](cpp/) ## Quick start with Python @@ -40,7 +40,7 @@ cd sotto-example sotto --version ``` -Already have Sotto? Skip the installer. You can also click **Use this template** +Already have Sotto? Skip the installer. On macOS 15 or newer, you can also install via the [Homebrew tap preview](https://github.com/getsotto/homebrew-tap#readme) with `brew install getsotto/tap/sotto`. You can also click **Use this template** on GitHub and clone your own copy. For manual downloads and verification, see [Sotto's installation instructions](https://github.com/getsotto/sotto#install). @@ -79,9 +79,11 @@ already use Sotto, it reuses your local identity and creates a new project for this directory; you may be asked to unlock it. At the hidden `Value:` prompt, enter `hello-from-sotto` and press Enter. This is -just a made-up demo value. Your typing will not appear in the terminal. +just a made-up demo value. Your typing will not appear in the terminal. In a +POSIX shell script or pipeline, you can also pass a synthetic value on standard +input with `printf '%s' 'hello-from-sotto' | sotto set DEMO_SECRET --stdin`. -Initialise once at the repository root. All eight examples share this project. +Initialise once at the repository root. All nine examples share this project. Your generated `sotto.toml` is ignored by Git so each visitor creates their own project. ### 4. Run with Sotto @@ -118,17 +120,18 @@ repository root on macOS, Linux, or Windows PowerShell unless noted. | Language | Prerequisite | Run | | --- | --- | --- | | [Python](python/) | Python 3 | `sotto run -- python3 python/main.py` (Windows: `sotto run -- py -3 python/main.py`) | -| [JavaScript](javascript/) | Node.js 24 LTS | `sotto run -- node javascript/main.js` | -| [TypeScript](typescript/) | Node.js 24.12+ | `sotto run -- node typescript/main.ts` | +| [JavaScript](javascript/) | Node.js 18+ | `sotto run -- node javascript/main.js` | +| [TypeScript](typescript/) | Node.js 22.18+ | `sotto run -- node typescript/main.ts` | | [Java](java/) | JDK 17+ | `sotto run -- java java/Main.java` | -| [C#](csharp/) | .NET 10 SDK | `sotto run -- dotnet run --project csharp/Demo.csproj` | +| [C#](csharp/) | .NET 8+ SDK | `sotto run -- dotnet run --project csharp/Demo.csproj` | | [PHP](php/) | PHP 8 CLI | `sotto run -- php php/main.php` | | [Go](go/) | Go 1.22+ | `sotto run -- go run go/main.go` | +| [Rust](rust/) | Rust and Cargo | `sotto run -- cargo run --quiet --manifest-path rust/Cargo.toml` | | [C++](cpp/) | CMake 3.20+ and a C++17 compiler | Build first; see below. | Node runs this small TypeScript example using its [built-in type stripping](https://nodejs.org/api/typescript.html), so it needs no -package install. Java's source-file launcher and `go run` handle compilation for +package install. Java's source-file launcher, `go run`, and `cargo run` handle compilation for their examples. C# uses the .NET SDK to build its dependency-free project. For C++, install CMake and a compiler (Clang/GCC on macOS or Linux; Visual Studio @@ -154,6 +157,47 @@ sotto run -- .\cpp\build\demo.exe Every example produces the same success message and returns `0`. A missing or empty secret produces the same helpful error on stderr and returns `1`. +## Explore more local features + +Everything below also works locally without an account or server. + +### Promote secrets across environments + +`sotto init` creates `dev`, `staging`, and `prod` environments and selects `dev`. +Compare `dev` with `staging`, copy `DEMO_SECRET` into `staging`, and run the +demo against `staging` without changing your default environment: + +```sh +sotto env ls +sotto env diff dev staging +sotto env copy dev staging --confirm +sotto run --env staging -- python3 python/main.py +``` + +### Import an existing dotenv file + +If you already have a `.env` file, `sotto import` encrypts each assignment into +your local store without modifying or deleting the file: + +```sh +sotto import .env +sotto import --env staging .env.staging +sotto ls --json +``` + +### Inspect status, lock, and change themes + +Check whether your local identity is set up and unlocked, clear the cached +session key when you finish, or switch between built-in terminal themes: + +```sh +sotto status +sotto status --json +sotto theme ls +sotto lock +sotto unlock +``` + ## How it works ```mermaid @@ -176,6 +220,9 @@ GNOME Keyring); see [troubleshooting](#troubleshooting) for headless machines. ## Troubleshooting +- **Check local state first:** run `sotto status` (or `sotto status --json`) from + the repository root to see whether a local identity is initialised, whether your + session is unlocked, and which project and environment are selected. - **`sotto` not found:** add the install directory to your current shell's `PATH` using the command shown above. To keep it available in future terminals, add `~/.local/bin` to your shell configuration on macOS/Linux, or @@ -200,6 +247,8 @@ GNOME Keyring); see [troubleshooting](#troubleshooting) for headless machines. - [Sotto](https://github.com/getsotto/sotto): encrypted sync, teams, and the full CLI. - [Sotto Action](https://github.com/getsotto/sotto-action): GitHub Actions setup and CI examples. +- [Sotto VS Code extension](https://github.com/getsotto/sotto-vscode): local VS Code task integration preview. +- [Sotto Homebrew tap](https://github.com/getsotto/homebrew-tap): macOS Homebrew formula preview. - [Maintaining the examples and animation](CONTRIBUTING.md). ## License diff --git a/docs/demo.gif b/docs/demo.gif index f0367d5..0539c2f 100644 Binary files a/docs/demo.gif and b/docs/demo.gif differ diff --git a/scripts/render_demo.py b/scripts/render_demo.py index e7d4ede..fdb4c5a 100644 --- a/scripts/render_demo.py +++ b/scripts/render_demo.py @@ -30,7 +30,7 @@ def font(size): ("Set it with `sotto set DEMO_SECRET`, then run this demo", MUTED), ("with `sotto run -- `.", MUTED), ]), - ("02 / Initialise locally", "No account. No server. One setup for all eight languages.", [ + ("02 / Initialise locally", "No account. No server. One setup for all nine languages.", [ ("$ sotto init", TEXT), ("[First run: choose and confirm a master password]", MUTED), ("[Save your Emergency Kit privately]", MUTED), @@ -45,7 +45,7 @@ def font(size): ("$ sotto run -- python3 python/main.py", TEXT), ("Sotto demo: secret loaded successfully.", ACCENT), ("", TEXT), - ("Same setup. Python + seven more languages.", MUTED), + ("Same setup. Python + eight more languages.", MUTED), ]), ]