feat: implement GNU-style command line options with pflag

- Add pflag dependency for POSIX/GNU-style command line parsing
- Replace Go standard flag package with pflag for better UX
- Implement long options with double dashes (--config, --max-messages, --help)
- Add short option aliases with single dashes (-c, -m, -h)
- Update help message with proper formatting and application description
- Update all documentation to reflect new flag syntax
- Update test scripts to use new command line format

GNU-style options provide better usability:
- Long descriptive options with --flag-name format
- Short single-character aliases for common options
- Standard help flag behavior with --help/-h
- Compatible with shell completion and standard conventions

Command line interface now supports:
- --config/-c FILE: Path to configuration file
- --max-messages/-m N: Message processing limit per mailbox
- --help/-h: Show help message and exit

All existing functionality preserved with improved command line experience.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-08-02 15:17:04 +02:00
commit 031dd86b0d
8 changed files with 47 additions and 28 deletions

View file

@ -2,10 +2,11 @@ package config
import (
"encoding/json"
"flag"
"fmt"
"os"
"path/filepath"
"github.com/spf13/pflag"
)
type Config struct {
@ -87,23 +88,37 @@ type CommandLineArgs struct {
MaxMessages int
}
// ParseCommandLine parses command line arguments
// ParseCommandLine parses command line arguments using GNU-style options
func ParseCommandLine() *CommandLineArgs {
configFlag := flag.String("config", "", "Path to configuration file")
maxMessagesFlag := flag.Int("max-messages", 0, "Maximum number of messages to process per mailbox per run (0 = no limit)")
flag.Parse()
var args CommandLineArgs
return &CommandLineArgs{
ConfigPath: *configFlag,
MaxMessages: *maxMessagesFlag,
// Define long options with -- and short options with -
pflag.StringVarP(&args.ConfigPath, "config", "c", "", "Path to configuration file")
pflag.IntVarP(&args.MaxMessages, "max-messages", "m", 0, "Maximum number of messages to process per mailbox per run (0 = no limit)")
// Add help option
pflag.BoolP("help", "h", false, "Show help message")
pflag.Parse()
// Handle help flag
if help, _ := pflag.CommandLine.GetBool("help"); help {
fmt.Fprintf(os.Stderr, "mail2couch - Email backup utility for CouchDB\n\n")
fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS]\n\n", os.Args[0])
fmt.Fprintf(os.Stderr, "Options:\n")
pflag.PrintDefaults()
os.Exit(0)
}
return &args
}
// FindConfigFile searches for config.json in the following order:
// 1. Path specified by -config flag
// 1. Path specified by --config/-c flag
// 2. ./config.json (current directory)
// 3. ~/.config/mail2couch/config.json (user config directory)
// 4. ~/.mail2couch.json (user home directory)
// 3. ./config/config.json (config subdirectory)
// 4. ~/.config/mail2couch/config.json (user config directory)
// 5. ~/.mail2couch.json (user home directory)
func FindConfigFile(args *CommandLineArgs) (string, error) {
if args.ConfigPath != "" {
if _, err := os.Stat(args.ConfigPath); err == nil {

View file

@ -6,6 +6,7 @@ require (
github.com/emersion/go-imap/v2 v2.0.0-beta.5
github.com/emersion/go-message v0.18.1
github.com/go-kivik/kivik/v4 v4.4.0
github.com/spf13/pflag v1.0.7
)
require (

View file

@ -24,6 +24,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
gitlab.com/flimzy/testy v0.14.0 h1:2nZV4Wa1OSJb3rOKHh0GJqvvhtE03zT+sKnPCI0owfQ=
gitlab.com/flimzy/testy v0.14.0/go.mod h1:m3aGuwdXc+N3QgnH+2Ar2zf1yg0UxNdIaXKvC5SlfMk=