# Shellshock

Shared scripting framework for [kernelle-soft](https://codeberg.org/kernelle-soft) projects.

## Usage

Add as a git submodule and bootstrap:

```bash
git submodule add git@codeberg.org:kernelle-soft/shellops.git shell/.ops
shell/.ops/init
```

On subsequent clones, initialize and install tools in one shot:

```bash
git submodule update --init shell/.ops && shell/.ops/init
```

`init` sets up the consumer `.envrc`, `.gitignore`, copies the `ops`
dispatcher to `shell/ops`, and runs `ops install` if a `ops.lock` exists.

```bash
shell/ops install --check
shell/ops git-bump --dry-run
shell/ops git-commit -a
shell/ops git-config
```

## Structure

```
init                # Standalone bootstrap script (no prerequisites)
ops                 # CLI dispatcher (copied to shell/ by consumer)
cli/                # Subcommands (standalone executables)
  install           # Declarative tool installer
  git-bump          # Semver tag bumping
  git-commit        # Automated CI commits
  git-config        # Git user config for CI bots
  publish-release   # Codeberg/Forgejo release creation with prerelease detection
lib/                # Sourceable libraries (.api.sh, .func.sh)
plugins/
  tools/            # Built-in .installer.sh/.uninstaller.sh for script channel
  channels/         # *.channel.sh plugins (system, script, cargo-*, go-install)
schema/             # JSON schemas for manifest.json and ops.lock
```

Consumer project layout:

```
project/
  ops.lock                      # declarative tool definitions
  shell/
    ops                         # dispatcher (copied from .ops/)
    .ops/                       # submodule
  plugins/
    tools/                      # project-specific .installer.sh/.uninstaller.sh
    channels/                   # project-specific channel plugins (optional)
```

## Tool Installation

`ops install` reads tool definitions from `ops.lock` at the project root.
Channels are top-level keys; each tool is an object with at least a `version`:

```json
{
  "cargo-binstall": {
    "tokei": { "version": "14.0.0", "args": "--locked --force" }
  },
  "go-install": {
    "govulncheck": { "version": "1.1.4", "pkg": "golang.org/x/vuln/cmd/govulncheck" }
  },
  "script": {
    "gh": { "version": "latest" }
  }
}
```

The `script` channel (aliased as `local` for backwards compatibility)
delegates to `<tool>.installer.sh` / `<tool>.uninstaller.sh` files
found under `$TOOLS_SCRIPTS_DIR` (defaults to `$PROJ/plugins/tools`).

## Environment

- `PROJ` -- project root (set by consumer's `.envrc` or CI)
- `SHELLOPS_DIR` -- path to the shellops submodule (set by `.envrc`)
- `TOOLS_SCRIPTS_DIR` -- override search path for script-channel installer files (defaults to `$PROJ/plugins/tools`)
