From f78726ba773dc8ce55bf55e39f2fc2f9766882e7 Mon Sep 17 00:00:00 2001 From: Andrei Burdulescu Date: Sat, 9 Dec 2023 12:33:12 +0200 Subject: [PATCH] better app usage --- internal/app/app.go | 40 +++++---- internal/app/app_test.go | 2 +- main.go | 169 +++++++++++++++++++++++---------------- 3 files changed, 125 insertions(+), 86 deletions(-) diff --git a/internal/app/app.go b/internal/app/app.go index 19e6abb..a8c4d70 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -5,14 +5,13 @@ import ( "fmt" "os" "runtime/debug" - "sort" "strings" ) -type Command struct { - Run func(...string) error - Name string - Usage string +type App struct { + categories []category + + printVersion bool } type category struct { @@ -20,10 +19,10 @@ type category struct { commands []Command } -type App struct { - categories []category - - printVersion bool +type Command struct { + Run func(...string) error + Name string + Usage string } func printAppVersion() { @@ -89,7 +88,7 @@ func (a *App) Run(args ...string) error { return fmt.Errorf("unknown command '%s'", name) } -func (a *App) Add(categoryName string, c Command) { +func (a *App) Add(categoryName string, cmds ...Command) { i := -1 for ii, v := range a.categories { if v.name == categoryName { @@ -100,11 +99,22 @@ func (a *App) Add(categoryName string, c Command) { a.categories = append(a.categories, category{name: categoryName}) i = len(a.categories) - 1 } - c.Name = categoryName + "-" + c.Name - a.categories[i].commands = append(a.categories[i].commands, c) - sort.Slice(a.categories, func(i, j int) bool { - return a.categories[i].name < a.categories[j].name - }) + cat := &a.categories[i] + for _, cmd := range cmds { + if err := cat.hasCmd(cmd.Name); err != nil { + panic(err.Error()) + } + } + cat.commands = append(cat.commands, cmds...) +} + +func (c category) hasCmd(name string) error { + for _, cmd := range c.commands { + if cmd.Name == name { + return fmt.Errorf("category '%s' already has a command name '%s'", c.name, name) + } + } + return nil } func (a App) maxCommandName(category string) int { diff --git a/internal/app/app_test.go b/internal/app/app_test.go index 6355bee..5519278 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -35,7 +35,7 @@ func TestApp(t *testing.T) { t.Fatal("expected an error") } - if err := app.Run("foo-bar"); err != nil { + if err := app.Run("bar"); err != nil { t.Fatal(err) } diff --git a/main.go b/main.go index 7f59ff3..03b31fd 100644 --- a/main.go +++ b/main.go @@ -14,79 +14,108 @@ import ( func main() { var a app.App - a.Add("aes", app.Command{ - Name: "keygen", - Usage: "Generate AES key", - Run: aes.KeyGen, - }) - a.Add("aes", app.Command{ - Name: "ecb", - Usage: "Encrypt/Decrypt using AES-ECB", - Run: aes.EcbCmd, - }) - a.Add("aes", app.Command{ - Name: "cbc", - Usage: "Encrypt/Decrypt using AES-CBC", - Run: aes.CbcCmd, - }) - a.Add("aes", app.Command{ - Name: "gcm", - Usage: "Encrypt/Decrypt using AES-GCM", - Run: aes.Gcm, - }) - a.Add("aes", app.Command{ - Name: "keywrap", - Usage: "Wrap/Unwrap using AES-KEYWRAP", - Run: aes.KeyWrapCmd, - }) + a.Add( + "Key Generation", + app.Command{ + Name: "gen-aes", + Usage: "Generate AES key", + Run: aes.KeyGen, + }, + app.Command{ + Name: "gen-rsa", + Usage: "Generate RSA key", + Run: rsa.KeyGenCmd, + }, + ) - a.Add("rsa", app.Command{ - Name: "keygen", - Usage: "Generate RSA key", - Run: rsa.KeyGenCmd, - }) - a.Add("rsa", app.Command{ - Name: "pub-from-priv", - Usage: "Extract RSA public key from private key", - Run: rsa.PubFromPrivCmd, - }) - a.Add("rsa", app.Command{ - Name: "kem", - Usage: "Encapsulate/Decapsulate using RSA-KEM", - Run: rsa.KemCmd, - }) - a.Add("rsa", app.Command{ - Name: "raw-der", - Usage: "Convert RSA key from raw values(n, e, d, p, q) to PKCS#1 ASN.1 DER", - Run: rsa.RawDerCmd, - }) - a.Add("rsa", app.Command{ - Name: "der-raw", - Usage: "Convert RSA key from PKCS#1 ASN.1 DER to raw values(n, e, d, p, q)", - Run: rsa.DerRawCmd, - }) - a.Add("rsa", app.Command{ - Name: "pem-der", - Usage: "Convert RSA key from PEM to PKCS#1 ASN.1 DER", - Run: rsa.PemDerCmd, - }) - a.Add("rsa", app.Command{ - Name: "der-pem", - Usage: "Convert RSA key from PKCS#1 ASN.1 DER to PEM", - Run: rsa.DerPemCmd, - }) + a.Add( + "Key Encoding", + app.Command{ + Name: "rsa-pub-from-priv", + Usage: "Extract RSA public key from private key", + Run: rsa.PubFromPrivCmd, + }, + app.Command{ + Name: "rsa-raw-der", + Usage: "Convert RSA key from raw values(n, e, d, p, q) to PKCS#1 ASN.1 DER", + Run: rsa.RawDerCmd, + }, app.Command{ + Name: "rsa-der-raw", + Usage: "Convert RSA key from PKCS#1 ASN.1 DER to raw values(n, e, d, p, q)", + Run: rsa.DerRawCmd, + }, app.Command{ + Name: "rsa-pem-der", + Usage: "Convert RSA key from PEM to PKCS#1 ASN.1 DER", + Run: rsa.PemDerCmd, + }, app.Command{ + Name: "rsa-der-pem", + Usage: "Convert RSA key from PKCS#1 ASN.1 DER to PEM", + Run: rsa.DerPemCmd, + }, + ) - a.Add("kdf", app.Command{ - Name: "pbkdf2", - Usage: "Derive key using PBKDF2", - Run: kdf.Pbkdf2Cmd, - }) + a.Add( + "Block Cipher", + app.Command{ + Name: "aes-ecb", + Usage: "Encrypt/Decrypt using AES-ECB", + Run: aes.EcbCmd, + }, + ) - a.Add("hash", app.Command{ - Name: "sha", - Usage: "Generate cryptographic hash using SHA", - Run: hash.ShaCmd, - }) + a.Add( + "Stream Cipher", + app.Command{ + Name: "aes-cbc", + Usage: "Encrypt/Decrypt using AES-CBC", + Run: aes.CbcCmd, + }, + ) + + a.Add( + "AEAD", + app.Command{ + Name: "aes-gcm", + Usage: "Encrypt/Decrypt using AES-GCM", + Run: aes.Gcm, + }, + ) + + a.Add( + "Key Wrap", + app.Command{ + Name: "aes-keywrap", + Usage: "Wrap/Unwrap using AES-KEYWRAP", + Run: aes.KeyWrapCmd, + }, + ) + + a.Add( + "Key Derivation", + app.Command{ + Name: "pbkdf2", + Usage: "Derive key using PBKDF2", + Run: kdf.Pbkdf2Cmd, + }, + ) + + a.Add( + "Hashing", + app.Command{ + Name: "sha", + Usage: "Generate cryptographic hash using SHA", + Run: hash.ShaCmd, + }, + ) + + a.Add( + "Key Encapsulation Mechanism", + app.Command{ + Name: "rsa-kem", + Usage: "Encapsulate/Decapsulate using RSA-KEM", + Run: rsa.KemCmd, + }, + ) if err := a.Run(os.Args[1:]...); err != nil { die("%v", err)