diff --git a/README.md b/README.md index 6013caf..3dd4e0a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ found, try `go run github.com/flwyd/adif-multitool/adifmt help` To do something useful with ADIF Multitool, the syntax is ``` -adifmt command [options] files... +adifmt command [files...] [options] [files...] ``` For example, the `cat` command concatenates all input files and outputs ADIF @@ -60,10 +60,10 @@ adifmt cat log1.adi log2.adi > combined.adi prints all of the records in the two `logX.adi` files to the `combined.adi` file. -Flags control input and output options. For example, to print records with -a UNIX newline between fields, two newlines between records, use lower case for -all field names, and add user defined fields `gain_db` (range ±100) and -`radio_color` (values black, white, or gray): +Options (also known as flags) control input and output options. For example, +to print records with a UNIX newline between fields, two newlines between +records, use lower case for all field names, and add user defined fields +`gain_db` (range ±100) and `radio_color` (values black, white, or gray): ```sh adifmt cat --adi-field-separator=newline \ @@ -74,6 +74,10 @@ adifmt cat --adi-field-separator=newline \ log1.csv ``` +File names to process can come before or after the options list, but cannot be +intermixed. A `--` by itself ends option parsing, which allows working with a +log file whose name starts with `-` (hyphen/minus/dash). + Multiple input and output formats are supported (currently ADI and ADX per the ADIF spec, Cabrillo according to the WWROF spec, CSV and TSV with field names matching the ADIF list, and JSON with a similar format to ADX). @@ -844,10 +848,10 @@ Features I plan to add: * Option for `save` to append records to an existing ADIF file. * Count the total number of records or the number of distinct values of a field. (The total number of records can currently be counted with - `--output=tsv`, piping the output to `wc -l`, and subtracting 1 for the - header row.) This could match the format of the “Report” comment in the - test QSOs file produced with the ADIF spec. -* Support for Cabrillo 2.0 format. + `--output=tsv --tsv-omit-header` and piping the output to `wc -l`.) This + could match the format of the “Report” comment in the test QSOs file + produced with the ADIF spec. +* Support for Cabrillo 2.0 format if needed. See the [issues page](https://github.com/flwyd/adif-multitool/issues) for more ideas or to suggest your own. diff --git a/adifmt/main.go b/adifmt/main.go index ea650b6..f75dd3e 100644 --- a/adifmt/main.go +++ b/adifmt/main.go @@ -29,6 +29,7 @@ import ( "github.com/flwyd/adif-multitool/adif" "github.com/flwyd/adif-multitool/adif/spec" "github.com/flwyd/adif-multitool/cmd" + "golang.org/x/exp/slices" ) const ( @@ -104,8 +105,14 @@ func runMain(prepare func(l *adif.Logfile)) int { if c.Configure != nil { c.Configure(ctx, fs) } - fs.Parse(os.Args[2:]) - err := c.Run(ctx, fs.Args()) + // filenames can come before or after flags, but not interspersed + args := os.Args[2:] + firstflag := slices.IndexFunc(args, func(s string) bool { return strings.HasPrefix(s, "-") }) + nonflags := args[0:firstflag] + args = args[firstflag:] + fs.Parse(args) + nonflags = append(nonflags, fs.Args()...) + err := c.Run(ctx, nonflags) if err != nil { fmt.Fprintf(os.Stderr, "Error running %s: %v\n", name, err) return 1 diff --git a/adifmt/testdata/cat_flag_order.txtar b/adifmt/testdata/cat_flag_order.txtar new file mode 100644 index 0000000..58e1b00 --- /dev/null +++ b/adifmt/testdata/cat_flag_order.txtar @@ -0,0 +1,65 @@ +# Tests that filenames can come before or after flags (or both) but filenames +# can't come in the middle of flags. + +# File before flags +exec adifmt cat foo.tsv bar.tsv --output json --json-indent 2 +cmp stdout combined.json +! stderr . + +# File after flags +exec adifmt cat --output json --json-indent 2 foo.tsv bar.tsv +cmp stdout combined.json +! stderr . + +# One file before and one after +exec adifmt cat foo.tsv --output json --json-indent 2 bar.tsv +cmp stdout combined.json +! stderr . + +# First filename stops flag parsing, so if there are flags leftover you'll get +# a file-not-found error. +! exec adifmt cat --output json foo.tsv --json-indent 2 bar.tsv +! stdout . +stderr '--json-indent: no such file' + +# Double dash stops flag parsing +cp foo.tsv -with-hyphen.tsv +exec adifmt cat --output json --json-indent 2 -- -with-hyphen.tsv bar.tsv +cmp stdout combined.json +! stderr . + +-- foo.tsv -- +CALL MODE +K1A CW +W2B SSB +-- bar.tsv -- +CALL MODE +K3C FM +W4D RTTY +-- combined.json -- +{ + "HEADER": { + "ADIF_VER": "3.1.4", + "CREATED_TIMESTAMP": "23450607 080910", + "PROGRAMID": "adifmt", + "PROGRAMVERSION": "(devel)" + }, + "RECORDS": [ + { + "CALL": "K1A", + "MODE": "CW" + }, + { + "CALL": "W2B", + "MODE": "SSB" + }, + { + "CALL": "K3C", + "MODE": "FM" + }, + { + "CALL": "W4D", + "MODE": "RTTY" + } + ] +}