From 327dc6459a02db0cd302f6f74c441ac4095b6915 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Mon, 22 Mar 2021 17:53:36 +0100 Subject: [PATCH] v0.2.6 - converted to go module structure - Better logging - Better error handling - Removed Makefile since github takes care of building/releasing --- Makefile | 101 ---------------------------------------------------- apg.go | 11 +++--- apg_test.go | 66 +++++++++++++++++----------------- go.mod | 3 ++ params.go | 9 ++--- 5 files changed, 45 insertions(+), 145 deletions(-) delete mode 100644 Makefile create mode 100644 go.mod diff --git a/Makefile b/Makefile deleted file mode 100644 index aad01a3..0000000 --- a/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -# The binaries to build (just the basenames). -BINS := apg - -VERSION ?= $(shell grep VersionString apg.go | head -1 | awk '{print $$5}' | sed 's/"//g') -ALL_PLATFORMS := darwin/amd64 darwin/arm64 \ - linux/amd64 linux/arm linux/arm64 linux/ppc64le linux/s390x \ - freebsd/386 freebsd/amd64 freebsd/arm \ - openbsd/386 openbsd/amd64 openbsd/arm \ - netbsd/386 netbsd/amd64 netbsd/arm \ - windows/386 windows/amd64 -OS := $(if $(GOOS),$(GOOS),$(shell go env GOOS)) -ARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH)) -TAG := $(VERSION)__$(OS)_$(ARCH) - -BIN_EXTENSION := -ifeq ($(OS), windows) - BIN_EXTENSION := .exe -endif - -# If you want to build all binaries, see the 'all-build' rule. -all: # @HELP builds binaries for one platform ($OS/$ARCH) -all: build - -# For the following OS/ARCH expansions, we transform OS/ARCH into OS_ARCH -# because make pattern rules don't match with embedded '/' characters. - -build-%: - @$(MAKE) build \ - --no-print-directory \ - GOOS=$(firstword $(subst _, ,$*)) \ - GOARCH=$(lastword $(subst _, ,$*)) - -all-build: # @HELP builds binaries for all platforms -all-build: $(addprefix build-, $(subst /,_, $(ALL_PLATFORMS))) -OUTBINS = $(foreach bin,$(BINS),bin/v$(VERSION)/$(OS)_$(ARCH)/$(bin)$(BIN_EXTENSION)) -build: $(OUTBINS) -BUILD_DIRS := bin/v$(VERSION)/$(OS)_$(ARCH) \ - bin/zip-files/v$(VERSION) \ - .go/bin/v$(VERSION)/$(OS)_$(ARCH) \ - .go/cache - -# Each outbin target is just a facade for the respective stampfile target. -# This `eval` establishes the dependencies for each. -$(foreach outbin,$(OUTBINS),$(eval \ - $(outbin): .go/$(outbin).stamp \ -)) -# This is the target definition for all outbins. -$(OUTBINS): - @true - -# Each stampfile target can reference an $(OUTBIN) variable. -$(foreach outbin,$(OUTBINS),$(eval $(strip \ - .go/$(outbin).stamp: OUTBIN = $(outbin) \ -))) -# This is the target definition for all stampfiles. -# This will build the binary under ./.go and update the real binary iff needed. -STAMPS = $(foreach outbin,$(OUTBINS),.go/$(outbin).stamp) -.PHONY: $(STAMPS) -$(STAMPS): go-build - @echo "binary: $(OUTBIN)" - @if ! cmp -s .go/$(OUTBIN) $(OUTBIN); then \ - mv .go/$(OUTBIN) $(OUTBIN); \ - zip -9 ./bin/zip-files/v$(VERSION)/apg_v$(VERSION)_$(OS)_$(ARCH).zip $(OUTBIN) \ - date >$@; \ - fi - -# This runs the actual `go build` which updates all binaries. -go-build: $(BUILD_DIRS) - @echo - @echo "building for $(OS)/$(ARCH)" - @go build -o .go/bin/v$(VERSION)/$(OS)_$(ARCH)/apg$(BIN_EXTENSION) apg.go - -version: # @HELP outputs the version string -version: - @echo $(VERSION) - - " - -$(BUILD_DIRS): - @mkdir -p $@ - -clean: # @HELP removes built binaries and temporary files -clean: bin-clean - -bin-clean: - rm -rf .go bin *.exe - -help: # @HELP prints this message -help: - @echo "VARIABLES:" - @echo " BINS = $(BINS)" - @echo " OS = $(OS)" - @echo " ARCH = $(ARCH)" - @echo " REGISTRY = $(REGISTRY)" - @echo - @echo "TARGETS:" - @grep -E '^.*: *# *@HELP' $(MAKEFILE_LIST) \ - | awk ' \ - BEGIN {FS = ": *# *@HELP"}; \ - { printf " %-30s %s\n", $$1, $$2 }; \ - ' diff --git a/apg.go b/apg.go index db1147d..3398de8 100644 --- a/apg.go +++ b/apg.go @@ -3,6 +3,7 @@ package main import ( "flag" "fmt" + "log" "os" ) @@ -63,9 +64,11 @@ func init() { flag.Parse() if config.showVersion { _, _ = os.Stderr.WriteString("Winni's Advanced Password Generator Clone (apg.go) v" + VersionString + "\n") - _, _ = os.Stderr.WriteString("© 2021 by Winni Neessen\n") + _, _ = os.Stderr.WriteString("(C) 2021 by Winni Neessen\n") os.Exit(0) } + + log.SetFlags(log.Ltime | log.Ldate | log.Lshortfile) } // Main function that generated the passwords and returns them @@ -77,8 +80,7 @@ func main() { for i := 1; i <= config.numOfPass; i++ { pwString, err := getRandChar(&charRange, pwLength) if err != nil { - fmt.Printf("getRandChar returned an error: %q\n", err.Error()) - os.Exit(1) + log.Fatalf("getRandChar returned an error: %q\n", err) } switch config.outputMode { @@ -86,8 +88,7 @@ func main() { { spelledPw, err := spellPasswordString(pwString) if err != nil { - fmt.Printf("spellPasswordString returned an error: %q\n", err.Error()) - os.Exit(1) + log.Fatalf("spellPasswordString returned an error: %q\n", err.Error()) } fmt.Printf("%v (%v)\n", pwString, spelledPw) break diff --git a/apg_test.go b/apg_test.go index e02a3f9..e411f12 100644 --- a/apg_test.go +++ b/apg_test.go @@ -16,31 +16,31 @@ func TestGetRandNum(t *testing.T) { t.Run("maxNum_is_1000", func(t *testing.T) { randNum, err := getRandNum(1000) if err != nil { - t.Errorf("Random number generation failed: %v", err.Error()) + t.Fatalf("Random number generation failed: %v", err.Error()) } if randNum > 1000 { - t.Errorf("Generated random number between 0 and 1000 is too big: %v", randNum) + t.Fatalf("Generated random number between 0 and 1000 is too big: %v", randNum) } if randNum < 0 { - t.Errorf("Generated random number between 0 and 1000 is too small: %v", randNum) + t.Fatalf("Generated random number between 0 and 1000 is too small: %v", randNum) } }) t.Run("maxNum_is_1", func(t *testing.T) { randNum, err := getRandNum(1) if err != nil { - t.Errorf("Random number generation failed: %v", err.Error()) + t.Fatalf("Random number generation failed: %v", err.Error()) } if randNum > 1 { - t.Errorf("Generated random number between 0 and 1000 is too big: %v", randNum) + t.Fatalf("Generated random number between 0 and 1000 is too big: %v", randNum) } if randNum < 0 { - t.Errorf("Generated random number between 0 and 1000 is too small: %v", randNum) + t.Fatalf("Generated random number between 0 and 1000 is too small: %v", randNum) } }) t.Run("maxNum_is_0", func(t *testing.T) { randNum, err := getRandNum(0) if err == nil { - t.Errorf("Random number expected to fail, but provided a value instead: %v", randNum) + t.Fatalf("Random number expected to fail, but provided a value instead: %v", randNum) } }) } @@ -51,10 +51,10 @@ func TestGetRandChar(t *testing.T) { charRange := "ABC" randChar, err := getRandChar(&charRange, 1) if err != nil { - t.Errorf("Random character generation failed => %v", err.Error()) + t.Fatalf("Random character generation failed => %v", err.Error()) } if randChar != "A" && randChar != "B" && randChar != "C" { - t.Errorf("Random character generation failed. Expected A, B or C but got: %v", randChar) + t.Fatalf("Random character generation failed. Expected A, B or C but got: %v", randChar) } }) @@ -62,10 +62,10 @@ func TestGetRandChar(t *testing.T) { charRange := "ABC" randChar, err := getRandChar(&charRange, 1000) if err != nil { - t.Errorf("Random character generation failed => %v", err.Error()) + t.Fatalf("Random character generation failed => %v", err.Error()) } if len(randChar) != 1000 { - t.Errorf("Generated random characters with 1000 chars returned wrong amount of chars: %v", + t.Fatalf("Generated random characters with 1000 chars returned wrong amount of chars: %v", len(randChar)) } }) @@ -74,7 +74,7 @@ func TestGetRandChar(t *testing.T) { charRange := "ABC" randChar, err := getRandChar(&charRange, -2000) if err == nil { - t.Errorf("Generated random characters expected to fail, but returned a value => %v", + t.Fatalf("Generated random characters expected to fail, but returned a value => %v", randChar) } }) @@ -96,7 +96,7 @@ func TestGetCharRange(t *testing.T) { for _, curChar := range charRange { searchAllowedBytes := containsByte(allowedBytes, int(curChar)) if !searchAllowedBytes { - t.Errorf("Character range for lower-case only returned invalid value: %v", + t.Fatalf("Character range for lower-case only returned invalid value: %v", string(curChar)) } } @@ -115,7 +115,7 @@ func TestGetCharRange(t *testing.T) { for _, curChar := range charRange { searchAllowedBytes := containsByte(allowedBytes, int(curChar)) if !searchAllowedBytes { - t.Errorf("Character range for lower-case only (human readable) returned invalid value: %v", + t.Fatalf("Character range for lower-case only (human readable) returned invalid value: %v", string(curChar)) } } @@ -134,7 +134,7 @@ func TestGetCharRange(t *testing.T) { for _, curChar := range charRange { searchAllowedBytes := containsByte(allowedBytes, int(curChar)) if !searchAllowedBytes { - t.Errorf("Character range for upper-case only returned invalid value: %v", + t.Fatalf("Character range for upper-case only returned invalid value: %v", string(curChar)) } } @@ -153,7 +153,7 @@ func TestGetCharRange(t *testing.T) { for _, curChar := range charRange { searchAllowedBytes := containsByte(allowedBytes, int(curChar)) if !searchAllowedBytes { - t.Errorf("Character range for upper-case only (human readable) returned invalid value: %v", + t.Fatalf("Character range for upper-case only (human readable) returned invalid value: %v", string(curChar)) } } @@ -171,7 +171,7 @@ func TestGetCharRange(t *testing.T) { for _, curChar := range charRange { searchAllowedBytes := containsByte(allowedBytes, int(curChar)) if !searchAllowedBytes { - t.Errorf("Character range for numbers only returned invalid value: %v", + t.Fatalf("Character range for numbers only returned invalid value: %v", string(curChar)) } } @@ -189,7 +189,7 @@ func TestGetCharRange(t *testing.T) { for _, curChar := range charRange { searchAllowedBytes := containsByte(allowedBytes, int(curChar)) if !searchAllowedBytes { - t.Errorf("Character range for numbers (human readable) only returned invalid value: %v", + t.Fatalf("Character range for numbers (human readable) only returned invalid value: %v", string(curChar)) } } @@ -208,7 +208,7 @@ func TestGetCharRange(t *testing.T) { for _, curChar := range charRange { searchAllowedBytes := containsByte(allowedBytes, int(curChar)) if !searchAllowedBytes { - t.Errorf("Character range for special characters only returned invalid value: %v", + t.Fatalf("Character range for special characters only returned invalid value: %v", string(curChar)) } } @@ -226,7 +226,7 @@ func TestGetCharRange(t *testing.T) { for _, curChar := range charRange { searchAllowedBytes := containsByte(allowedBytes, int(curChar)) if !searchAllowedBytes { - t.Errorf("Character range for special characters only returned invalid value: %v", + t.Fatalf("Character range for special characters only returned invalid value: %v", string(curChar)) } } @@ -238,37 +238,37 @@ func TestConvert(t *testing.T) { t.Run("convert_A_to_Alfa", func(t *testing.T) { charToString, err := convertCharToName('A') if err != nil { - t.Errorf("Character to string conversion failed: %v", err.Error()) + t.Fatalf("Character to string conversion failed: %v", err.Error()) } if charToString != "Alfa" { - t.Errorf("Converting 'A' to string did not return the correct value of 'Alfa': %q", charToString) + t.Fatalf("Converting 'A' to string did not return the correct value of 'Alfa': %q", charToString) } }) t.Run("convert_a_to_alfa", func(t *testing.T) { charToString, err := convertCharToName('a') if err != nil { - t.Errorf("Character to string conversion failed: %v", err.Error()) + t.Fatalf("Character to string conversion failed: %v", err.Error()) } if charToString != "alfa" { - t.Errorf("Converting 'a' to string did not return the correct value of 'alfa': %q", charToString) + t.Fatalf("Converting 'a' to string did not return the correct value of 'alfa': %q", charToString) } }) t.Run("convert_0_to_ZERO", func(t *testing.T) { charToString, err := convertCharToName('0') if err != nil { - t.Errorf("Character to string conversion failed: %v", err.Error()) + t.Fatalf("Character to string conversion failed: %v", err.Error()) } if charToString != "ZERO" { - t.Errorf("Converting '0' to string did not return the correct value of 'ZERO': %q", charToString) + t.Fatalf("Converting '0' to string did not return the correct value of 'ZERO': %q", charToString) } }) t.Run("convert_/_to_SLASH", func(t *testing.T) { charToString, err := convertCharToName('/') if err != nil { - t.Errorf("Character to string conversion failed: %v", err.Error()) + t.Fatalf("Character to string conversion failed: %v", err.Error()) } if charToString != "SLASH" { - t.Errorf("Converting '/' to string did not return the correct value of 'SLASH': %q", charToString) + t.Fatalf("Converting '/' to string did not return the correct value of 'SLASH': %q", charToString) } }) t.Run("all_chars_convert_to_string", func(t *testing.T) { @@ -281,7 +281,7 @@ func TestConvert(t *testing.T) { for _, curChar := range charRange { _, err := convertCharToName(byte(curChar)) if err != nil { - t.Errorf("Character to string conversion failed: %v", err.Error()) + t.Fatalf("Character to string conversion failed: %v", err.Error()) } } }) @@ -289,10 +289,10 @@ func TestConvert(t *testing.T) { pwString := "Ab!" spelledString, err := spellPasswordString(pwString) if err != nil { - t.Errorf("password spelling failed: %v", err.Error()) + t.Fatalf("password spelling failed: %v", err.Error()) } if spelledString != "Alfa/bravo/EXCLAMATION_POINT" { - t.Errorf( + t.Fatalf( "Spelling pwString 'Ab!' is expected to provide 'Alfa/bravo/EXCLAMATION_POINT', but returned: %q", spelledString) } @@ -305,14 +305,14 @@ func TestForceFailures(t *testing.T) { maxNum := 9223372036854775807 maxNumBigInt := big.NewInt(int64(maxNum) + 1) if maxNumBigInt.IsUint64() { - t.Errorf("Calling big.NewInt() with too large number expected to fail: %v", maxNumBigInt) + t.Fatalf("Calling big.NewInt() with too large number expected to fail: %v", maxNumBigInt) } }) t.Run("negative value for big.NewInt()", func(t *testing.T) { randNum, err := getRandNum(-20000) if err == nil { - t.Errorf("Calling getRandNum() with negative value is expected to fail, but returned value: %v", + t.Fatalf("Calling getRandNum() with negative value is expected to fail, but returned value: %v", randNum) } }) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dd33c59 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/wneessen/apg.go + +go 1.16 diff --git a/params.go b/params.go index 48b2ae0..5adc5b3 100644 --- a/params.go +++ b/params.go @@ -1,8 +1,7 @@ package main import ( - "fmt" - "os" + "log" ) // Parse the parameters and set the according config flags @@ -22,8 +21,7 @@ func parseParams() { config.useLowerCase == false && config.useNumber == false && config.useSpecial == false { - fmt.Printf("No password mode set. Cannot generate password from empty character set.") - os.Exit(1) + log.Fatalf("No password mode set. Cannot generate password from empty character set.") } // Set output mode @@ -90,8 +88,7 @@ func parseNewStyleParams() { config.useComplex = false break default: - fmt.Printf("Unknown password style parameter: %q\n", string(curParam)) - os.Exit(1) + log.Fatalf("Unknown password style parameter: %q\n", string(curParam)) } } }