diff options
author | EuAndreh <eu@euandre.org> | 2025-05-04 09:12:26 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2025-05-04 09:12:26 -0300 |
commit | f5187787c58670e80884078bd8eca5335e5b37e7 (patch) | |
tree | cdc6afc123e95c4537fadd436879b5929801bd85 | |
parent | re s/guuid/uuid/g (diff) | |
download | uuid-f5187787c58670e80884078bd8eca5335e5b37e7.tar.gz uuid-f5187787c58670e80884078bd8eca5335e5b37e7.tar.xz |
Add standalone uuid(1) utility
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 42 | ||||
-rw-r--r-- | deps.mk | 16 | ||||
-rw-r--r-- | doc/uuid.en.1.adoc | 134 | ||||
-rwxr-xr-x | mkdeps.sh | 13 | ||||
-rw-r--r-- | src/main.go | 7 | ||||
-rw-r--r-- | src/uuid.go | 16 | ||||
-rwxr-xr-x | tests/cli-opts.sh | 0 | ||||
-rwxr-xr-x | tests/integration.sh | 0 |
9 files changed, 209 insertions, 20 deletions
@@ -1,3 +1,4 @@ +/doc/*.[0-9] /src/version.go /*.bin /src/*.a @@ -24,7 +24,7 @@ GOLDFLAGS = -L $(GOLIBDIR) .SUFFIXES: -.SUFFIXES: .go .a .bin .bin-check +.SUFFIXES: .go .a .bin .bin-check .adoc .go.a: go tool compile -I $(@D) $(GOCFLAGS) -o $@ -p $(*F) \ @@ -34,22 +34,27 @@ GOLDFLAGS = -L $(GOLIBDIR) .a.bin: go tool link -L $(@D) $(GOLDFLAGS) -o $@ --extldflags '$(LDLIBS)' $< +.adoc: + asciidoctor -b manpage -o $@ $< + all: include deps.mk -libs.a = $(libs.go:.go=.a) -mains.a = $(mains.go:.go=.a) -mains.bin = $(mains.go:.go=.bin) -functional/lib.a = $(functional/lib.go:.go=.a) -fuzz/lib.a = $(fuzz/lib.go:.go=.a) -benchmarks/lib.a = $(benchmarks/lib.go:.go=.a) +libs.a = $(libs.go:.go=.a) +mains.a = $(mains.go:.go=.a) +mains.bin = $(mains.go:.go=.bin) +functional-tests/lib.a = $(functional-tests/lib.go:.go=.a) +fuzz-targets/lib.a = $(fuzz-targets/lib.go:.go=.a) +benchmarks/lib.a = $(benchmarks/lib.go:.go=.a) +manpages.N = $(manpages.N.adoc:.adoc=) sources = \ src/$(NAME).go \ src/version.go \ + src/main.go \ derived-assets = \ @@ -57,6 +62,8 @@ derived-assets = \ $(libs.a) \ $(mains.a) \ $(mains.bin) \ + $(NAME).bin \ + $(manpages.N) \ side-assets = \ tests/fuzz/corpus/ \ @@ -73,18 +80,21 @@ $(libs.a): Makefile deps.mk $(libs.a): src/$(NAME).go src/version.go -$(fuzz/lib.a): +$(fuzz-targets/lib.a): go tool compile $(GOCFLAGS) -o $@ -p $(NAME) -d=libfuzzer \ $*.go src/$(NAME).go src/version.go src/version.go: Makefile echo 'package $(NAME); const Version = "$(VERSION)"' > $@ +$(NAME).bin: src/main.bin + ln -fs src/main.bin $@ + tests.bin-check = \ tests/main.bin-check \ - $(functional/main.go:.go=.bin-check) \ + $(functional-tests/main.go:.go=.bin-check) \ $(tests.bin-check): $(EXEC)$*.bin @@ -93,6 +103,8 @@ check-unit: $(tests.bin-check) integration-tests = \ + tests/cli-opts.sh \ + tests/integration.sh \ .PRECIOUS: $(integration-tests) $(integration-tests): $(NAME).bin @@ -111,12 +123,12 @@ check: check-unit check-integration FUZZSEC=1 -fuzz/main.bin-check = $(fuzz/main.go:.go=.bin-check) -$(fuzz/main.bin-check): +fuzz-targets/main.bin-check = $(fuzz-targets/main.go:.go=.bin-check) +$(fuzz-targets/main.bin-check): $(EXEC)$*.bin --test.fuzztime=$(FUZZSEC)s \ --test.fuzz='.*' --test.fuzzcachedir=tests/fuzz/corpus -fuzz: $(fuzz/main.bin-check) +fuzz: $(fuzz-targets/main.bin-check) @@ -140,20 +152,26 @@ clean: ## ensures that all installable artifacts are crafted beforehand. install: all mkdir -p \ + '$(DESTDIR)$(BINDIR)' \ '$(DESTDIR)$(GOLIBDIR)' \ '$(DESTDIR)$(SRCDIR)' \ + cp $(NAME).bin '$(DESTDIR)$(BINDIR)'/$(NAME) cp src/$(NAME).a '$(DESTDIR)$(GOLIBDIR)' cp $(sources) '$(DESTDIR)$(SRCDIR)' + mandir install '$(DESTDIR)$(MANDIR)' $(manpages.N) ## Uninstalls from $(DESTDIR)$(PREFIX). This is a perfect mirror ## of the "install" target, and removes *all* that was installed. ## A dedicated test asserts that this is always true. uninstall: rm -rf \ + '$(DESTDIR)$(BINDIR)'/$(NAME) \ '$(DESTDIR)$(GOLIBDIR)'/$(NAME).a \ '$(DESTDIR)$(SRCDIR)' \ + mandir uninstall '$(DESTDIR)$(MANDIR)' $(manpages.N) + ALWAYS: @@ -7,23 +7,27 @@ libs.go = \ tests/uuid.go \ mains.go = \ + src/main.go \ tests/benchmarks/string-roundtrip/main.go \ tests/functional/string-round-trip/main.go \ tests/fuzz/from-string/main.go \ tests/fuzz/new-from/main.go \ tests/main.go \ -functional/lib.go = \ +manpages.N.adoc = \ + doc/uuid.en.1.adoc \ + +functional-tests/lib.go = \ tests/functional/string-round-trip/uuid.go \ -functional/main.go = \ +functional-tests/main.go = \ tests/functional/string-round-trip/main.go \ -fuzz/lib.go = \ +fuzz-targets/lib.go = \ tests/fuzz/from-string/uuid.go \ tests/fuzz/new-from/uuid.go \ -fuzz/main.go = \ +fuzz-targets/main.go = \ tests/fuzz/from-string/main.go \ tests/fuzz/new-from/main.go \ @@ -33,6 +37,7 @@ benchmarks/lib.go = \ benchmarks/main.go = \ tests/benchmarks/string-roundtrip/main.go \ +src/main.a: src/main.go src/uuid.a: src/uuid.go tests/benchmarks/string-roundtrip/main.a: tests/benchmarks/string-roundtrip/main.go tests/benchmarks/string-roundtrip/uuid.a: tests/benchmarks/string-roundtrip/uuid.go @@ -44,16 +49,19 @@ tests/fuzz/new-from/main.a: tests/fuzz/new-from/main.go tests/fuzz/new-from/uuid.a: tests/fuzz/new-from/uuid.go tests/main.a: tests/main.go tests/uuid.a: tests/uuid.go +src/main.bin: src/main.a tests/benchmarks/string-roundtrip/main.bin: tests/benchmarks/string-roundtrip/main.a tests/functional/string-round-trip/main.bin: tests/functional/string-round-trip/main.a tests/fuzz/from-string/main.bin: tests/fuzz/from-string/main.a tests/fuzz/new-from/main.bin: tests/fuzz/new-from/main.a tests/main.bin: tests/main.a +src/main.bin-check: src/main.bin tests/benchmarks/string-roundtrip/main.bin-check: tests/benchmarks/string-roundtrip/main.bin tests/functional/string-round-trip/main.bin-check: tests/functional/string-round-trip/main.bin tests/fuzz/from-string/main.bin-check: tests/fuzz/from-string/main.bin tests/fuzz/new-from/main.bin-check: tests/fuzz/new-from/main.bin tests/main.bin-check: tests/main.bin +src/main.a: src/$(NAME).a tests/benchmarks/string-roundtrip/main.a: tests/benchmarks/string-roundtrip/$(NAME).a tests/functional/string-round-trip/main.a: tests/functional/string-round-trip/$(NAME).a tests/fuzz/from-string/main.a: tests/fuzz/from-string/$(NAME).a diff --git a/doc/uuid.en.1.adoc b/doc/uuid.en.1.adoc new file mode 100644 index 0000000..6366acb --- /dev/null +++ b/doc/uuid.en.1.adoc @@ -0,0 +1,134 @@ += uuid(1) + + + +== NAME + +uuid - generate or validate a UUIDv4 + + + +== SYNOPSYS + +*uuid* [_STRING_] + + + +== EXAMPLES + + +=== Print a UUID on the terminal + +.... +$ uuid +d3891787-c952-af17-d697-0df3b85981e1 +.... + + +=== Create a new UUID as part of a path + +.... +dir="$PWD"/"$(uuid)"/data +.... + + +=== Validate a given UUID + +.... +ID="$(basename -- "$directory")" +if ! uuid "$ID"; then + echo "Bad UUID in directory: $ID" >&2 + exit 1 +fi +.... + + + +== DESCRIPTION + +The *uuid* utility generates a new UUID when no _STRING_ is given and write it +to _stdout_. If a _STRING_ is given, *uuid* validates it and exits, and +produces no output. + + + +== OPERANDS + +_STRING_:: If it is + + *not given*::: generate a brand new random UUIDv4, print it to _stdout_ and exit + normally; + *given*::: test if it is a valid UUIDv4 and exit normally if so. + + + +== IO + + +=== STDIN + +Not used. + + +=== STDOUT + +The UUIDv4 format is made of byte blocks encoded as hexadecimals, using a +<hyphen-minus>('`-`') as the block separator: + +.... +XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX +.... + +An example output is: + +.... +cb46d0c0-b2aa-4a6c-a119-8deace2544a2 +.... + + +=== STDERR + +Not used. + + +=== INPUT FILES + +None. + + +=== OUTPUT FILES + +None. + + + +== EXIT STATUS + +0:: Generating or validating a UUID was successfull. +3:: UUID validation failed. + + + +== CONFORMING TO + +The v4 UUID defined in *RFC 9562*. + + + +== SEE ALSO + + + +== AUTHORS + +mailto:eu@euandre.org[EuAndreh] and contributors. + + + +== BUGS + +* Report bugs to the mailto:~euandreh/public-inbox@lists.sr.ht[mailing list]. + Use the subject "[uuid] BUG or TASK: <description>". +* Browse bugs https://euandre.org/git/uuid/TODOs.html[online]. +* https://euandre.org/git/uuid/[Homepage]. +* https://lists.sr.ht/~euandreh/public-inbox?search=%5Buuid%5D[Comments and discussions]. @@ -13,13 +13,18 @@ mains() { find src tests -name '*.go' | grep '/main\.go$' } +docs() { + find doc/*.adoc +} + libs | varlist 'libs.go' mains | varlist 'mains.go' +docs | varlist 'manpages.N.adoc' -find tests/functional/*/*.go -not -name main.go | varlist 'functional/lib.go' -find tests/functional/*/main.go | varlist 'functional/main.go' -find tests/fuzz/*/*.go -not -name main.go | varlist 'fuzz/lib.go' -find tests/fuzz/*/main.go | varlist 'fuzz/main.go' +find tests/functional/*/*.go -not -name main.go | varlist 'functional-tests/lib.go' +find tests/functional/*/main.go | varlist 'functional-tests/main.go' +find tests/fuzz/*/*.go -not -name main.go | varlist 'fuzz-targets/lib.go' +find tests/fuzz/*/main.go | varlist 'fuzz-targets/main.go' find tests/benchmarks/*/*.go -not -name main.go | varlist 'benchmarks/lib.go' find tests/benchmarks/*/main.go | varlist 'benchmarks/main.go' diff --git a/src/main.go b/src/main.go new file mode 100644 index 0000000..d3c7f21 --- /dev/null +++ b/src/main.go @@ -0,0 +1,7 @@ +package main + +import "uuid" + +func main() { + uuid.Main() +} diff --git a/src/uuid.go b/src/uuid.go index 8b953f8..6c4b8f6 100644 --- a/src/uuid.go +++ b/src/uuid.go @@ -4,7 +4,9 @@ import ( "crypto/rand" "encoding/hex" "errors" + "fmt" "io" + "os" "strings" ) @@ -100,3 +102,17 @@ func FromString(str string) (UUID, error) { return [ByteCount]byte(data), nil } + + + +func Main() { + if len(os.Args) < 2 { + fmt.Println(New().String()) + } else { + _, err := FromString(strings.TrimSpace(os.Args[1])) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(3) + } + } +} diff --git a/tests/cli-opts.sh b/tests/cli-opts.sh new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/tests/cli-opts.sh diff --git a/tests/integration.sh b/tests/integration.sh new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/tests/integration.sh |