CLI: Upgrade github.com/urfave/cli from v1 to v2 #3168

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer
2024-12-05 17:15:59 +01:00
parent 3b61aba85d
commit 9eef183323
103 changed files with 1961 additions and 1642 deletions

View File

@@ -25,7 +25,7 @@ package main
import (
"os"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/commands"
"github.com/photoprism/photoprism/internal/config"

3
go.mod
View File

@@ -40,7 +40,6 @@ require (
github.com/tensorflow/tensorflow v1.15.2
github.com/tidwall/gjson v1.18.0
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6
github.com/urfave/cli v1.22.16
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/crypto v0.30.0
golang.org/x/net v0.32.0
@@ -85,6 +84,7 @@ require (
github.com/robfig/cron/v3 v3.0.1
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/urfave/cli/v2 v2.27.5
github.com/zitadel/oidc/v3 v3.33.1
)
@@ -137,6 +137,7 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/zitadel/logging v0.6.1 // indirect
github.com/zitadel/schema v1.3.0 // indirect
go.opentelemetry.io/otel v1.29.0 // indirect

10
go.sum
View File

@@ -18,7 +18,6 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
@@ -371,7 +370,6 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -379,8 +377,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/sunfish-shogi/bufseekio v0.0.0-20210207115823-a4185644b365/go.mod h1:dEzdXgvImkQ3WLI+0KQpmEx8T/C/ma9KeS3AfmU899I=
@@ -409,8 +405,10 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6 h1:TtyC78WMafNW8QFfv3TeP3yWNDG+uxNkk9vOrnDu6JA=
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6/go.mod h1:h8272+G2omSmi30fBXiZDMkmHuOgonplfKIKjQWzlfs=
github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ=
github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zitadel/logging v0.6.1 h1:Vyzk1rl9Kq9RCevcpX6ujUaTYFX43aa4LkvV1TvUk+Y=
github.com/zitadel/logging v0.6.1/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow=

View File

@@ -1,7 +1,7 @@
package commands
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
)
// AuthCommands registers the API authentication subcommands.
@@ -9,17 +9,17 @@ var AuthCommands = cli.Command{
Name: "auth",
Aliases: []string{"sess"},
Usage: "API authentication subcommands",
Subcommands: []cli.Command{
AuthListCommand,
AuthAddCommand,
AuthShowCommand,
AuthRemoveCommand,
AuthResetCommand,
Subcommands: []*cli.Command{
&AuthListCommand,
&AuthAddCommand,
&AuthShowCommand,
&AuthRemoveCommand,
&AuthResetCommand,
},
}
// tokensFlag represents a CLI flag to include tokens in a report.
var tokensFlag = cli.BoolFlag{
var tokensFlag = &cli.BoolFlag{
Name: "tokens",
Usage: "show preview and download tokens",
}

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
@@ -17,18 +17,21 @@ import (
// AuthAddFlags specifies the "photoprism auth add" command flags.
var AuthAddFlags = []cli.Flag{
cli.StringFlag{
Name: "name, n",
Usage: "`CLIENT` name to help identify the application",
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
Usage: "`CLIENT` name to help identify the application",
},
cli.StringFlag{
Name: "scope, s",
Usage: "authorization `SCOPES` e.g. \"metrics\" or \"photos albums\" (\"*\" to allow all)",
&cli.StringFlag{
Name: "scope",
Aliases: []string{"s"},
Usage: "authorization `SCOPES` e.g. \"metrics\" or \"photos albums\" (\"*\" to allow all)",
},
cli.Int64Flag{
Name: "expires, e",
Usage: "authentication `LIFETIME` in seconds, after which access expires (-1 to disable the limit)",
Value: unix.Year,
&cli.Int64Flag{
Name: "expires",
Aliases: []string{"e"},
Usage: "authentication `LIFETIME` in seconds, after which access expires (-1 to disable the limit)",
Value: unix.Year,
},
}

View File

@@ -12,11 +12,12 @@ func TestAuthAddCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"add", "--scope=metrics", "--expires=5000", "--name=alice", "alice"})
args := []string{"add", "--scope=metrics", "--expires=5000", "--name=alice", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthAddCommand.Run(ctx)
err = AuthAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -30,11 +31,12 @@ func TestAuthAddCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"add", "--scope=test", "--expires=5000", "--name=xyz"})
args := []string{"add", "--scope=test", "--expires=5000", "--name=xyz"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthAddCommand.Run(ctx)
err = AuthAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -48,11 +50,12 @@ func TestAuthAddCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"add", "--scope=test", "--expires=5000", "xxxxx"})
args := []string{"add", "--scope=test", "--expires=5000", "xxxxx"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthAddCommand.Run(ctx)
err = AuthAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -65,11 +68,12 @@ func TestAuthAddCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"add", "--scope=test", "--expires=5000", "alice"})
args := []string{"add", "--scope=test", "--expires=5000", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthAddCommand.Run(ctx)
err = AuthAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -81,11 +85,12 @@ func TestAuthAddCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"add", "--name=test", "--expires=5000", "alice"})
args := []string{"add", "--name=test", "--expires=5000", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthAddCommand.Run(ctx)
err = AuthAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity/query"
@@ -32,7 +32,7 @@ func authListAction(ctx *cli.Context) error {
}
// Fetch sessions from database.
results, err := query.Sessions(ctx.Int("n"), 0, "", ctx.Args().First())
results, err := query.Sessions(ctx.Int("count"), 0, "", ctx.Args().First())
if err != nil {
return err

View File

@@ -1,6 +1,8 @@
package commands
import (
"fmt"
"runtime/debug"
"testing"
"github.com/stretchr/testify/assert"
@@ -13,11 +15,12 @@ func TestAuthListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls"})
args := []string{"ls"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthListCommand.Run(ctx)
err = AuthListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -31,11 +34,12 @@ func TestAuthListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "alice"})
args := []string{"ls", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthListCommand.Run(ctx)
err = AuthListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -51,11 +55,12 @@ func TestAuthListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--csv", "alice"})
args := []string{"ls", "--csv", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthListCommand.Run(ctx)
err = AuthListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -70,11 +75,12 @@ func TestAuthListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--tokens", "alice"})
args := []string{"ls", "--tokens", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthListCommand.Run(ctx)
err = AuthListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -90,11 +96,12 @@ func TestAuthListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--tokens", "notexisting"})
args := []string{"ls", "--tokens", "notexisting"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthListCommand.Run(ctx)
err = AuthListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -105,12 +112,20 @@ func TestAuthListCommand(t *testing.T) {
t.Run("Error", func(t *testing.T) {
var err error
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("error: %s \nstack: %s", r, debug.Stack())
assert.Error(t, err)
}
}()
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--xyz", "alice"})
args := []string{"ls", "--xyz", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthListCommand.Run(ctx)
err = AuthListCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -5,7 +5,7 @@ import (
"fmt"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity/query"

View File

@@ -11,10 +11,11 @@ func TestAuthRemoveCommand(t *testing.T) {
t.Run("NotConfirmed", func(t *testing.T) {
var err error
ctx0 := NewTestContext([]string{"show", "sessgh6123yt"})
args0 := []string{"show", "sessgh6123yt"}
ctx0 := NewTestContext(args0)
output0 := capture.Output(func() {
err = AuthShowCommand.Run(ctx0)
err = AuthShowCommand.Run(ctx0, args0...)
})
//t.Logf(output0)
@@ -22,11 +23,12 @@ func TestAuthRemoveCommand(t *testing.T) {
assert.NotEmpty(t, output0)
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"rm", "sessgh6123yt"})
args := []string{"rm", "sessgh6123yt"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthRemoveCommand.Run(ctx)
err = AuthRemoveCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -35,7 +37,7 @@ func TestAuthRemoveCommand(t *testing.T) {
assert.Empty(t, output)
output1 := capture.Output(func() {
err = AuthShowCommand.Run(ctx0)
err = AuthShowCommand.Run(ctx0, args0...)
})
//t.Logf(output1)

View File

@@ -6,7 +6,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
@@ -20,13 +20,15 @@ var AuthResetCommand = cli.Command{
Usage: "Resets the authentication of all users and clients",
Description: AuthResetDescription,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "trace, t",
Usage: "show trace logs for debugging",
&cli.BoolFlag{
Name: "trace",
Aliases: []string{"t"},
Usage: "show trace logs for debugging",
},
cli.BoolFlag{
Name: "yes, y",
Usage: "assume \"yes\" and run non-interactively",
&cli.BoolFlag{
Name: "yes",
Aliases: []string{"y"},
Usage: "assume \"yes\" and run non-interactively",
},
},
Action: authResetAction,

View File

@@ -12,11 +12,12 @@ func TestAuthResetCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx0 := NewTestContext([]string{"ls"})
args0 := []string{"ls"}
ctx0 := NewTestContext(args0)
// Run command with test context.
output0 := capture.Output(func() {
err = AuthListCommand.Run(ctx0)
err = AuthListCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.
@@ -26,11 +27,12 @@ func TestAuthResetCommand(t *testing.T) {
assert.Contains(t, output0, "visitor")
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"reset"})
args := []string{"reset"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthResetCommand.Run(ctx)
err = AuthResetCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -40,7 +42,7 @@ func TestAuthResetCommand(t *testing.T) {
// Run command with test context.
output1 := capture.Output(func() {
err = AuthListCommand.Run(ctx0)
err = AuthListCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.

View File

@@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity/query"

View File

@@ -12,15 +12,16 @@ func TestAuthShowCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"show", "sess34q3hael"})
args := []string{"show", "sess34q3hael"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthShowCommand.Run(ctx)
err = AuthShowCommand.Run(ctx, args...)
})
// Check command output for plausibility.
// t.Logf(output)
t.Logf(output)
assert.NoError(t, err)
assert.Contains(t, output, "alice")
assert.Contains(t, output, "access_token")
@@ -30,11 +31,12 @@ func TestAuthShowCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"show", "sess34qxxxxx"})
args := []string{"show", "sess34qxxxxx"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthShowCommand.Run(ctx)
err = AuthShowCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -13,11 +13,12 @@ func TestAuthCommands(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"auth", "ls"})
args := []string{"auth", "ls"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthCommands.Run(ctx)
err = AuthCommands.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -31,11 +32,12 @@ func TestAuthCommands(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"auth", "ls", "alice"})
args := []string{"auth", "ls", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = AuthCommands.Run(ctx)
err = AuthCommands.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -7,7 +7,7 @@ import (
"time"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism/backup"
@@ -30,30 +30,35 @@ var BackupCommand = cli.Command{
}
var backupFlags = []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "replace the index database backup file, if it exists",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "replace the index database backup file, if it exists",
},
cli.BoolFlag{
Name: "albums, a",
Usage: "create YAML files to back up album metadata (in the standard backup path if no other path is specified)",
&cli.BoolFlag{
Name: "albums",
Aliases: []string{"a"},
Usage: "create YAML files to back up album metadata (in the standard backup path if no other path is specified)",
},
cli.StringFlag{
&cli.StringFlag{
Name: "albums-path",
Usage: "custom album backup `PATH`",
},
cli.BoolFlag{
Name: "database, index, i",
Usage: "create index database backup (in the backup path with the date as filename if no filename is passed, or sent to stdout if - is passed as filename)",
&cli.BoolFlag{
Name: "database",
Aliases: []string{"index", "i"},
Usage: "create index database backup (in the backup path with the date as filename if no filename is passed, or sent to stdout if - is passed as filename)",
},
cli.StringFlag{
Name: "database-path, index-path",
Usage: "custom database backup `PATH`",
&cli.StringFlag{
Name: "database-path",
Aliases: []string{"index-path"},
Usage: "custom database backup `PATH`",
},
cli.IntFlag{
Name: "retain, r",
Usage: "`NUMBER` of database backups to keep (-1 to keep all)",
Value: config.DefaultBackupRetain,
&cli.IntFlag{
Name: "retain",
Aliases: []string{"r"},
Usage: "`NUMBER` of database backups to keep (-1 to keep all)",
Value: config.DefaultBackupRetain,
},
}

View File

@@ -5,7 +5,7 @@ import (
"time"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/photoprism"
"github.com/photoprism/photoprism/internal/photoprism/get"
@@ -20,7 +20,7 @@ var CleanUpCommand = cli.Command{
}
var cleanUpFlags = []cli.Flag{
cli.BoolFlag{
&cli.BoolFlag{
Name: "dry",
Usage: "dry run, don't actually remove anything",
},

View File

@@ -1,7 +1,7 @@
package commands
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/auth/acl"
"github.com/photoprism/photoprism/pkg/authn"
@@ -30,59 +30,66 @@ var ClientsCommands = cli.Command{
Name: "clients",
Aliases: []string{"client"},
Usage: "Client credentials subcommands",
Subcommands: []cli.Command{
ClientsListCommand,
ClientsAddCommand,
ClientsShowCommand,
ClientsModCommand,
ClientsRemoveCommand,
ClientsResetCommand,
Subcommands: []*cli.Command{
&ClientsListCommand,
&ClientsAddCommand,
&ClientsShowCommand,
&ClientsModCommand,
&ClientsRemoveCommand,
&ClientsResetCommand,
},
}
// ClientAddFlags specifies the "photoprism client add" command flags.
var ClientAddFlags = []cli.Flag{
cli.StringFlag{
&cli.StringFlag{
Name: "id",
Usage: ClientIdUsage,
Hidden: true,
},
cli.StringFlag{
Name: "name, n",
Usage: ClientNameUsage,
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
Usage: ClientNameUsage,
},
cli.StringFlag{
Name: "role, r",
Usage: ClientRoleUsage,
Value: acl.RoleClient.String(),
&cli.StringFlag{
Name: "role",
Aliases: []string{"r"},
Usage: ClientRoleUsage,
Value: acl.RoleClient.String(),
},
cli.StringFlag{
Name: "scope, s",
Usage: ClientAuthScope,
&cli.StringFlag{
Name: "scope",
Aliases: []string{"s"},
Usage: ClientAuthScope,
},
cli.StringFlag{
Name: "provider, p",
Usage: ClientAuthProvider,
Value: authn.ProviderClient.String(),
Hidden: true,
&cli.StringFlag{
Name: "provider",
Aliases: []string{"p"},
Usage: ClientAuthProvider,
Value: authn.ProviderClient.String(),
Hidden: true,
},
cli.StringFlag{
Name: "method, m",
Usage: ClientAuthMethod,
Value: authn.MethodOAuth2.String(),
Hidden: true,
&cli.StringFlag{
Name: "method",
Aliases: []string{"m"},
Usage: ClientAuthMethod,
Value: authn.MethodOAuth2.String(),
Hidden: true,
},
cli.Int64Flag{
Name: "expires, e",
Usage: ClientAuthExpires,
Value: unix.Day,
&cli.Int64Flag{
Name: "expires",
Aliases: []string{"e"},
Usage: ClientAuthExpires,
Value: unix.Day,
},
cli.Int64Flag{
Name: "tokens, t",
Usage: ClientAuthTokens,
Value: 10,
&cli.Int64Flag{
Name: "tokens",
Aliases: []string{"t"},
Usage: ClientAuthTokens,
Value: 10,
},
cli.StringFlag{
&cli.StringFlag{
Name: "secret",
Usage: ClientSecretUsage,
Hidden: true,
@@ -91,55 +98,62 @@ var ClientAddFlags = []cli.Flag{
// ClientModFlags specifies the "photoprism client mod" command flags.
var ClientModFlags = []cli.Flag{
cli.StringFlag{
Name: "name, n",
Usage: ClientNameUsage,
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
Usage: ClientNameUsage,
},
cli.StringFlag{
Name: "role, r",
Usage: ClientRoleUsage,
Value: acl.RoleClient.String(),
&cli.StringFlag{
Name: "role",
Aliases: []string{"r"},
Usage: ClientRoleUsage,
Value: acl.RoleClient.String(),
},
cli.StringFlag{
Name: "scope, s",
Usage: ClientAuthScope,
&cli.StringFlag{
Name: "scope",
Aliases: []string{"s"},
Usage: ClientAuthScope,
},
cli.StringFlag{
Name: "provider, p",
Usage: ClientAuthProvider,
Value: authn.ProviderClient.String(),
Hidden: true,
&cli.StringFlag{
Name: "provider",
Aliases: []string{"p"},
Usage: ClientAuthProvider,
Value: authn.ProviderClient.String(),
Hidden: true,
},
cli.StringFlag{
Name: "method, m",
Usage: ClientAuthMethod,
Value: authn.MethodOAuth2.String(),
Hidden: true,
&cli.StringFlag{
Name: "method",
Aliases: []string{"m"},
Usage: ClientAuthMethod,
Value: authn.MethodOAuth2.String(),
Hidden: true,
},
cli.Int64Flag{
Name: "expires, e",
Usage: ClientAuthExpires,
Value: unix.Day,
&cli.Int64Flag{
Name: "expires",
Aliases: []string{"e"},
Usage: ClientAuthExpires,
Value: unix.Day,
},
cli.Int64Flag{
Name: "tokens, t",
Usage: ClientAuthTokens,
Value: 10,
&cli.Int64Flag{
Name: "tokens",
Aliases: []string{"t"},
Usage: ClientAuthTokens,
Value: 10,
},
cli.StringFlag{
&cli.StringFlag{
Name: "secret",
Usage: ClientSecretUsage,
Hidden: true,
},
cli.BoolFlag{
&cli.BoolFlag{
Name: "regenerate",
Usage: ClientRegenerateSecret,
},
cli.BoolFlag{
&cli.BoolFlag{
Name: "enable",
Usage: ClientEnable,
},
cli.BoolFlag{
&cli.BoolFlag{
Name: "disable",
Usage: ClientDisable,
},

View File

@@ -5,7 +5,7 @@ import (
"github.com/dustin/go-humanize/english"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"

View File

@@ -11,11 +11,12 @@ func TestClientsAddCommand(t *testing.T) {
t.Run("AddClient", func(t *testing.T) {
var err error
ctx := NewTestContext([]string{"add", "--name=Clara Client", "--scope=photos albums", "--expires=5000", "--tokens=2", "clara"})
args := []string{"add", "--name=Clara Client", "--scope=photos albums", "--expires=5000", "--tokens=2", "clara"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsAddCommand.Run(ctx)
err = ClientsAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity/query"
@@ -26,7 +26,7 @@ func clientsListAction(ctx *cli.Context) error {
cols := []string{"Client ID", "Name", "Authentication Method", "User", "Role", "Scope", "Enabled", "Access Token Lifetime", "Created At"}
// Fetch clients from database.
clients, err := query.Clients(ctx.Int("n"), 0, "", ctx.Args().First())
clients, err := query.Clients(ctx.Int("count"), 0, "", ctx.Args().First())
if err != nil {
return err

View File

@@ -1,6 +1,8 @@
package commands
import (
"fmt"
"runtime/debug"
"testing"
"github.com/stretchr/testify/assert"
@@ -13,11 +15,12 @@ func TestClientsListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls"})
args := []string{"ls"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsListCommand.Run(ctx)
err = ClientsListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -32,11 +35,12 @@ func TestClientsListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "monitoring"})
args := []string{"ls", "monitoring"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsListCommand.Run(ctx)
err = ClientsListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -52,11 +56,12 @@ func TestClientsListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--csv", "monitoring"})
args := []string{"ls", "--csv", "monitoring"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsListCommand.Run(ctx)
err = ClientsListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -72,11 +77,12 @@ func TestClientsListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "notexisting"})
args := []string{"ls", "notexisting"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsListCommand.Run(ctx)
err = ClientsListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -87,12 +93,20 @@ func TestClientsListCommand(t *testing.T) {
t.Run("Error", func(t *testing.T) {
var err error
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("error: %s \nstack: %s", r, debug.Stack())
assert.Error(t, err)
}
}()
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--xyz", "monitoring"})
args := []string{"ls", "--xyz", "monitoring"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsListCommand.Run(ctx)
err = ClientsListCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"

View File

@@ -12,11 +12,12 @@ func TestClientsModCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"mod", "--name=New", "--scope=test", "cs5cpu17n6gjxxxx"})
args := []string{"mod", "--name=New", "--scope=test", "cs5cpu17n6gjxxxx"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsModCommand.Run(ctx)
err = ClientsModCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -26,11 +27,12 @@ func TestClientsModCommand(t *testing.T) {
t.Run("DisableEnableAuth", func(t *testing.T) {
var err error
ctx0 := NewTestContext([]string{"show", "cs7pvt5h8rw9aaqj"})
args0 := []string{"show", "cs7pvt5h8rw9aaqj"}
ctx0 := NewTestContext(args0)
// Run command with test context.
output0 := capture.Output(func() {
err = ClientsShowCommand.Run(ctx0)
err = ClientsShowCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.
@@ -40,11 +42,12 @@ func TestClientsModCommand(t *testing.T) {
assert.Contains(t, output0, "oauth2")
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"mod", "--disable", "cs7pvt5h8rw9aaqj"})
args := []string{"mod", "--disable", "cs7pvt5h8rw9aaqj"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsModCommand.Run(ctx)
err = ClientsModCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -54,7 +57,7 @@ func TestClientsModCommand(t *testing.T) {
// Run command with test context.
output1 := capture.Output(func() {
err = ClientsShowCommand.Run(ctx0)
err = ClientsShowCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.
@@ -63,11 +66,12 @@ func TestClientsModCommand(t *testing.T) {
assert.Contains(t, output1, "AuthEnabled | false")
// Create test context with flags and arguments.
ctx1 := NewTestContext([]string{"mod", "--enable", "cs7pvt5h8rw9aaqj"})
args1 := []string{"mod", "--enable", "cs7pvt5h8rw9aaqj"}
ctx1 := NewTestContext(args1)
// Run command with test context.
output2 := capture.Output(func() {
err = ClientsModCommand.Run(ctx1)
err = ClientsModCommand.Run(ctx1, args1...)
})
// Check command output for plausibility.
@@ -76,7 +80,7 @@ func TestClientsModCommand(t *testing.T) {
// Run command with test context.
output3 := capture.Output(func() {
err = ClientsShowCommand.Run(ctx0)
err = ClientsShowCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.
@@ -88,11 +92,12 @@ func TestClientsModCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"mod", "--regenerate", "cs7pvt5h8rw9aaqj"})
args := []string{"mod", "--regenerate", "cs7pvt5h8rw9aaqj"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsModCommand.Run(ctx)
err = ClientsModCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
@@ -17,9 +17,10 @@ var ClientsRemoveCommand = cli.Command{
Usage: "Deletes the specified client application",
ArgsUsage: "[client id]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "don't ask for confirmation",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "don't ask for confirmation",
},
},
Action: clientsRemoveAction,

View File

@@ -11,10 +11,11 @@ func TestCientsRemoveCommand(t *testing.T) {
t.Run("NoConfirmationProvided", func(t *testing.T) {
var err error
ctx0 := NewTestContext([]string{"show", "cs7pvt5h8rw9aaqj"})
args0 := []string{"show", "cs7pvt5h8rw9aaqj"}
ctx0 := NewTestContext(args0)
output0 := capture.Output(func() {
err = ClientsShowCommand.Run(ctx0)
err = ClientsShowCommand.Run(ctx0, args0...)
})
//t.Logf(output0)
@@ -23,11 +24,12 @@ func TestCientsRemoveCommand(t *testing.T) {
assert.Contains(t, output0, "client")
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"rm", "cs7pvt5h8rw9aaqj"})
args := []string{"rm", "cs7pvt5h8rw9aaqj"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsRemoveCommand.Run(ctx)
err = ClientsRemoveCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -35,10 +37,11 @@ func TestCientsRemoveCommand(t *testing.T) {
assert.NoError(t, err)
assert.Empty(t, output)
ctx2 := NewTestContext([]string{"show", "cs7pvt5h8rw9aaqj"})
args2 := []string{"show", "cs7pvt5h8rw9aaqj"}
ctx2 := NewTestContext(args2)
output2 := capture.Output(func() {
err = ClientsShowCommand.Run(ctx2)
err = ClientsShowCommand.Run(ctx2, args2...)
})
//t.Logf(output2)
@@ -49,10 +52,11 @@ func TestCientsRemoveCommand(t *testing.T) {
t.Run("RemoveClient", func(t *testing.T) {
var err error
ctx0 := NewTestContext([]string{"show", "cs7pvt5h8rw9aaqj"})
args0 := []string{"show", "cs7pvt5h8rw9aaqj"}
ctx0 := NewTestContext(args0)
output0 := capture.Output(func() {
err = ClientsShowCommand.Run(ctx0)
err = ClientsShowCommand.Run(ctx0, args0...)
})
//t.Logf(output0)
@@ -61,21 +65,23 @@ func TestCientsRemoveCommand(t *testing.T) {
assert.Contains(t, output0, "client")
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"rm", "--force", "cs7pvt5h8rw9aaqj"})
args := []string{"rm", "--force", "cs7pvt5h8rw9aaqj"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsRemoveCommand.Run(ctx)
err = ClientsRemoveCommand.Run(ctx, args...)
})
// Check command output for plausibility.
assert.NoError(t, err)
assert.Empty(t, output)
ctx2 := NewTestContext([]string{"show", "cs7pvt5h8rw9aaqj"})
args2 := []string{"show", "cs7pvt5h8rw9aaqj"}
ctx2 := NewTestContext(args2)
output2 := capture.Output(func() {
err = ClientsShowCommand.Run(ctx2)
err = ClientsShowCommand.Run(ctx2, args2...)
})
assert.Error(t, err)
@@ -85,11 +91,12 @@ func TestCientsRemoveCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"rm", "--force", "cs7pvt5h8rw9a000"})
args := []string{"rm", "--force", "cs7pvt5h8rw9a000"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsRemoveCommand.Run(ctx)
err = ClientsRemoveCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -5,7 +5,7 @@ import (
"github.com/manifoldco/promptui"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
@@ -16,13 +16,15 @@ var ClientsResetCommand = cli.Command{
Name: "reset",
Usage: "Removes all registered client applications",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "trace, t",
Usage: "show trace logs for debugging",
&cli.BoolFlag{
Name: "trace",
Aliases: []string{"t"},
Usage: "show trace logs for debugging",
},
cli.BoolFlag{
Name: "yes, y",
Usage: "assume \"yes\" and run non-interactively",
&cli.BoolFlag{
Name: "yes",
Aliases: []string{"y"},
Usage: "assume \"yes\" and run non-interactively",
},
},
Action: clientsResetAction,

View File

@@ -12,11 +12,12 @@ func TestClientsResetCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx0 := NewTestContext([]string{"ls"})
args0 := []string{"ls"}
ctx0 := NewTestContext(args0)
// Run command with test context.
output0 := capture.Output(func() {
err = ClientsListCommand.Run(ctx0)
err = ClientsListCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.
@@ -26,11 +27,12 @@ func TestClientsResetCommand(t *testing.T) {
assert.Contains(t, output0, "metrics")
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"reset"})
args := []string{"reset"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsResetCommand.Run(ctx)
err = ClientsResetCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -40,7 +42,7 @@ func TestClientsResetCommand(t *testing.T) {
// Run command with test context.
output1 := capture.Output(func() {
err = ClientsListCommand.Run(ctx0)
err = ClientsListCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.

View File

@@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"

View File

@@ -12,11 +12,12 @@ func TestClientsShowCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"show", "cs5gfen1bgxz7s9i"})
args := []string{"show", "cs5gfen1bgxz7s9i"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsShowCommand.Run(ctx)
err = ClientsShowCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -30,11 +31,12 @@ func TestClientsShowCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"show", "cs5gfen1bgxzxxxx"})
args := []string{"show", "cs5gfen1bgxzxxxx"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = ClientsShowCommand.Run(ctx)
err = ClientsShowCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -30,7 +30,7 @@ import (
"syscall"
"github.com/sevlyar/go-daemon"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/event"
@@ -40,42 +40,44 @@ import (
var log = event.Log
// PhotoPrism contains the photoprism CLI (sub-)commands.
var PhotoPrism = []cli.Command{
StartCommand,
StopCommand,
StatusCommand,
IndexCommand,
FindCommand,
ImportCommand,
CopyCommand,
FacesCommands,
PlacesCommands,
PurgeCommand,
CleanUpCommand,
OptimizeCommand,
MomentsCommand,
ConvertCommand,
ThumbsCommand,
MigrateCommand,
MigrationsCommands,
BackupCommand,
RestoreCommand,
ResetCommand,
PasswdCommand,
UsersCommands,
ClientsCommands,
AuthCommands,
ShowCommands,
VersionCommand,
ShowConfigCommand,
ConnectCommand,
var PhotoPrism = []*cli.Command{
&StartCommand,
&StopCommand,
&StatusCommand,
&IndexCommand,
&FindCommand,
&ImportCommand,
&CopyCommand,
&FacesCommands,
&PlacesCommands,
&PurgeCommand,
&CleanUpCommand,
&OptimizeCommand,
&MomentsCommand,
&ConvertCommand,
&ThumbsCommand,
&MigrateCommand,
&MigrationsCommands,
&BackupCommand,
&RestoreCommand,
&ResetCommand,
&PasswdCommand,
&UsersCommands,
&ClientsCommands,
&AuthCommands,
&ShowCommands,
&VersionCommand,
&EditionCommand,
&ShowConfigCommand,
&ConnectCommand,
}
// CountFlag represents a CLI flag to limit the number of report rows.
var CountFlag = cli.UintFlag{
Name: "n",
Usage: "`LIMIT` number of results",
Value: 100,
var CountFlag = &cli.UintFlag{
Name: "count",
Aliases: []string{"n"},
Usage: "`LIMIT` number of results",
Value: 100,
}
// LogErr logs an error if the argument is not nil.

View File

@@ -6,7 +6,7 @@ import (
"testing"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/event"
@@ -39,11 +39,14 @@ func TestMain(m *testing.M) {
func NewTestContext(args []string) *cli.Context {
// Create new command-line app.
app := cli.NewApp()
app.Name = "photoprism"
app.Usage = "PhotoPrism®"
app.Description = ""
app.Version = "test"
app.Copyright = "(c) 2018-2024 PhotoPrism UG. All rights reserved."
app.EnableBashCompletion = true
app.Flags = config.Flags.Cli()
app.Commands = PhotoPrism
app.EnableBashCompletion = false
app.Metadata = map[string]interface{}{
"Name": "PhotoPrism",
"About": "PhotoPrism®",
@@ -52,9 +55,9 @@ func NewTestContext(args []string) *cli.Context {
}
// Parse command arguments.
flags := flag.NewFlagSet("test", 0)
LogErr(flags.Parse(args))
set := flag.NewFlagSet("test", flag.ContinueOnError)
LogErr(set.Parse(args))
// Create and return new context.
return cli.NewContext(app, flags, nil)
return cli.NewContext(app, set, nil)
}

View File

@@ -1,7 +1,7 @@
package commands
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism/get"

View File

@@ -1,7 +1,7 @@
package commands
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
)

View File

@@ -6,7 +6,7 @@ import (
"strings"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism/get"
@@ -19,13 +19,15 @@ var ConvertCommand = cli.Command{
Usage: "Converts files in other formats to JPEG and AVC as needed",
ArgsUsage: "[subfolder]",
Flags: []cli.Flag{
cli.StringSliceFlag{
Name: "ext, e",
Usage: "only process files with the specified extensions, e.g. mp4",
&cli.StringSliceFlag{
Name: "ext",
Aliases: []string{"e"},
Usage: "only process files with the specified extensions, e.g. mp4",
},
cli.BoolFlag{
Name: "force, f",
Usage: "replace existing JPEG files in the sidecar folder",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "replace existing JPEG files in the sidecar folder",
},
},
Action: convertAction,

View File

@@ -7,7 +7,7 @@ import (
"strings"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
@@ -22,9 +22,10 @@ var CopyCommand = cli.Command{
Usage: "Copies media files to originals",
ArgsUsage: "[source]",
Flags: []cli.Flag{
cli.StringFlag{
Name: "dest, d",
Usage: "relative originals `PATH` to which the files should be imported",
&cli.StringFlag{
Name: "dest",
Aliases: []string{"d"},
Usage: "relative originals `PATH` to which the files should be imported",
},
},
Action: copyAction,

View File

@@ -0,0 +1,26 @@
package commands
import (
"fmt"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
)
// EditionCommand configures the "photoprism edition" command.
var EditionCommand = cli.Command{
Name: "edition",
Usage: "Shows edition information",
Hidden: true,
Action: editionAction,
}
// editionAction displays information about the current edition.
func editionAction(ctx *cli.Context) error {
conf := config.NewConfig(ctx)
fmt.Println(conf.Edition())
return nil
}

View File

@@ -0,0 +1,28 @@
package commands
import (
"testing"
"github.com/photoprism/photoprism/pkg/capture"
"github.com/stretchr/testify/assert"
)
func TestEditionCommand(t *testing.T) {
t.Run("Success", func(t *testing.T) {
var err error
// Create test context with flags and arguments.
args := []string{"edition"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = EditionCommand.Run(ctx, args...)
})
// Check command output for plausibility.
// t.Logf(output)
assert.NoError(t, err)
assert.Contains(t, output, "ce")
})
}

View File

@@ -8,7 +8,7 @@ import (
"github.com/dustin/go-humanize/english"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity/query"
@@ -22,7 +22,7 @@ import (
var FacesCommands = cli.Command{
Name: "faces",
Usage: "Face recognition subcommands",
Subcommands: []cli.Command{
Subcommands: []*cli.Command{
{
Name: "stats",
Usage: "Shows stats on face samples",
@@ -32,9 +32,10 @@ var FacesCommands = cli.Command{
Name: "audit",
Usage: "Scans the index for issues",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "fix, f",
Usage: "fix discovered issues",
&cli.BoolFlag{
Name: "fix",
Aliases: []string{"f"},
Usage: "fix discovered issues",
},
},
Action: facesAuditAction,
@@ -43,9 +44,10 @@ var FacesCommands = cli.Command{
Name: "reset",
Usage: "Removes people and faces after confirmation",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "remove all people and faces",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "remove all people and faces",
},
},
Action: facesResetAction,
@@ -60,9 +62,10 @@ var FacesCommands = cli.Command{
Name: "update",
Usage: "Performs face clustering and matching",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "update all faces",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "update all faces",
},
},
Action: facesUpdateAction,

View File

@@ -6,7 +6,7 @@ import (
"strings"
"github.com/dustin/go-humanize"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/entity/search"
"github.com/photoprism/photoprism/internal/entity/sortby"
@@ -19,10 +19,11 @@ var FindCommand = cli.Command{
Name: "find",
Usage: "Searches the index for specific files",
ArgsUsage: "filter",
Flags: append(report.CliFlags, cli.UintFlag{
Name: "n",
Usage: "maximum number of search `RESULTS`",
Value: 10000,
Flags: append(report.CliFlags, &cli.UintFlag{
Name: "count",
Aliases: []string{"n"},
Usage: "maximum number of search `RESULTS`",
Value: 10000,
}),
Action: findAction,
}
@@ -44,7 +45,7 @@ func findAction(ctx *cli.Context) error {
Query: strings.TrimSpace(ctx.Args().First()),
Primary: false,
Merged: false,
Count: ctx.Int("n"),
Count: ctx.Int("count"),
Offset: 0,
Order: sortby.Name,
}

View File

@@ -12,11 +12,12 @@ func TestFindCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"find", "--csv"})
args := []string{"find", "--csv"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = FindCommand.Run(ctx)
err = FindCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -7,7 +7,7 @@ import (
"strings"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
@@ -22,9 +22,10 @@ var ImportCommand = cli.Command{
Usage: "Moves media files to originals",
ArgsUsage: "[source]",
Flags: []cli.Flag{
cli.StringFlag{
Name: "dest, d",
Usage: "relative originals `PATH` to which the files should be imported",
&cli.StringFlag{
Name: "dest",
Aliases: []string{"d"},
Usage: "relative originals `PATH` to which the files should be imported",
},
},
Action: importAction,

View File

@@ -7,7 +7,7 @@ import (
"time"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/photoprism"
"github.com/photoprism/photoprism/internal/photoprism/get"
@@ -25,17 +25,20 @@ var IndexCommand = cli.Command{
}
var indexFlags = []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "rescan all originals, including unchanged files",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "rescan all originals, including unchanged files",
},
cli.BoolFlag{
Name: "archived, a",
Usage: "do not skip files belonging to archived photos",
&cli.BoolFlag{
Name: "archived",
Aliases: []string{"a"},
Usage: "do not skip files belonging to archived photos",
},
cli.BoolFlag{
Name: "cleanup, c",
Usage: "remove orphan index entries and thumbnails",
&cli.BoolFlag{
Name: "cleanup",
Aliases: []string{"c"},
Usage: "remove orphan index entries and thumbnails",
},
}

View File

@@ -1,6 +1,6 @@
package commands
import "github.com/urfave/cli"
import "github.com/urfave/cli/v2"
// MigrateCommand configures the command name, flags, and action.
var MigrateCommand = cli.Command{

View File

@@ -9,7 +9,7 @@ import (
"time"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity/migrate"
@@ -31,13 +31,15 @@ var MigrationsRunCommand = cli.Command{
Usage: "Executes database schema migrations",
ArgsUsage: "[migrations...]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "failed, f",
Usage: "run previously failed migrations",
&cli.BoolFlag{
Name: "failed",
Aliases: []string{"f"},
Usage: "run previously failed migrations",
},
cli.BoolFlag{
Name: "trace, t",
Usage: "show trace logs for debugging",
&cli.BoolFlag{
Name: "trace",
Aliases: []string{"t"},
Usage: "show trace logs for debugging",
},
},
Action: migrationsRunAction,
@@ -47,9 +49,9 @@ var MigrationsRunCommand = cli.Command{
var MigrationsCommands = cli.Command{
Name: "migrations",
Usage: "Database schema migration subcommands",
Subcommands: []cli.Command{
MigrationsStatusCommand,
MigrationsRunCommand,
Subcommands: []*cli.Command{
&MigrationsStatusCommand,
&MigrationsRunCommand,
},
}

View File

@@ -4,7 +4,7 @@ import (
"context"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/photoprism/get"
)

View File

@@ -4,7 +4,7 @@ import (
"context"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/workers"
@@ -15,9 +15,10 @@ var OptimizeCommand = cli.Command{
Name: "optimize",
Usage: "Maintains titles, estimates, and other metadata",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "update all, including recently optimized",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "update all, including recently optimized",
},
},
Action: optimizeAction,

View File

@@ -10,7 +10,7 @@ import (
"strings"
"syscall"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/pkg/clean"
@@ -24,13 +24,15 @@ var PasswdCommand = cli.Command{
Usage: "Changes the local account password of a registered user",
ArgsUsage: "[username]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "show, s",
Usage: "show bcrypt hash of new password",
&cli.BoolFlag{
Name: "show",
Aliases: []string{"s"},
Usage: "show bcrypt hash of new password",
},
cli.BoolFlag{
Name: "remove, rm",
Usage: "remove password to disable local authentication",
&cli.BoolFlag{
Name: "remove",
Aliases: []string{"rm"},
Usage: "remove password to disable local authentication",
},
},
Action: passwdAction,

View File

@@ -11,11 +11,12 @@ func TestPasswdCommand(t *testing.T) {
t.Run("UserNotFound", func(t *testing.T) {
var err error
ctx := NewTestContext([]string{"passwd", "--show", "mila"})
args := []string{"passwd", "--show", "mila"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = PasswdCommand.Run(ctx)
err = PasswdCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -25,11 +26,12 @@ func TestPasswdCommand(t *testing.T) {
t.Run("DeletedUser", func(t *testing.T) {
var err error
ctx := NewTestContext([]string{"passwd", "--show", "uqxqg7i1kperxvu8"})
args := []string{"passwd", "--show", "uqxqg7i1kperxvu8"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = PasswdCommand.Run(ctx)
err = PasswdCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -39,7 +41,8 @@ func TestPasswdCommand(t *testing.T) {
t.Run("DeletePassword", func(t *testing.T) {
var err error
ctx := NewTestContext([]string{"passwd", "--rm", "no_local_auth"})
args := []string{"passwd", "--rm", "no_local_auth"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {

View File

@@ -5,7 +5,7 @@ import (
"time"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/entity/query"
@@ -16,19 +16,21 @@ import (
var PlacesCommands = cli.Command{
Name: "places",
Usage: "Maps and location information subcommands",
Subcommands: []cli.Command{
Subcommands: []*cli.Command{
{
Name: "update",
Usage: "Updates location information",
Description: "Updates missing location information only if used without the --force flag.",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "forces the location of all pictures to be updated",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "forces the location of all pictures to be updated",
},
cli.BoolFlag{
Name: "yes, y",
Usage: "assume \"yes\" and run non-interactively",
&cli.BoolFlag{
Name: "yes",
Aliases: []string{"y"},
Usage: "assume \"yes\" and run non-interactively",
},
},
Action: placesUpdateAction,

View File

@@ -7,7 +7,7 @@ import (
"time"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/photoprism"
"github.com/photoprism/photoprism/internal/photoprism/get"
@@ -24,11 +24,11 @@ var PurgeCommand = cli.Command{
}
var purgeFlags = []cli.Flag{
cli.BoolFlag{
&cli.BoolFlag{
Name: "hard",
Usage: "permanently remove from index",
},
cli.BoolFlag{
&cli.BoolFlag{
Name: "dry",
Usage: "dry run, don't actually remove anything",
},

View File

@@ -10,7 +10,7 @@ import (
"github.com/manifoldco/promptui"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
@@ -22,17 +22,20 @@ var ResetCommand = cli.Command{
Name: "reset",
Usage: "Resets the index, clears the cache, and removes sidecar files",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "index, i",
Usage: "reset index database only",
&cli.BoolFlag{
Name: "index",
Aliases: []string{"i"},
Usage: "reset index database only",
},
cli.BoolFlag{
Name: "trace, t",
Usage: "show trace logs for debugging",
&cli.BoolFlag{
Name: "trace",
Aliases: []string{"t"},
Usage: "show trace logs for debugging",
},
cli.BoolFlag{
Name: "yes, y",
Usage: "assume \"yes\" and run non-interactively",
&cli.BoolFlag{
Name: "yes",
Aliases: []string{"y"},
Usage: "assume \"yes\" and run non-interactively",
},
},
Action: resetAction,

View File

@@ -5,7 +5,7 @@ import (
"time"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/photoprism/backup"
"github.com/photoprism/photoprism/internal/photoprism/get"
@@ -28,25 +28,29 @@ var RestoreCommand = cli.Command{
}
var restoreFlags = []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "replace the index database with the backup, if it already exists",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "replace the index database with the backup, if it already exists",
},
cli.BoolFlag{
Name: "albums, a",
Usage: "restore albums from the YAML backup files found in the album backup path",
&cli.BoolFlag{
Name: "albums",
Aliases: []string{"a"},
Usage: "restore albums from the YAML backup files found in the album backup path",
},
cli.StringFlag{
&cli.StringFlag{
Name: "albums-path",
Usage: "custom album backup `PATH`",
},
cli.BoolFlag{
Name: "database, index, i",
Usage: "restore the index database from the specified file (stdin if - is passed as filename), or the most recent backup found in the database backup path",
&cli.BoolFlag{
Name: "database",
Aliases: []string{"index", "i"},
Usage: "restore the index database from the specified file (stdin if - is passed as filename), or the most recent backup found in the database backup path",
},
cli.StringFlag{
Name: "database-path, index-path",
Usage: "custom database backup `PATH`",
&cli.StringFlag{
Name: "database-path",
Aliases: []string{"index-path"},
Usage: "custom database backup `PATH`",
},
}

View File

@@ -1,21 +1,21 @@
package commands
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
)
// ShowCommands configures the show subcommands.
var ShowCommands = cli.Command{
Name: "show",
Usage: "Shows supported formats, features, and config options",
Subcommands: []cli.Command{
ShowConfigCommand,
ShowConfigOptionsCommand,
ShowConfigYamlCommand,
ShowSearchFiltersCommand,
ShowFileFormatsCommand,
ShowThumbSizesCommand,
ShowVideoSizesCommand,
ShowMetadataCommand,
Subcommands: []*cli.Command{
&ShowConfigCommand,
&ShowConfigOptionsCommand,
&ShowConfigYamlCommand,
&ShowSearchFiltersCommand,
&ShowFileFormatsCommand,
&ShowThumbSizesCommand,
&ShowVideoSizesCommand,
&ShowMetadataCommand,
},
}

View File

@@ -5,7 +5,7 @@ import (
"strings"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism/get"

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/pkg/txt/report"

View File

@@ -10,10 +10,10 @@ import (
func TestShowConfigOptionsCommand(t *testing.T) {
var err error
ctx := NewTestContext([]string{"config-options", "--md"})
args := []string{"config-options", "--md"}
ctx := NewTestContext(args)
output := capture.Stdout(func() {
err = ShowConfigOptionsCommand.Run(ctx)
err = ShowConfigOptionsCommand.Run(ctx, args...)
})
assert.NoError(t, err)

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/pkg/txt/report"

View File

@@ -10,10 +10,10 @@ import (
func TestShowConfigYamlCommand(t *testing.T) {
var err error
ctx := NewTestContext([]string{"config-yaml", "--md"})
args := []string{"config-yaml", "--md"}
ctx := NewTestContext(args)
output := capture.Stdout(func() {
err = ShowConfigYamlCommand.Run(ctx)
err = ShowConfigYamlCommand.Run(ctx, args...)
})
if err != nil {

View File

@@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/media"
@@ -15,9 +15,10 @@ var ShowFileFormatsCommand = cli.Command{
Name: "file-formats",
Aliases: []string{"formats"},
Usage: "Displays supported media and sidecar file formats",
Flags: append(report.CliFlags, cli.BoolFlag{
Name: "short, s",
Usage: "hide format descriptions",
Flags: append(report.CliFlags, &cli.BoolFlag{
Name: "short",
Aliases: []string{"s"},
Usage: "hide format descriptions",
}),
Action: showFileFormatsAction,
}

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"sort"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/meta"
"github.com/photoprism/photoprism/pkg/txt/report"
@@ -15,9 +15,10 @@ var ShowMetadataCommand = cli.Command{
Name: "metadata",
Aliases: []string{"meta"},
Usage: "Displays supported metadata tags and standards",
Flags: append(report.CliFlags, cli.BoolFlag{
Name: "short, s",
Usage: "hide links to documentation",
Flags: append(report.CliFlags, &cli.BoolFlag{
Name: "short",
Aliases: []string{"s"},
Usage: "hide links to documentation",
}),
Action: showMetadataAction,
}

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"sort"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/pkg/txt/report"

View File

@@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/thumb"
"github.com/photoprism/photoprism/pkg/txt/report"

View File

@@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/thumb"
"github.com/photoprism/photoprism/pkg/txt/report"

View File

@@ -11,9 +11,10 @@ import (
"github.com/dustin/go-humanize/english"
"github.com/sevlyar/go-daemon"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/auth/session"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/mutex"
"github.com/photoprism/photoprism/internal/photoprism/backup"
"github.com/photoprism/photoprism/internal/server"
@@ -35,14 +36,16 @@ var StartCommand = cli.Command{
// startFlags specifies the start command parameters.
var startFlags = []cli.Flag{
cli.BoolFlag{
Name: "detach-server, d",
Usage: "detach from the console (daemon mode)",
EnvVar: "PHOTOPRISM_DETACH_SERVER",
&cli.BoolFlag{
Name: "detach-server",
Aliases: []string{"d"},
Usage: "detach from the console (daemon mode)",
EnvVars: config.EnvVars("DETACH_SERVER"),
},
cli.BoolFlag{
Name: "config, c",
Usage: "show config",
&cli.BoolFlag{
Name: "config",
Aliases: []string{"c"},
Usage: "show config",
},
}
@@ -89,7 +92,7 @@ func startAction(ctx *cli.Context) error {
dctx := new(daemon.Context)
dctx.LogFileName = conf.LogFilename()
dctx.PidFileName = conf.PIDFilename()
dctx.Args = ctx.Args()
dctx.Args = ctx.Args().Slice()
if !daemon.WasReborn() && conf.DetachServer() {
conf.Shutdown()

View File

@@ -9,7 +9,7 @@ import (
"time"
"github.com/tidwall/gjson"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
)

View File

@@ -4,7 +4,7 @@ import (
"syscall"
"github.com/sevlyar/go-daemon"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/pkg/clean"
)

View File

@@ -5,7 +5,7 @@ import (
"strings"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/photoprism/get"
"github.com/photoprism/photoprism/pkg/clean"
@@ -17,13 +17,15 @@ var ThumbsCommand = cli.Command{
Usage: "(Re-)generates thumbnails based on the current configuration",
ArgsUsage: "[subfolder]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "replace existing thumbnail images",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "replace existing thumbnail images",
},
cli.BoolFlag{
Name: "originals, o",
Usage: "scan originals only, skip sidecar folder",
&cli.BoolFlag{
Name: "originals",
Aliases: []string{"o"},
Usage: "scan originals only, skip sidecar folder",
},
},
Action: thumbsAction,

View File

@@ -1,7 +1,7 @@
package commands
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/auth/acl"
"github.com/photoprism/photoprism/pkg/authn"
@@ -26,80 +26,91 @@ var UsersCommands = cli.Command{
Name: "users",
Aliases: []string{"user"},
Usage: "User management subcommands",
Subcommands: []cli.Command{
UsersListCommand,
UsersLegacyCommand,
UsersAddCommand,
UsersShowCommand,
UsersModCommand,
UsersRemoveCommand,
UsersResetCommand,
Subcommands: []*cli.Command{
&UsersListCommand,
&UsersLegacyCommand,
&UsersAddCommand,
&UsersShowCommand,
&UsersModCommand,
&UsersRemoveCommand,
&UsersResetCommand,
},
}
// UserFlags specifies the add and modify user command flags.
var UserFlags = []cli.Flag{
cli.StringFlag{
Name: "name, n",
Usage: UserNameUsage,
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
Usage: UserNameUsage,
},
cli.StringFlag{
Name: "email, m",
Usage: UserEmailUsage,
&cli.StringFlag{
Name: "email",
Aliases: []string{"m"},
Usage: UserEmailUsage,
},
cli.StringFlag{
Name: "password, p",
Usage: UserPasswordUsage,
&cli.StringFlag{
Name: "password",
Aliases: []string{"p"},
Usage: UserPasswordUsage,
},
cli.StringFlag{
Name: "role, r",
Usage: UserRoleUsage,
Value: acl.RoleAdmin.String(),
&cli.StringFlag{
Name: "role",
Aliases: []string{"r"},
Usage: UserRoleUsage,
Value: acl.RoleAdmin.String(),
},
cli.StringFlag{
Name: "auth, A",
Usage: UserAuthUsage,
Value: authn.ProviderDefault.String(),
&cli.StringFlag{
Name: "auth",
Aliases: []string{"A"},
Usage: UserAuthUsage,
Value: authn.ProviderDefault.String(),
},
cli.StringFlag{
&cli.StringFlag{
Name: "auth-id",
Usage: UserAuthIDUsage,
Value: "",
},
cli.BoolFlag{
Name: "superadmin, s",
Usage: UserAdminUsage,
&cli.BoolFlag{
Name: "superadmin",
Aliases: []string{"s"},
Usage: UserAdminUsage,
},
cli.BoolFlag{
Name: "no-login, l",
Usage: UserNoLoginUsage,
&cli.BoolFlag{
Name: "no-login",
Aliases: []string{"l"},
Usage: UserNoLoginUsage,
},
cli.BoolFlag{
Name: "webdav, w",
Usage: UserWebDAVUsage,
&cli.BoolFlag{
Name: "webdav",
Aliases: []string{"w"},
Usage: UserWebDAVUsage,
},
}
// UserTokensFlag is a CLI flag for showing the security tokens in reports.
var UserTokensFlag = cli.BoolFlag{
var UserTokensFlag = &cli.BoolFlag{
Name: "tokens",
Usage: "show user preview and download tokens",
}
// UsersLoginFlag is a CLI flag for showing the last login timestamp in reports.
var UsersLoginFlag = cli.BoolFlag{
Name: "login, l",
Usage: "show date and time of last login",
var UsersLoginFlag = &cli.BoolFlag{
Name: "login",
Aliases: []string{"l"},
Usage: "show date and time of last login",
}
// UsersCreatedFlag is a CLI flag for showing the account creation timestamp in reports.
var UsersCreatedFlag = cli.BoolFlag{
Name: "created, a",
Usage: "show account creation timestamp",
var UsersCreatedFlag = &cli.BoolFlag{
Name: "created",
Aliases: []string{"a"},
Usage: "show account creation timestamp",
}
// UsersDeletedFlag is a CLI flag for showing deleted user accounts in reports.
var UsersDeletedFlag = cli.BoolFlag{
Name: "deleted, r",
Usage: "show deleted user accounts",
var UsersDeletedFlag = &cli.BoolFlag{
Name: "deleted",
Aliases: []string{"r"},
Usage: "show deleted user accounts",
}

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"

View File

@@ -12,11 +12,12 @@ func TestUsersAddCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"add", "--name=Alice", "--email=jane@test.de", "--password=test1234", "--role=admin", "alice"})
args := []string{"add", "--name=Alice", "--email=jane@test.de", "--password=test1234", "--role=admin", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersAddCommand.Run(ctx)
err = UsersAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -29,11 +30,12 @@ func TestUsersAddCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"add", "--name=deleted", "--password=test1234", "deleted"})
args := []string{"add", "--name=deleted", "--password=test1234", "deleted"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersAddCommand.Run(ctx)
err = UsersAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -46,11 +48,12 @@ func TestUsersAddCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"add", "--name=noname", "--password=test1234", "/##"})
args := []string{"add", "--name=noname", "--password=test1234", "/##"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersAddCommand.Run(ctx)
err = UsersAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"

View File

@@ -12,11 +12,12 @@ func TestUsersLegacyCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{""})
args := []string{""}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersLegacyCommand.Run(ctx)
err = UsersLegacyCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity/query"
@@ -39,7 +39,7 @@ func usersListAction(ctx *cli.Context) error {
}
// Fetch users from database.
users, err := query.Users(ctx.Int("n"), 0, "", ctx.Args().First(), ctx.Bool("deleted"))
users, err := query.Users(ctx.Int("count"), 0, "", ctx.Args().First(), ctx.Bool("deleted"))
if err != nil {
return err

View File

@@ -1,6 +1,8 @@
package commands
import (
"fmt"
"runtime/debug"
"testing"
"github.com/stretchr/testify/assert"
@@ -13,11 +15,12 @@ func TestUsersListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--login", "--created", "--deleted", "-n", "100", "--md"})
args := []string{"ls", "--login", "--created", "--deleted", "-n", "100", "--md"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx)
err = UsersListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -32,11 +35,12 @@ func TestUsersListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "-l", "friend"})
args := []string{"ls", "-l", "friend"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx)
err = UsersListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -52,11 +56,12 @@ func TestUsersListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "-a", "friend"})
args := []string{"ls", "-a", "friend"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx)
err = UsersListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -72,11 +77,12 @@ func TestUsersListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "-r", "friend"})
args := []string{"ls", "-r", "friend"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx)
err = UsersListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -92,11 +98,12 @@ func TestUsersListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--csv", "friend"})
args := []string{"ls", "--csv", "friend"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx)
err = UsersListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -112,11 +119,12 @@ func TestUsersListCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "notexisting"})
args := []string{"ls", "notexisting"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx)
err = UsersListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -124,15 +132,39 @@ func TestUsersListCommand(t *testing.T) {
assert.NoError(t, err)
assert.Empty(t, output)
})
t.Run("InvalidFlag", func(t *testing.T) {
t.Run("OneResult", func(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "--xyz", "friend"})
args := []string{"ls", "--count=1", "friend"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx)
err = UsersListCommand.Run(ctx, args...)
})
// Check result.
assert.NoError(t, err)
assert.NotEmpty(t, output)
})
t.Run("InvalidFlag", func(t *testing.T) {
var err error
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("error: %s \nstack: %s", r, debug.Stack())
assert.Error(t, err)
}
}()
// Create test context with flags and arguments.
args := []string{"ls", "--xyz", "friend"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -140,20 +172,4 @@ func TestUsersListCommand(t *testing.T) {
assert.Error(t, err)
assert.Empty(t, output)
})
t.Run("InvalidValue", func(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"ls", "-n=-1", "friend"})
// Run command with test context.
output := capture.Output(func() {
err = UsersListCommand.Run(ctx)
})
// Check command output for plausibility.
//t.Logf(output)
assert.Error(t, err)
assert.Empty(t, output)
})
}

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
@@ -17,7 +17,7 @@ var UsersModCommand = cli.Command{
Name: "mod",
Usage: "Changes user account settings",
ArgsUsage: "[username]",
Flags: append(UserFlags, cli.BoolFlag{
Flags: append(UserFlags, &cli.BoolFlag{
Name: "disable-2fa",
Usage: UserDisable2FA,
}),

View File

@@ -12,11 +12,12 @@ func TestUsersModCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"mod", "--name=New", "--email=new@test.de", "uqxqg7i1kperxxx0"})
args := []string{"mod", "--name=New", "--email=new@test.de", "uqxqg7i1kperxxx0"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersModCommand.Run(ctx)
err = UsersModCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -28,11 +29,12 @@ func TestUsersModCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"mod", "--name=New", "--email=new@test.de", "deleted"})
args := []string{"mod", "--name=New", "--email=new@test.de", "deleted"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersModCommand.Run(ctx)
err = UsersModCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
@@ -18,9 +18,10 @@ var UsersRemoveCommand = cli.Command{
Usage: "Deletes a registered user account",
ArgsUsage: "[username]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "don't ask for confirmation",
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "don't ask for confirmation",
},
},
Action: usersRemoveAction,

View File

@@ -12,11 +12,12 @@ func TestUsersRemoveCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"rm", "uqxqg7i1kperxxx0"})
args := []string{"rm", "uqxqg7i1kperxxx0"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersRemoveCommand.Run(ctx)
err = UsersRemoveCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -28,11 +29,12 @@ func TestUsersRemoveCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"rm", "deleted"})
args := []string{"rm", "deleted"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersRemoveCommand.Run(ctx)
err = UsersRemoveCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -5,7 +5,7 @@ import (
"github.com/manifoldco/promptui"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
@@ -19,13 +19,15 @@ var UsersResetCommand = cli.Command{
Usage: "Removes all registered user accounts",
Description: UsersResetDescription,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "trace, t",
Usage: "show trace logs for debugging",
&cli.BoolFlag{
Name: "trace",
Aliases: []string{"t"},
Usage: "show trace logs for debugging",
},
cli.BoolFlag{
Name: "yes, y",
Usage: "assume \"yes\" and run non-interactively",
&cli.BoolFlag{
Name: "yes",
Aliases: []string{"y"},
Usage: "assume \"yes\" and run non-interactively",
},
},
Action: usersResetAction,

View File

@@ -12,11 +12,12 @@ func TestUsersResetCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx0 := NewTestContext([]string{"ls"})
args0 := []string{"ls"}
ctx0 := NewTestContext(args0)
// Run command with test context.
output0 := capture.Output(func() {
err = UsersListCommand.Run(ctx0)
err = UsersListCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.
@@ -26,11 +27,12 @@ func TestUsersResetCommand(t *testing.T) {
assert.Contains(t, output0, "bob")
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"reset"})
args := []string{"reset"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersResetCommand.Run(ctx)
err = UsersResetCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -40,7 +42,7 @@ func TestUsersResetCommand(t *testing.T) {
// Run command with test context.
output1 := capture.Output(func() {
err = UsersListCommand.Run(ctx0)
err = UsersListCommand.Run(ctx0, args0...)
})
// Check command output for plausibility.

View File

@@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"

View File

@@ -12,11 +12,12 @@ func TestUsersShowCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"show", "alice"})
args := []string{"show", "alice"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersShowCommand.Run(ctx)
err = UsersShowCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -30,11 +31,12 @@ func TestUsersShowCommand(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{"show", "notexisting"})
args := []string{"show", "notexisting"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersShowCommand.Run(ctx)
err = UsersShowCommand.Run(ctx, args...)
})
// Check command output for plausibility.

View File

@@ -12,11 +12,12 @@ func TestUsersCommand(t *testing.T) {
var err error
//Add John
ctx := NewTestContext([]string{"add", "--name=John", "--email=john@test.de", "--password=test1234", "--role=admin", "john"})
args := []string{"add", "--name=John", "--email=john@test.de", "--password=test1234", "--role=admin", "john"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = UsersAddCommand.Run(ctx)
err = UsersAddCommand.Run(ctx, args...)
})
// Check command output for plausibility.
@@ -24,11 +25,12 @@ func TestUsersCommand(t *testing.T) {
assert.NoError(t, err)
assert.Empty(t, output)
ctx2 := NewTestContext([]string{"show", "john"})
args2 := []string{"show", "john"}
ctx2 := NewTestContext(args2)
// Run command with test context.
output2 := capture.Output(func() {
err = UsersShowCommand.Run(ctx2)
err = UsersShowCommand.Run(ctx2, args2...)
})
//t.Logf(output2)
@@ -40,11 +42,12 @@ func TestUsersCommand(t *testing.T) {
//Modify John
// Create test context with flags and arguments.
ctx3 := NewTestContext([]string{"mod", "--name=Johnny", "--email=johnnny@test.de", "--password=test12345", "john"})
args3 := []string{"mod", "--name=Johnny", "--email=johnnny@test.de", "--password=test12345", "john"}
ctx3 := NewTestContext(args3)
// Run command with test context.
output3 := capture.Output(func() {
err = UsersModCommand.Run(ctx3)
err = UsersModCommand.Run(ctx3, args3...)
})
// Check command output for plausibility.
@@ -53,7 +56,7 @@ func TestUsersCommand(t *testing.T) {
assert.Empty(t, output3)
output4 := capture.Output(func() {
err = UsersShowCommand.Run(ctx2)
err = UsersShowCommand.Run(ctx2, args2...)
})
//t.Logf(output4)
@@ -65,11 +68,12 @@ func TestUsersCommand(t *testing.T) {
//Remove John
// Create test context with flags and arguments.
ctx5 := NewTestContext([]string{"rm", "--force", "john"})
args5 := []string{"rm", "--force", "john"}
ctx5 := NewTestContext(args5)
// Run command with test context.
output5 := capture.Output(func() {
err = UsersRemoveCommand.Run(ctx5)
err = UsersRemoveCommand.Run(ctx5, args5...)
})
// Check command output for plausibility.
@@ -78,7 +82,7 @@ func TestUsersCommand(t *testing.T) {
assert.Empty(t, output5)
output6 := capture.Output(func() {
err = UsersShowCommand.Run(ctx2)
err = UsersShowCommand.Run(ctx2, args2...)
})
//t.Logf(output6)

View File

@@ -3,19 +3,19 @@ package commands
import (
"fmt"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/config"
)
// VersionCommand configures the command name, flags, and action.
// VersionCommand configures the "photoprism version" command.
var VersionCommand = cli.Command{
Name: "version",
Usage: "Shows version information",
Action: versionAction,
}
// versionAction prints the current version
// versionAction displays information about the current version.
func versionAction(ctx *cli.Context) error {
conf := config.NewConfig(ctx)

View File

@@ -8,18 +8,21 @@ import (
)
func TestVersionCommand(t *testing.T) {
var err error
t.Run("Success", func(t *testing.T) {
var err error
// Create test context with flags and arguments.
ctx := NewTestContext([]string{""})
// Create test context with flags and arguments.
args := []string{"version"}
ctx := NewTestContext(args)
// Run command with test context.
output := capture.Output(func() {
err = VersionCommand.Run(ctx)
// Run command with test context.
output := capture.Output(func() {
err = VersionCommand.Run(ctx, args...)
})
// Check command output for plausibility.
// t.Logf(output)
assert.NoError(t, err)
assert.Contains(t, output, "test")
})
// Check command output for plausibility.
// t.Logf(output)
assert.NoError(t, err)
assert.Contains(t, output, "test")
}

View File

@@ -4,7 +4,7 @@ import (
"reflect"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/pkg/txt"
)
@@ -26,10 +26,8 @@ func ApplyCliContext(c interface{}, ctx *cli.Context) error {
var s string
// Get duration string.
if ctx.IsSet(tagValue) {
if ctx.IsSet(tagValue) || fieldValue.Interface().(time.Duration) == 0 {
s = ctx.String(tagValue)
} else if ctx.GlobalIsSet(tagValue) || fieldValue.Interface().(time.Duration) == 0 {
s = ctx.GlobalString(tagValue)
}
// Parse duration string.
@@ -42,55 +40,37 @@ func ApplyCliContext(c interface{}, ctx *cli.Context) error {
}
case float64:
// Only if explicitly set or current value is empty (use default).
if ctx.IsSet(tagValue) {
if ctx.IsSet(tagValue) || fieldValue.Float() == 0 {
f := ctx.Float64(tagValue)
fieldValue.SetFloat(f)
} else if ctx.GlobalIsSet(tagValue) || fieldValue.Float() == 0 {
f := ctx.GlobalFloat64(tagValue)
fieldValue.SetFloat(f)
}
case int, int64:
// Only if explicitly set or current value is empty (use default).
if ctx.IsSet(tagValue) {
if ctx.IsSet(tagValue) || fieldValue.Int() == 0 {
f := ctx.Int64(tagValue)
fieldValue.SetInt(f)
} else if ctx.GlobalIsSet(tagValue) || fieldValue.Int() == 0 {
f := ctx.GlobalInt64(tagValue)
fieldValue.SetInt(f)
}
case uint, uint64:
// Only if explicitly set or current value is empty (use default).
if ctx.IsSet(tagValue) {
if ctx.IsSet(tagValue) || fieldValue.Uint() == 0 {
f := ctx.Uint64(tagValue)
fieldValue.SetUint(f)
} else if ctx.GlobalIsSet(tagValue) || fieldValue.Uint() == 0 {
f := ctx.GlobalUint64(tagValue)
fieldValue.SetUint(f)
}
case string:
// Only if explicitly set or current value is empty (use default)
if ctx.IsSet(tagValue) {
if ctx.IsSet(tagValue) || fieldValue.String() == "" {
f := ctx.String(tagValue)
fieldValue.SetString(f)
} else if ctx.GlobalIsSet(tagValue) || fieldValue.String() == "" {
f := ctx.GlobalString(tagValue)
fieldValue.SetString(f)
}
case []string:
if ctx.IsSet(tagValue) {
if ctx.IsSet(tagValue) || fieldValue.Len() == 0 {
f := reflect.ValueOf(ctx.StringSlice(tagValue))
fieldValue.Set(f)
} else if ctx.GlobalIsSet(tagValue) || fieldValue.Len() == 0 {
f := reflect.ValueOf(ctx.GlobalStringSlice(tagValue))
fieldValue.Set(f)
}
case bool:
if ctx.IsSet(tagValue) {
f := ctx.Bool(tagValue)
fieldValue.SetBool(f)
} else if ctx.GlobalIsSet(tagValue) {
f := ctx.GlobalBool(tagValue)
fieldValue.SetBool(f)
}
default:
log.Warnf("cannot assign value of type %s from cli flag %s", t, tagValue)

View File

@@ -4,7 +4,7 @@ import (
"reflect"
"strings"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/pkg/list"
)
@@ -52,26 +52,49 @@ func (f CliFlag) Hidden() bool {
return true
}
// EnvVar returns the flag environment variable name.
// EnvVar returns the names of the environment variables as a comma separated string.
func (f CliFlag) EnvVar() string {
field := f.Fields().FieldByName("EnvVar")
if !field.IsValid() {
return ""
}
return field.String()
return strings.Join(f.EnvVars(), ", ")
}
// Name returns the command flag name.
// EnvVars returns the environment variable names as string slice.
func (f CliFlag) EnvVars() []string {
field := f.Fields().FieldByName("EnvVars")
if !field.IsValid() {
return []string{}
}
if vars := field.Interface().([]string); len(vars) > 0 {
return vars
}
return []string{}
}
// Name returns the command flag names as a comma-separated string.
func (f CliFlag) String() string {
return strings.Join(f.Names(), ", ")
}
// Name returns the default command flag name.
func (f CliFlag) Name() string {
return f.Flag.GetName()
if n := f.Flag.Names(); len(n) > 0 {
return n[0]
}
return ""
}
// Names returns the command flag names as string slice.
func (f CliFlag) Names() []string {
return f.Flag.Names()
}
// CommandFlag returns the full command flag based on the name.
func (f CliFlag) CommandFlag() string {
n := strings.Split(f.Name(), ",")
return "--" + n[0]
n := strings.Split(f.String(), ",")
return "--" + strings.TrimSpace(n[0])
}
// Usage returns the command flag usage.

View File

@@ -4,24 +4,24 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
)
func TestCliFlag_Skip(t *testing.T) {
withTags := CliFlag{
Flag: cli.StringFlag{
Name: "with-tags",
Usage: "`STRING`",
EnvVar: "PHOTOPRISM_WITH_TAGS",
Flag: &cli.StringFlag{
Name: "with-tags",
Usage: "`STRING`",
EnvVars: []string{"PHOTOPRISM_WITH_TAGS"},
},
Tags: []string{"foo", "bar"},
}
noTags := CliFlag{
Flag: cli.StringFlag{
Name: "no-tags",
Usage: "`STRING`",
EnvVar: "PHOTOPRISM_NO_TAGS",
Flag: &cli.StringFlag{
Name: "no-tags",
Usage: "`STRING`",
EnvVars: []string{"PHOTOPRISM_NO_TAGS"},
},
Tags: []string{},
}
@@ -38,21 +38,21 @@ func TestCliFlag_Skip(t *testing.T) {
func TestCliFlag_Hidden(t *testing.T) {
hidden := CliFlag{
Flag: cli.StringFlag{
Name: "is-hidden",
Usage: "`STRING`",
EnvVar: "PHOTOPRISM_HIDDEN",
Hidden: true,
Flag: &cli.StringFlag{
Name: "is-hidden",
Usage: "`STRING`",
EnvVars: []string{"PHOTOPRISM_HIDDEN"},
Hidden: true,
},
Tags: []string{"foo", "bar"},
}
visible := CliFlag{
Flag: cli.StringFlag{
Name: "is-visible",
Usage: "`STRING`",
EnvVar: "PHOTOPRISM_VISIBLE",
Hidden: false,
Flag: &cli.StringFlag{
Name: "is-visible",
Usage: "`STRING`",
EnvVars: []string{"PHOTOPRISM_VISIBLE"},
Hidden: false,
},
Tags: []string{},
}
@@ -67,20 +67,20 @@ func TestCliFlag_Hidden(t *testing.T) {
func TestCliFlag_Default(t *testing.T) {
hasdefault := CliFlag{
Flag: cli.StringFlag{
Name: "flag-with-default",
Usage: "`STRING`",
EnvVar: "PHOTOPRISM_DEFAULT",
Flag: &cli.StringFlag{
Name: "flag-with-default",
Usage: "`STRING`",
EnvVars: []string{"PHOTOPRISM_DEFAULT"},
},
DocDefault: "default-value",
Tags: []string{"foo", "bar"},
}
nodefault := CliFlag{
Flag: cli.StringFlag{
Name: "flag-without-default",
Usage: "`STRING`",
EnvVar: "PHOTOPRISM_NODEFAULT",
Flag: &cli.StringFlag{
Name: "flag-without-default",
Usage: "`STRING`",
EnvVars: []string{"PHOTOPRISM_NODEFAULT"},
},
Tags: []string{},
}
@@ -91,10 +91,10 @@ func TestCliFlag_Default(t *testing.T) {
func TestCliFlag_EnvVar(t *testing.T) {
hasDefault := CliFlag{
Flag: cli.StringFlag{
Name: "flag-with-default",
Usage: "`STRING`",
EnvVar: "PHOTOPRISM_DEFAULT",
Flag: &cli.StringFlag{
Name: "flag-with-default",
Usage: "`STRING`",
EnvVars: []string{"PHOTOPRISM_DEFAULT"},
},
DocDefault: "default-value",
Tags: []string{"foo", "bar"},
@@ -105,10 +105,10 @@ func TestCliFlag_EnvVar(t *testing.T) {
func TestCliFlag_CommandFlag(t *testing.T) {
hasdefault := CliFlag{
Flag: cli.StringFlag{
Name: "flag-with-default",
Usage: "`STRING`",
EnvVar: "PHOTOPRISM_DEFAULT",
Flag: &cli.StringFlag{
Name: "flag-with-default",
Usage: "`STRING`",
EnvVars: []string{"PHOTOPRISM_DEFAULT"},
},
DocDefault: "default-value",
Tags: []string{"foo", "bar"},
@@ -119,7 +119,7 @@ func TestCliFlag_CommandFlag(t *testing.T) {
func TestCliFlag_Usage(t *testing.T) {
community := CliFlag{
Flag: cli.StringFlag{
Flag: &cli.StringFlag{
Name: "flag-community",
Usage: "`STRING`",
},
@@ -128,7 +128,7 @@ func TestCliFlag_Usage(t *testing.T) {
}
essentials := CliFlag{
Flag: cli.StringFlag{
Flag: &cli.StringFlag{
Name: "flag-essentials",
Usage: "`STRING`",
},
@@ -136,7 +136,7 @@ func TestCliFlag_Usage(t *testing.T) {
}
plus := CliFlag{
Flag: cli.StringFlag{
Flag: &cli.StringFlag{
Name: "flag-plus",
Usage: "`STRING`",
},
@@ -144,7 +144,7 @@ func TestCliFlag_Usage(t *testing.T) {
}
pro := CliFlag{
Flag: cli.StringFlag{
Flag: &cli.StringFlag{
Name: "flag-pro",
Usage: "`STRING`",
},

View File

@@ -1,12 +1,22 @@
package config
import (
"github.com/urfave/cli"
"strings"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/list"
)
func firstName(names string) string {
if n := strings.Split(names, ","); len(n) > 0 {
return strings.TrimSpace(n[0])
}
return ""
}
// CliFlags represents a list of command-line parameters.
type CliFlags []CliFlag
@@ -41,7 +51,7 @@ func (f CliFlags) Remove(names []string) (result CliFlags) {
result = make(CliFlags, 0, len(f))
for _, flag := range f {
if list.Contains(names, flag.Name()) {
if list.ContainsAny(names, []string{flag.Name(), flag.String()}) {
continue
}
@@ -55,10 +65,12 @@ func (f CliFlags) Remove(names []string) (result CliFlags) {
func (f CliFlags) Replace(name string, replacement CliFlag) CliFlags {
done := false
for i, flag := range f {
if !done && flag.Name() == name {
f[i] = replacement
done = true
if name = firstName(name); name != "" {
for i, flag := range f {
if !done && flag.Name() == name {
f[i] = replacement
done = true
}
}
}
@@ -72,15 +84,16 @@ func (f CliFlags) Replace(name string, replacement CliFlag) CliFlags {
// Insert inserts command flags, if possible after the flag specified by name.
func (f CliFlags) Insert(name string, insert []CliFlag) (result CliFlags) {
result = make(CliFlags, 0, len(f)+len(insert))
done := false
for _, flag := range f {
result = append(result, flag)
if name = firstName(name); name != "" {
for _, flag := range f {
result = append(result, flag)
if !done && flag.Name() == name {
result = append(result, insert...)
done = true
if !done && flag.Name() == name {
result = append(result, insert...)
done = true
}
}
}
@@ -95,16 +108,17 @@ func (f CliFlags) Insert(name string, insert []CliFlag) (result CliFlags) {
// InsertBefore inserts command flags, if possible before the flag specified by name.
func (f CliFlags) InsertBefore(name string, insert []CliFlag) (result CliFlags) {
result = make(CliFlags, 0, len(f)+len(insert))
done := false
for _, flag := range f {
if !done && flag.Name() == name {
result = append(result, insert...)
done = true
}
if name = firstName(name); name != "" {
for _, flag := range f {
if !done && flag.Name() == name {
result = append(result, insert...)
done = true
}
result = append(result, flag)
result = append(result, flag)
}
}
if !done {

View File

@@ -4,7 +4,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
)
func TestCliFlags_Cli(t *testing.T) {
@@ -26,39 +26,42 @@ func TestCliFlags_Find(t *testing.T) {
}
func TestCliFlags_Replace(t *testing.T) {
originalPublicFlag := CliFlag{Flag: cli.BoolFlag{
Name: "public, p",
Hidden: true,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVar: EnvVar("PUBLIC"),
originalPublicFlag := CliFlag{Flag: &cli.BoolFlag{
Name: "public",
Aliases: []string{"p"},
Hidden: true,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVars: EnvVars("PUBLIC"),
}}
newPublicFlag := CliFlag{Flag: cli.BoolFlag{
Name: "public",
Hidden: false,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVar: EnvVar("PUBLIC"),
newPublicFlag := CliFlag{Flag: &cli.BoolFlag{
Name: "public",
Hidden: false,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVars: EnvVars("PUBLIC"),
}}
cliFlags := CliFlags{
{
Flag: cli.StringFlag{
Name: "auth-mode, a",
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVar: EnvVar("AUTH_MODE"),
Flag: &cli.StringFlag{
Name: "auth-mode",
Aliases: []string{"a"},
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVars: EnvVars("AUTH_MODE"),
}},
originalPublicFlag,
{
Flag: cli.StringFlag{
Name: "admin-user, login",
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVar: EnvVar("ADMIN_USER"),
Flag: &cli.StringFlag{
Name: "admin-user",
Aliases: []string{"login"},
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVars: EnvVars("ADMIN_USER"),
}}}
assert.Equal(t, 3, len(cliFlags))
assert.Equal(t, originalPublicFlag.Name(), cliFlags[1].Name())
assert.Equal(t, originalPublicFlag.String(), cliFlags[1].String())
assert.Equal(t, originalPublicFlag.Hidden(), cliFlags[1].Hidden())
t.Run("WrongName", func(t *testing.T) {
@@ -66,16 +69,16 @@ func TestCliFlags_Replace(t *testing.T) {
r := cliFlags.Replace("xxx", newPublicFlag)
assert.Equal(t, 3, len(r))
assert.Equal(t, "auth-mode, a", r[0].Name())
assert.Equal(t, originalPublicFlag.Name(), r[1].Name())
assert.Equal(t, "admin-user, login", r[2].Name())
assert.Equal(t, "auth-mode, a", r[0].String())
assert.Equal(t, originalPublicFlag.String(), r[1].String())
assert.Equal(t, "admin-user, login", r[2].String())
})
t.Run("Success", func(t *testing.T) {
r := cliFlags.Replace("public, p", newPublicFlag)
assert.Equal(t, 3, len(r))
assert.Equal(t, newPublicFlag.Name(), r[1].Name())
assert.Equal(t, newPublicFlag.String(), r[1].String())
assert.Equal(t, newPublicFlag.Hidden(), r[1].Hidden())
})
}
@@ -83,148 +86,161 @@ func TestCliFlags_Replace(t *testing.T) {
func TestCliFlags_Remove(t *testing.T) {
cliFlags := CliFlags{
{
Flag: cli.StringFlag{
Name: "auth-mode, a",
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVar: EnvVar("AUTH_MODE"),
Flag: &cli.StringFlag{
Name: "auth-mode",
Aliases: []string{"a"},
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVars: EnvVars("AUTH_MODE"),
}},
{
Flag: cli.StringFlag{
Name: "admin-user, login",
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVar: EnvVar("ADMIN_USER"),
Flag: &cli.StringFlag{
Name: "admin-user",
Aliases: []string{"login"},
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVars: EnvVars("ADMIN_USER"),
}}}
assert.Equal(t, 2, len(cliFlags))
r := cliFlags.Remove([]string{"auth-mode, a"})
result := cliFlags.Remove([]string{"auth-mode, a"})
assert.Equal(t, 1, len(r))
assert.Equal(t, 1, len(result))
}
func TestCliFlags_Insert(t *testing.T) {
PublicFlag := CliFlag{Flag: cli.BoolFlag{
Name: "public, p",
Hidden: true,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVar: EnvVar("PUBLIC"),
PublicFlag := CliFlag{Flag: &cli.BoolFlag{
Name: "public",
Aliases: []string{"p"},
Hidden: true,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVars: EnvVars("PUBLIC"),
}}
cliFlags := CliFlags{
{
Flag: cli.StringFlag{
Name: "auth-mode, a",
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVar: EnvVar("AUTH_MODE"),
Flag: &cli.StringFlag{
Name: "auth-mode",
Aliases: []string{"a"},
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVars: EnvVars("AUTH_MODE"),
}},
{
Flag: cli.StringFlag{
Name: "admin-user, login",
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVar: EnvVar("ADMIN_USER"),
Flag: &cli.StringFlag{
Name: "admin-user",
Aliases: []string{"login"},
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVars: EnvVars("ADMIN_USER"),
}}}
assert.Equal(t, 2, len(cliFlags))
t.Run("Success", func(t *testing.T) {
r := cliFlags.Insert("auth-mode, a", []CliFlag{PublicFlag})
result := cliFlags.Insert("auth-mode, a", []CliFlag{PublicFlag})
assert.Equal(t, 3, len(r))
assert.Equal(t, 3, len(result))
assert.Equal(t, "auth-mode, a", r[0].Name())
assert.Equal(t, PublicFlag.Name(), r[1].Name())
assert.Equal(t, "admin-user, login", r[2].Name())
assert.Equal(t, "auth-mode, a", result[0].String())
assert.Equal(t, PublicFlag.String(), result[1].String())
assert.Equal(t, "admin-user, login", result[2].String())
})
t.Run("WrongName", func(t *testing.T) {
r := cliFlags.Insert("xxx", []CliFlag{PublicFlag})
result := cliFlags.Insert("xxx", []CliFlag{PublicFlag})
assert.Equal(t, 3, len(r))
assert.Equal(t, 3, len(result))
assert.Equal(t, "auth-mode, a", r[0].Name())
assert.Equal(t, "admin-user, login", r[1].Name())
assert.Equal(t, PublicFlag.Name(), r[2].Name())
assert.Equal(t, "auth-mode, a", result[0].String())
assert.Equal(t, "admin-user, login", result[1].String())
assert.Equal(t, PublicFlag.String(), result[2].String())
})
}
func TestCliFlags_InsertBefore(t *testing.T) {
PublicFlag := CliFlag{Flag: cli.BoolFlag{
Name: "public, p",
Hidden: true,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVar: EnvVar("PUBLIC"),
PublicFlag := CliFlag{Flag: &cli.BoolFlag{
Name: "public",
Aliases: []string{"p"},
Hidden: true,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVars: EnvVars("PUBLIC"),
}}
cliFlags := CliFlags{
{
Flag: cli.StringFlag{
Name: "auth-mode, a",
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVar: EnvVar("AUTH_MODE"),
Flag: &cli.StringFlag{
Name: "auth-mode",
Aliases: []string{"a"},
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVars: EnvVars("AUTH_MODE"),
}},
{
Flag: cli.StringFlag{
Name: "admin-user, login",
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVar: EnvVar("ADMIN_USER"),
Flag: &cli.StringFlag{
Name: "admin-user",
Aliases: []string{"login"},
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVars: EnvVars("ADMIN_USER"),
}}}
assert.Equal(t, 2, len(cliFlags))
t.Run("Success", func(t *testing.T) {
r := cliFlags.InsertBefore("auth-mode, a", []CliFlag{PublicFlag})
result := cliFlags.InsertBefore("auth-mode, a", []CliFlag{PublicFlag})
assert.Equal(t, 3, len(r))
assert.Equal(t, 3, len(result))
assert.Equal(t, "auth-mode, a", r[1].Name())
assert.Equal(t, PublicFlag.Name(), r[0].Name())
assert.Equal(t, "admin-user, login", r[2].Name())
assert.Equal(t, "auth-mode, a", result[1].String())
assert.Equal(t, PublicFlag.String(), result[0].String())
assert.Equal(t, "admin-user, login", result[2].String())
})
t.Run("WrongName", func(t *testing.T) {
r := cliFlags.InsertBefore("xxx", []CliFlag{PublicFlag})
result := cliFlags.InsertBefore("xxx", []CliFlag{PublicFlag})
assert.Equal(t, 3, len(r))
assert.Equal(t, 3, len(result))
assert.Equal(t, "auth-mode, a", r[0].Name())
assert.Equal(t, "admin-user, login", r[1].Name())
assert.Equal(t, PublicFlag.Name(), r[2].Name())
t.Logf("flags: %#v", result)
assert.Equal(t, "auth-mode, a", result[0].String())
assert.Equal(t, "admin-user, login", result[1].String())
assert.Equal(t, PublicFlag.String(), result[2].String())
})
}
func TestCliFlags_Prepend(t *testing.T) {
PublicFlag := CliFlag{Flag: cli.BoolFlag{
Name: "public, p",
Hidden: true,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVar: EnvVar("PUBLIC"),
PublicFlag := CliFlag{Flag: &cli.BoolFlag{
Name: "public",
Aliases: []string{"p"},
Hidden: true,
Usage: "disable authentication, advanced settings, and WebDAV remote access",
EnvVars: EnvVars("PUBLIC"),
}}
cliFlags := CliFlags{
{
Flag: cli.StringFlag{
Name: "auth-mode, a",
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVar: EnvVar("AUTH_MODE"),
Flag: &cli.StringFlag{
Name: "auth-mode",
Aliases: []string{"a"},
Usage: "authentication `MODE` (public, password)",
Value: "password",
EnvVars: EnvVars("AUTH_MODE"),
}},
{
Flag: cli.StringFlag{
Name: "admin-user, login",
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVar: EnvVar("ADMIN_USER"),
Flag: &cli.StringFlag{
Name: "admin-user",
Aliases: []string{"login"},
Usage: "`USERNAME` of the superadmin account that is created on first startup",
Value: "admin",
EnvVars: EnvVars("ADMIN_USER"),
}}}
assert.Equal(t, 2, len(cliFlags))
r := cliFlags.Prepend([]CliFlag{PublicFlag})
assert.Equal(t, "auth-mode, a", r[1].Name())
assert.Equal(t, PublicFlag.Name(), r[0].Name())
assert.Equal(t, "admin-user, login", r[2].Name())
assert.Equal(t, "auth-mode, a", r[1].String())
assert.Equal(t, PublicFlag.String(), r[0].String())
assert.Equal(t, "admin-user, login", r[2].String())
}

View File

@@ -42,7 +42,7 @@ import (
"github.com/klauspost/cpuid/v2"
"github.com/pbnjay/memory"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/ai/face"
"github.com/photoprism/photoprism/internal/config/customize"
@@ -323,13 +323,13 @@ func (c *Config) CliContext() *cli.Context {
return c.cliCtx
}
// CliGlobalString returns a global cli string flag value if set.
func (c *Config) CliGlobalString(name string) string {
// CliContextString returns a global cli string flag value if set.
func (c *Config) CliContextString(name string) string {
if c.cliCtx == nil {
return ""
}
return c.cliCtx.GlobalString(name)
return c.cliCtx.String(name)
}
// readSerial reads and returns the current storage serial.

View File

@@ -145,7 +145,7 @@ func (c *Config) SitePreview() string {
// LegalInfo returns the legal info text for the page footer.
func (c *Config) LegalInfo() string {
if s := c.CliGlobalString("imprint"); s != "" {
if s := c.CliContextString("imprint"); s != "" {
log.Warnf("config: option 'imprint' is deprecated, please use 'legal-info'")
return s
}
@@ -155,7 +155,7 @@ func (c *Config) LegalInfo() string {
// LegalUrl returns the legal info url.
func (c *Config) LegalUrl() string {
if s := c.CliGlobalString("imprint-url"); s != "" {
if s := c.CliContextString("imprint-url"); s != "" {
log.Warnf("config: option 'imprint-url' is deprecated, please use 'legal-url'")
return s
}

View File

@@ -23,6 +23,17 @@ func EnvVar(flag string) string {
return "PHOTOPRISM_" + strings.ToUpper(strings.ReplaceAll(flag, "-", "_"))
}
// EnvVars returns the names of the environment variable for the specified config flag.
func EnvVars(flags ...string) (vars []string) {
vars = make([]string, len(flags))
for i, flag := range flags {
vars[i] = EnvVar(flag)
}
return vars
}
// Env checks the presence of environment and command-line flags.
func Env(vars ...string) bool {
for _, s := range vars {

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@ import (
"os"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v2"
"github.com/photoprism/photoprism/pkg/clean"
@@ -25,6 +25,7 @@ type Options struct {
PartnerID string `yaml:"-" json:"-" flag:"partner-id"`
AuthMode string `yaml:"AuthMode" json:"-" flag:"auth-mode"`
Public bool `yaml:"Public" json:"-" flag:"public"`
NoHub bool `yaml:"NoHub" json:"-" flag:"no-hub"`
AdminUser string `yaml:"AdminUser" json:"-" flag:"admin-user"`
AdminPassword string `yaml:"AdminPassword" json:"-" flag:"admin-password"`
PasswordLength int `yaml:"PasswordLength" json:"-" flag:"password-length"`
@@ -236,7 +237,7 @@ func NewOptions(ctx *cli.Context) *Options {
c.BackupAlbums = true
// Initialize options with the values from the "defaults.yml" file, if it exists.
if defaultsYaml := ctx.GlobalString("defaults-yaml"); defaultsYaml == "" {
if defaultsYaml := ctx.String("defaults-yaml"); defaultsYaml == "" {
log.Tracef("config: defaults file was not specified")
} else if c.DefaultsYaml = fs.Abs(defaultsYaml); !fs.FileExists(c.DefaultsYaml) {
log.Tracef("config: defaults file %s does not exist", clean.Log(c.DefaultsYaml))

View File

@@ -10,7 +10,7 @@ import (
"sync"
"time"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
_ "github.com/jinzhu/gorm/dialects/mysql"
_ "github.com/jinzhu/gorm/dialects/sqlite"
@@ -216,7 +216,7 @@ func NewTestContext(args []string) *cli.Context {
}
// Parse command arguments.
flags := flag.NewFlagSet("test", 0)
flags := flag.NewFlagSet("test", flag.ContinueOnError)
LogErr(flags.Parse(args))
// Create and return new context.
@@ -227,7 +227,7 @@ func NewTestContext(args []string) *cli.Context {
func CliTestContext() *cli.Context {
config := NewTestOptions("config-cli")
globalSet := flag.NewFlagSet("test", 0)
globalSet := flag.NewFlagSet("test", flag.ContinueOnError)
globalSet.String("config-path", config.ConfigPath, "doc")
globalSet.String("admin-password", config.DarktableBin, "doc")
globalSet.String("oidc-uri", config.OIDCUri, "doc")

View File

@@ -6,7 +6,7 @@ import (
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
)
func TestConfig_TestdataPath2(t *testing.T) {

View File

@@ -2,7 +2,7 @@ package entity
import (
"github.com/photoprism/photoprism/pkg/authn"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/pkg/clean"

View File

@@ -1,7 +1,7 @@
package form
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/photoprism/photoprism/internal/auth/acl"
"github.com/photoprism/photoprism/pkg/authn"

Some files were not shown because too many files have changed in this diff Show More