Skip to content

Commit

Permalink
Merge branch 'better-handling-boolean-flags' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
simulot committed Dec 27, 2023
2 parents 26d719a + cb534b5 commit 070d9c9
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 48 deletions.
10 changes: 3 additions & 7 deletions cmdduplicate/duplicate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (
"flag"
"path"
"sort"
"strconv"
"strings"
"time"

"github.com/simulot/immich-go/helpers/fshelper/myflag"
"github.com/simulot/immich-go/helpers/gen"
"github.com/simulot/immich-go/immich"
"github.com/simulot/immich-go/logger"
Expand Down Expand Up @@ -47,12 +47,8 @@ func NewDuplicateCmd(ctx context.Context, ic *immich.ImmichClient, logger *logge
assetsByBaseAndDate: map[duplicateKey][]*immich.Asset{},
}

cmd.BoolVar(&app.IgnoreTZErrors, "ignore-tz-errors", false, "Ignore timezone difference to check duplicates (default: FALSE).")
cmd.BoolFunc("yes", "When true, assume Yes to all actions", func(s string) error {
var err error
app.AssumeYes, err = strconv.ParseBool(s)
return err
})
cmd.BoolFunc("ignore-tz-errors", "Ignore timezone difference to check duplicates (default: FALSE).", myflag.BoolFlagFn(&app.IgnoreTZErrors, false))
cmd.BoolFunc("yes", "When true, assume Yes to all actions", myflag.BoolFlagFn(&app.AssumeYes, false))
cmd.Var(&app.DateRange, "date", "Process only documents having a capture date in that range.")
err := cmd.Parse(args)
return &app, err
Expand Down
7 changes: 4 additions & 3 deletions cmdmetadata/metadatacmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/simulot/immich-go/helpers/docker"
"github.com/simulot/immich-go/helpers/fshelper/myflag"
"github.com/simulot/immich-go/immich"
"github.com/simulot/immich-go/immich/metadata"
"github.com/simulot/immich-go/logger"
Expand All @@ -31,9 +32,9 @@ func NewMetadataCmd(ctx context.Context, ic *immich.ImmichClient, logger *logger
Log: logger,
}

cmd.BoolVar(&app.DryRun, "dry-run", true, "display actions, but don't touch the server assets")
cmd.BoolVar(&app.MissingDate, "missing-date", false, "select all assets where the date is missing")
cmd.BoolVar(&app.MissingDateDespiteName, "missing-date-with-name", false, "select all assets where the date is missing ut the name contains a the date")
cmd.BoolFunc("dry-run", "display actions, but don't touch the server assets", myflag.BoolFlagFn(&app.DryRun, false))
cmd.BoolFunc("missing-date", "select all assets where the date is missing", myflag.BoolFlagFn(&app.MissingDate, false))
cmd.BoolFunc("missing-date-with-name", "select all assets where the date is missing but the name contains a the date", myflag.BoolFlagFn(&app.MissingDateDespiteName, false))
cmd.StringVar(&app.DockerHost, "docker-host", "local", "Immich's docker host where to inject sidecar file as workaround for the issue #3888. 'local' for local connection, 'ssh://user:password@server' for remote host.")
err = cmd.Parse(args)
return &app, err
Expand Down
62 changes: 28 additions & 34 deletions cmdupload/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/simulot/immich-go/browser/files"
"github.com/simulot/immich-go/browser/gp"
"github.com/simulot/immich-go/helpers/fshelper"
"github.com/simulot/immich-go/helpers/fshelper/myflag"
"github.com/simulot/immich-go/helpers/gen"
"github.com/simulot/immich-go/helpers/stacking"
"github.com/simulot/immich-go/immich"
Expand Down Expand Up @@ -88,70 +89,63 @@ func NewUpCmd(ctx context.Context, ic iClient, log logger.Logger, args []string)
Journal: logger.NewJournal(log),
client: ic,
}
cmd.BoolVar(&app.DryRun,
cmd.BoolFunc(
"dry-run",
false,
"display actions but don't touch source or destination")
"display actions but don't touch source or destination",
myflag.BoolFlagFn(&app.DryRun, false))
cmd.Var(&app.DateRange,
"date",
"Date of capture range.")
cmd.StringVar(&app.ImportIntoAlbum,
"album",
"",
"All assets will be added to this album.")
cmd.BoolVar(&app.ForceSidecar,
cmd.BoolFunc(
"force-sidecar",
false,
"Upload the photo and a sidecar file with known information like date and GPS coordinates. With google-photos, information comes from the metadata files. (DEFAULT false)")
cmd.BoolVar(&app.CreateAlbumAfterFolder,
"Upload the photo and a sidecar file with known information like date and GPS coordinates. With google-photos, information comes from the metadata files. (DEFAULT false)",
myflag.BoolFlagFn(&app.ForceSidecar, false))
cmd.BoolFunc(
"create-album-folder",
false,
" folder import only: Create albums for assets based on the parent folder")

cmd.BoolVar(&app.GooglePhotos,
" folder import only: Create albums for assets based on the parent folder",
myflag.BoolFlagFn(&app.CreateAlbumAfterFolder, false))
cmd.BoolFunc(
"google-photos",
false,
"Import GooglePhotos takeout zip files")
cmd.BoolVar(&app.CreateAlbums,
"Import GooglePhotos takeout zip files",
myflag.BoolFlagFn(&app.GooglePhotos, false))
cmd.BoolFunc(
"create-albums",
true,
" google-photos only: Create albums like there were in the source")
" google-photos only: Create albums like there were in the source (default: TRUE)",
myflag.BoolFlagFn(&app.CreateAlbums, true))
cmd.StringVar(&app.PartnerAlbum,
"partner-album",
"",
" google-photos only: Assets from partner will be added to this album. (ImportIntoAlbum, must already exist)")
cmd.BoolVar(&app.KeepPartner,
cmd.BoolFunc(
"keep-partner",
true,
" google-photos only: Import also partner's items")
" google-photos only: Import also partner's items (default: TRUE)", myflag.BoolFlagFn(&app.KeepPartner, true))
cmd.StringVar(&app.ImportFromAlbum,
"from-album",
"",
" google-photos only: Import only from this album")

cmd.BoolVar(&app.KeepUntitled,
cmd.BoolFunc(
"keep-untitled-albums",
false,
" google-photos only: Keep Untitled albums and imports their contain")
" google-photos only: Keep Untitled albums and imports their contain (default: FALSE)", myflag.BoolFlagFn(&app.KeepUntitled, false))

cmd.BoolVar(&app.UseFolderAsAlbumName,
cmd.BoolFunc(
"use-album-folder-as-name",
false,
" google-photos only: Use folder name and ignore albums' title")
" google-photos only: Use folder name and ignore albums' title (default:FALSE)", myflag.BoolFlagFn(&app.UseFolderAsAlbumName, false))

cmd.BoolVar(&app.CreateStacks,
cmd.BoolFunc(
"create-stacks",
true,
"Stack jpg/raw or bursts (default TRUE)")
"Stack jpg/raw or bursts (default TRUE)", myflag.BoolFlagFn(&app.CreateStacks, true))

cmd.BoolVar(&app.StackJpgRaws,
cmd.BoolFunc(
"stack-jpg-raw",
true,
"Control the stacking of jpg/raw photos (default TRUE)")
cmd.BoolVar(&app.StackBurst,
"Control the stacking of jpg/raw photos (default TRUE)", myflag.BoolFlagFn(&app.StackJpgRaws, true))
cmd.BoolFunc(
"stack-burst",
true,
"Control the stacking bursts (default TRUE)")
"Control the stacking bursts (default TRUE)", myflag.BoolFlagFn(&app.StackBurst, true))

// cmd.BoolVar(&app.Delete, "delete", false, "Delete local assets after upload")

Expand Down
13 changes: 13 additions & 0 deletions docs/releases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Release notes

## Release next

### feat: better handling of boolean flags
Just mention the `-flag` to activate the functionality

Example:
`... upload -create-album-folder ...` is now sufficient to activate the create album based on folder option
create-albums

Example: to deactivate a flag that is on by default:
`... upload -create-albums=FALSE ...` deactivate the album creation from google photos


## Release 0.9.5

### fix: panic: runtime error: invalid memory address or nil pointer dereference at github.com/simulot/immich-go/cmdupload/upload.go:255
Expand Down
30 changes: 30 additions & 0 deletions helpers/fshelper/myflag/boolfn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package myflag

import (
"fmt"
"strconv"
"strings"
)

// BoolFlagFn returns a convenient function for handling boolean option on CLI to be used as parameter of the flag.BoolFn.
// It works has the flag.BoolVar but, the presence of the flag, without value, set the flag to True

func BoolFlagFn(b *bool, defaultValue bool) func(string) error {
*b = defaultValue
return func(v string) error {

switch strings.ToLower(v) {
case "":
*b = true
return nil
default:
var err error
*b, err = strconv.ParseBool(v)
if err != nil {
err = fmt.Errorf("can't parse the parameter value: %w", err)
}
return err
}
}

}
67 changes: 67 additions & 0 deletions helpers/fshelper/myflag/boolfn_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package myflag

import "testing"

func Test_BoolFn(t *testing.T) {
tc := []struct {
name string
defaultValue bool
want bool
wantErr bool
}{
{
name: "",
want: true,
defaultValue: true,
},
{
name: "",
want: true,
defaultValue: false,
},
{
name: "true",
want: true,
},
{
name: "false",
want: false,
},
{
name: "1",
want: true,
},
{
name: "T",
want: true,
},
{
name: "F",
want: false,
},
{
name: "0",
want: false,
},
{
name: "let's be affirmative",
want: false,
wantErr: true,
},
}
for _, c := range tc {
t.Run(c.name, func(t *testing.T) {
var b bool
fn := BoolFlagFn(&b, c.defaultValue)

err := fn(c.name)
if (err == nil && c.wantErr) || (err != nil && !c.wantErr) {
t.Errorf("fn(%q)=%v, expecting error: %v", c.name, err, c.wantErr)
return
}
if b != c.want {
t.Errorf("fn(%q) set b to %v, expecting: %v", c.name, b, c.want)
}
})
}
}
9 changes: 5 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/simulot/immich-go/cmdstack"
"github.com/simulot/immich-go/cmdtool"
"github.com/simulot/immich-go/cmdupload"
"github.com/simulot/immich-go/helpers/fshelper/myflag"
"github.com/simulot/immich-go/helpers/tzone"
"github.com/simulot/immich-go/immich"
"github.com/simulot/immich-go/logger"
Expand Down Expand Up @@ -88,13 +89,13 @@ func Run(ctx context.Context, log *logger.Log) (*logger.Log, error) {
flag.StringVar(&app.API, "api", "", "Immich api endpoint (http://container_ip:3301)")
flag.StringVar(&app.Key, "key", "", "API Key")
flag.StringVar(&app.DeviceUUID, "device-uuid", deviceID, "Set a device UUID")
flag.BoolVar(&app.NoLogColors, "no-colors-log", false, "Disable colors on logs")
flag.BoolFunc("no-colors-log", "Disable colors on logs", myflag.BoolFlagFn(&app.NoLogColors, false))
flag.StringVar(&app.LogLevel, "log-level", "ok", "Log level (Error|Warning|OK|Info), default OK")
flag.StringVar(&app.LogFile, "log-file", "", "Write log messages into the file")
flag.BoolVar(&app.ApiTrace, "api-trace", false, "enable api call traces")
flag.BoolVar(&app.Debug, "debug", false, "enable debug messages")
flag.BoolFunc("api-trace", "enable api call traces", myflag.BoolFlagFn(&app.ApiTrace, false))
flag.BoolFunc("debug", "enable debug messages", myflag.BoolFlagFn(&app.Debug, false))
flag.StringVar(&app.TimeZone, "time-zone", "", "Override the system time zone")
flag.BoolVar(&app.SkipSSL, "skip-verify-ssl", false, "Skip SSL verification")
flag.BoolFunc("skip-verify-ssl", "Skip SSL verification", myflag.BoolFlagFn(&app.SkipSSL, false))
flag.Parse()

app.Server = strings.TrimSuffix(app.Server, "/")
Expand Down

0 comments on commit 070d9c9

Please sign in to comment.