feat: add versioning
This commit is contained in:
23
AGENTS.md
23
AGENTS.md
@@ -218,3 +218,26 @@ When behavior changes:
|
||||
If a product decision would materially affect persistence compatibility,
|
||||
GitHub writes, AI data exposure, destructive behavior, or default keybindings,
|
||||
ask the repository owner rather than guessing.
|
||||
|
||||
## Semantic versioning
|
||||
|
||||
The application version lives in `version.go` and must use Semantic Versioning
|
||||
in `MAJOR.MINOR.PATCH` form.
|
||||
|
||||
- Keep the major version at `0` until the repository owner explicitly requests
|
||||
a `1.0.0` or later release.
|
||||
- Increment `MINOR` and reset `PATCH` to zero for a completed new
|
||||
backward-compatible feature. During `0.x`, also use a minor increment for an
|
||||
intentional breaking change and document that break.
|
||||
- Increment `PATCH` for a completed backward-compatible bug fix, refinement,
|
||||
or other non-feature change.
|
||||
- Apply one version increment per complete logical change, not per user prompt.
|
||||
Follow-up questions and refinements that finish the same feature share that
|
||||
feature's single version increment.
|
||||
- Before incrementing, determine the logical change boundary from the
|
||||
conversation and current work. When the boundary is unclear and Jujutsu is
|
||||
available, inspect the current change and its parent read-only; an empty
|
||||
described parent may identify the feature being developed. Never mutate
|
||||
Jujutsu history merely to determine a version.
|
||||
- If the current logical change already contains the appropriate version
|
||||
increment, do not increment it again for another prompt in that same change.
|
||||
|
||||
@@ -134,6 +134,7 @@ Adjust polling or inspect all command-line options:
|
||||
|
||||
```sh
|
||||
diple --poll 15s
|
||||
diple --version
|
||||
diple --help
|
||||
```
|
||||
|
||||
|
||||
17
cli.go
17
cli.go
@@ -8,6 +8,17 @@ import (
|
||||
|
||||
var completionShells = []string{"bash", "zsh", "fish"}
|
||||
|
||||
func handleVersionCommand(args []string, output io.Writer) (bool, error) {
|
||||
if len(args) == 0 || args[0] != "--version" {
|
||||
return false, nil
|
||||
}
|
||||
if len(args) != 1 {
|
||||
return true, fmt.Errorf("usage: diple --version")
|
||||
}
|
||||
_, err := fmt.Fprintf(output, "diple %s\n", dipleVersion)
|
||||
return true, err
|
||||
}
|
||||
|
||||
func handleCompletionCommand(args []string, output io.Writer) (bool, error) {
|
||||
if len(args) == 0 || args[0] != "completion" {
|
||||
return false, nil
|
||||
@@ -55,6 +66,7 @@ func writeCLIHelp(output io.Writer, defaults Config, configPath string) {
|
||||
|
||||
Usage:
|
||||
diple [options]
|
||||
diple --version
|
||||
diple completion <bash|zsh|fish>
|
||||
diple help
|
||||
|
||||
@@ -92,6 +104,7 @@ Local state:
|
||||
|
||||
Other:
|
||||
-h, --help Show this help and exit.
|
||||
--version Show the application version and exit.
|
||||
|
||||
Boolean options accept explicit values, for example --cache=false.
|
||||
Command-line options override TOML settings. GH_REPO is used only when
|
||||
@@ -158,7 +171,7 @@ _diple_completion() {
|
||||
;;
|
||||
esac
|
||||
|
||||
local options="--repo --all --limit --poll --endpoint --theme --dashboard-mode --thread-list-width --fold-resolved --compact-reviews --path-scroll --path-scroll-interval --editor-mode --config --cache --cache-max-age --cache-dir --help -h"
|
||||
local options="--repo --all --limit --poll --endpoint --theme --dashboard-mode --thread-list-width --fold-resolved --compact-reviews --path-scroll --path-scroll-interval --editor-mode --config --cache --cache-max-age --cache-dir --version --help -h"
|
||||
COMPREPLY=($(compgen -W "${options}" -- "${current}"))
|
||||
}
|
||||
complete -F _diple_completion diple
|
||||
@@ -202,6 +215,7 @@ _diple() {
|
||||
'--cache=[enable local read cache]:boolean:(true false)' \
|
||||
'--cache-max-age[maximum offline cache age]:duration:' \
|
||||
'--cache-dir[local read-cache directory]:directory:_directories' \
|
||||
'--version[show application version]' \
|
||||
'(-h --help)'{-h,--help}'[show help]'
|
||||
}
|
||||
|
||||
@@ -234,5 +248,6 @@ complete -c diple -l config -r -F -d 'TOML configuration file'
|
||||
complete -c diple -l cache -d 'Enable local read cache'
|
||||
complete -c diple -l cache-max-age -x -d 'Maximum offline cache age'
|
||||
complete -c diple -l cache-dir -r -a '(__fish_complete_directories)' -d 'Local read-cache directory'
|
||||
complete -c diple -l version -d 'Show application version'
|
||||
complete -c diple -s h -l help -d 'Show help'
|
||||
`
|
||||
|
||||
25
cli_test.go
25
cli_test.go
@@ -2,10 +2,34 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVersionCommandPrintsSemanticVersion(t *testing.T) {
|
||||
var output bytes.Buffer
|
||||
handled, err := handleVersionCommand([]string{"--version"}, &output)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !handled || output.String() != "diple "+dipleVersion+"\n" {
|
||||
t.Fatalf("version output = %q, handled=%t", output.String(), handled)
|
||||
}
|
||||
if !regexp.MustCompile(`^0\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$`).MatchString(dipleVersion) {
|
||||
t.Fatalf("version %q is not a pre-1.0 semantic version", dipleVersion)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionCommandRejectsAdditionalArguments(t *testing.T) {
|
||||
handled, err := handleVersionCommand(
|
||||
[]string{"--version", "--help"}, &bytes.Buffer{},
|
||||
)
|
||||
if !handled || err == nil || !strings.Contains(err.Error(), "usage: diple --version") {
|
||||
t.Fatalf("handled=%t error=%v", handled, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompletionCommandGeneratesSupportedShells(t *testing.T) {
|
||||
for _, shell := range completionShells {
|
||||
t.Run(shell, func(t *testing.T) {
|
||||
@@ -65,6 +89,7 @@ func TestCLIHelpIsGroupedAndActionable(t *testing.T) {
|
||||
"Appearance and navigation:",
|
||||
"Local state:",
|
||||
"diple completion <bash|zsh|fish>",
|
||||
"--version",
|
||||
"--repo OWNER/REPOSITORY",
|
||||
"--cache=false",
|
||||
"gh auth login",
|
||||
|
||||
6
main.go
6
main.go
@@ -11,6 +11,12 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
if handled, err := handleVersionCommand(os.Args[1:], os.Stdout); handled {
|
||||
if err != nil {
|
||||
exitf("%v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if handled, err := handleCompletionCommand(os.Args[1:], os.Stdout); handled {
|
||||
if err != nil {
|
||||
exitf("%v", err)
|
||||
|
||||
3
version.go
Normal file
3
version.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package main
|
||||
|
||||
const dipleVersion = "0.1.0"
|
||||
Reference in New Issue
Block a user