refactor: urfave v3
This commit is contained in:
parent
375e17a4a0
commit
1f8662cd95
@ -1,15 +1,15 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AppCommand = cli.Command{
|
var AppCommand = cli.Command{
|
||||||
Name: "app",
|
Name: "app",
|
||||||
Aliases: []string{"a"},
|
Aliases: []string{"a"},
|
||||||
Usage: "Manage apps",
|
Usage: "Manage apps",
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app [command] [options] [arguments]",
|
||||||
Subcommands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&appBackupCommand,
|
&appBackupCommand,
|
||||||
&appCheckCommand,
|
&appCheckCommand,
|
||||||
&appCmdCommand,
|
&appCmdCommand,
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var snapshot string
|
var snapshot string
|
||||||
@ -38,16 +39,16 @@ var appBackupListCommand = cli.Command{
|
|||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
snapshotFlag,
|
snapshotFlag,
|
||||||
includePathFlag,
|
includePathFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Usage: "List all backups",
|
Usage: "List all backups",
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
UsageText: "abra app backup list <domain> [options]",
|
||||||
Action: func(c *cli.Context) error {
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
app := internal.ValidateApp(c)
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -85,16 +86,16 @@ var appBackupDownloadCommand = cli.Command{
|
|||||||
Name: "download",
|
Name: "download",
|
||||||
Aliases: []string{"d"},
|
Aliases: []string{"d"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
snapshotFlag,
|
snapshotFlag,
|
||||||
includePathFlag,
|
includePathFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Usage: "Download a backup",
|
Usage: "Download a backup",
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
UsageText: "abra app backup download <domain> [options]",
|
||||||
Action: func(c *cli.Context) error {
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
app := internal.ValidateApp(c)
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if err := app.Recipe.EnsureExists(); err != nil {
|
if err := app.Recipe.EnsureExists(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -156,15 +157,15 @@ var appBackupCreateCommand = cli.Command{
|
|||||||
Name: "create",
|
Name: "create",
|
||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
resticRepoFlag,
|
resticRepoFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Usage: "Create a new backup",
|
Usage: "Create a new backup",
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
UsageText: "abra app backup create <domain> [options]",
|
||||||
Action: func(c *cli.Context) error {
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
app := internal.ValidateApp(c)
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if err := app.Recipe.EnsureExists(); err != nil {
|
if err := app.Recipe.EnsureExists(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -214,15 +215,15 @@ var appBackupSnapshotsCommand = cli.Command{
|
|||||||
Name: "snapshots",
|
Name: "snapshots",
|
||||||
Aliases: []string{"s"},
|
Aliases: []string{"s"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
snapshotFlag,
|
snapshotFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Usage: "List backup snapshots",
|
Usage: "List backup snapshots",
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
UsageText: "abra app backup snapshots <domain> [options]",
|
||||||
Action: func(c *cli.Context) error {
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
app := internal.ValidateApp(c)
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if err := app.Recipe.EnsureExists(); err != nil {
|
if err := app.Recipe.EnsureExists(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -272,8 +273,8 @@ var appBackupCommand = cli.Command{
|
|||||||
Name: "backup",
|
Name: "backup",
|
||||||
Aliases: []string{"b"},
|
Aliases: []string{"b"},
|
||||||
Usage: "Manage app backups",
|
Usage: "Manage app backups",
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app backup [command] [arguments] [options]",
|
||||||
Subcommands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&appBackupListCommand,
|
&appBackupListCommand,
|
||||||
&appBackupSnapshotsCommand,
|
&appBackupSnapshotsCommand,
|
||||||
&appBackupDownloadCommand,
|
&appBackupDownloadCommand,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
@ -9,16 +10,15 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appCheckCommand = cli.Command{
|
var appCheckCommand = cli.Command{
|
||||||
Name: "check",
|
Name: "check",
|
||||||
Aliases: []string{"chk"},
|
Aliases: []string{"chk"},
|
||||||
Usage: "Ensure an app is well configured",
|
UsageText: "abra app check <domain> [options]",
|
||||||
Description: `
|
Usage: "Ensure an app is well configured",
|
||||||
This command compares env vars in both the app ".env" and recipe ".env.sample"
|
Description: `Compare env vars in both the app ".env" and recipe ".env.sample" file.
|
||||||
file.
|
|
||||||
|
|
||||||
The goal is to ensure that recipe ".env.sample" env vars are defined in your
|
The goal is to ensure that recipe ".env.sample" env vars are defined in your
|
||||||
app ".env" file. Only env var definitions in the ".env.sample" which are
|
app ".env" file. Only env var definitions in the ".env.sample" which are
|
||||||
@ -28,16 +28,15 @@ these env vars, then "check" will complain.
|
|||||||
Recipe maintainers may or may not provide defaults for env vars within their
|
Recipe maintainers may or may not provide defaults for env vars within their
|
||||||
recipes regardless of commenting or not (e.g. through the use of
|
recipes regardless of commenting or not (e.g. through the use of
|
||||||
${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
|
${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
|
||||||
ArgsUsage: "<domain>",
|
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
internal.OfflineFlag,
|
internal.OfflineFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -14,61 +15,53 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appCmdCommand = cli.Command{
|
var appCmdCommand = cli.Command{
|
||||||
Name: "command",
|
Name: "command",
|
||||||
Aliases: []string{"cmd"},
|
Aliases: []string{"cmd"},
|
||||||
Usage: "Run app commands",
|
Usage: "Run app commands",
|
||||||
|
UsageText: "abra app cmd <domain> [<service>] <cmd> [<cmd-args>] [options]",
|
||||||
Description: `Run an app specific command.
|
Description: `Run an app specific command.
|
||||||
|
|
||||||
These commands are bash functions, defined in the abra.sh of the recipe itself.
|
These commands are bash functions, defined in the abra.sh of the recipe itself.
|
||||||
They can be run within the context of a service (e.g. app) or locally on your
|
They can be run within the context of a service (e.g. app) or locally on your
|
||||||
work station by passing "--local". Arguments can be passed into these functions
|
work station by passing "--local".`,
|
||||||
using the "-- <args>" syntax.
|
|
||||||
|
|
||||||
**WARNING**: options must be passed directly after the sub-command "cmd".
|
|
||||||
|
|
||||||
EXAMPLE:
|
|
||||||
|
|
||||||
abra app cmd --local example.com app create_user -- me@example.com`,
|
|
||||||
ArgsUsage: "<domain> [<service>] <command> [-- <args>]",
|
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.LocalCmdFlag,
|
internal.LocalCmdFlag,
|
||||||
internal.RemoteUserFlag,
|
internal.RemoteUserFlag,
|
||||||
internal.TtyFlag,
|
internal.TtyFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Subcommands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&appCmdListCommand,
|
&appCmdListCommand,
|
||||||
},
|
},
|
||||||
BashComplete: func(ctx *cli.Context) {
|
ShellComplete: func(ctx context.Context, cmd *cli.Command) {
|
||||||
args := ctx.Args()
|
args := cmd.Args()
|
||||||
switch args.Len() {
|
switch args.Len() {
|
||||||
case 0:
|
case 0:
|
||||||
autocomplete.AppNameComplete(ctx)
|
autocomplete.AppNameComplete(ctx, cmd)
|
||||||
case 1:
|
case 1:
|
||||||
autocomplete.ServiceNameComplete(args.Get(0))
|
autocomplete.ServiceNameComplete(args.Get(0))
|
||||||
case 2:
|
case 2:
|
||||||
cmdNameComplete(args.Get(0))
|
cmdNameComplete(args.Get(0))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if internal.LocalCmd && internal.RemoteUser != "" {
|
if internal.LocalCmd && internal.RemoteUser != "" {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("cannot use --local & --user together"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("cannot use --local & --user together"))
|
||||||
}
|
}
|
||||||
|
|
||||||
hasCmdArgs, parsedCmdArgs := parseCmdArgs(c.Args().Slice(), internal.LocalCmd)
|
hasCmdArgs, parsedCmdArgs := parseCmdArgs(cmd.Args().Slice(), internal.LocalCmd)
|
||||||
|
|
||||||
if _, err := os.Stat(app.Recipe.AbraShPath); err != nil {
|
if _, err := os.Stat(app.Recipe.AbraShPath); err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
@ -78,11 +71,11 @@ EXAMPLE:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if internal.LocalCmd {
|
if internal.LocalCmd {
|
||||||
if !(c.Args().Len() >= 2) {
|
if !(cmd.Args().Len() >= 2) {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments"))
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdName := c.Args().Get(1)
|
cmdName := cmd.Args().Get(1)
|
||||||
if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil {
|
if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -114,13 +107,13 @@ EXAMPLE:
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !(c.Args().Len() >= 3) {
|
if !(cmd.Args().Len() >= 3) {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments"))
|
||||||
}
|
}
|
||||||
|
|
||||||
targetServiceName := c.Args().Get(1)
|
targetServiceName := cmd.Args().Get(1)
|
||||||
|
|
||||||
cmdName := c.Args().Get(2)
|
cmdName := cmd.Args().Get(2)
|
||||||
if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil {
|
if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -200,16 +193,16 @@ var appCmdListCommand = cli.Command{
|
|||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List all available commands",
|
Usage: "List all available commands",
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app cmd ls <domain> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
},
|
},
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
|
r := recipe.Get(app.Recipe.Name)
|
||||||
|
|
||||||
if err := app.Recipe.EnsureExists(); err != nil {
|
if err := app.Recipe.EnsureExists(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -10,24 +11,22 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appConfigCommand = cli.Command{
|
var appConfigCommand = cli.Command{
|
||||||
Name: "config",
|
Name: "config",
|
||||||
Aliases: []string{"cfg"},
|
Aliases: []string{"cfg"},
|
||||||
Usage: "Edit app config",
|
Usage: "Edit app config",
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app config <domain> [options]",
|
||||||
Flags: []cli.Flag{
|
Before: internal.SubCommandBefore,
|
||||||
internal.DebugFlag,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
},
|
HideHelp: true,
|
||||||
Before: internal.SubCommandBefore,
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
appName := cmd.Args().First()
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
appName := c.Args().First()
|
|
||||||
|
|
||||||
if appName == "" {
|
if appName == "" {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no app provided"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("no app provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
files, err := appPkg.LoadAppFiles("")
|
files, err := appPkg.LoadAppFiles("")
|
||||||
@ -51,11 +50,11 @@ var appConfigCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command(ed, appFile.Path)
|
c := exec.Command(ed, appFile.Path)
|
||||||
cmd.Stdin = os.Stdin
|
c.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
c.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
c.Stderr = os.Stderr
|
||||||
if err := cmd.Run(); err != nil {
|
if err := c.Run(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,21 +22,16 @@ import (
|
|||||||
dockerClient "github.com/docker/docker/client"
|
dockerClient "github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appCpCommand = cli.Command{
|
var appCpCommand = cli.Command{
|
||||||
Name: "cp",
|
Name: "cp",
|
||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
ArgsUsage: "<domain> <src> <dst>",
|
Before: internal.SubCommandBefore,
|
||||||
Flags: []cli.Flag{
|
Usage: "Copy files to/from a deployed app service",
|
||||||
internal.DebugFlag,
|
UsageText: "abra app cp <domain> <src> <dst> [options]",
|
||||||
internal.NoInputFlag,
|
Description: `Copy files to and from any app service file system.
|
||||||
},
|
|
||||||
Before: internal.SubCommandBefore,
|
|
||||||
Usage: "Copy files to/from a deployed app service",
|
|
||||||
Description: `
|
|
||||||
Copy files to and from any app service file system.
|
|
||||||
|
|
||||||
If you want to copy a myfile.txt to the root of the app service:
|
If you want to copy a myfile.txt to the root of the app service:
|
||||||
|
|
||||||
@ -44,18 +39,17 @@ If you want to copy a myfile.txt to the root of the app service:
|
|||||||
|
|
||||||
And if you want to copy that file back to your current working directory locally:
|
And if you want to copy that file back to your current working directory locally:
|
||||||
|
|
||||||
abra app cp <domain> app:/myfile.txt .
|
abra app cp <domain> app:/myfile.txt`,
|
||||||
`,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
HideHelp: true,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
src := c.Args().Get(1)
|
src := cmd.Args().Get(1)
|
||||||
dst := c.Args().Get(2)
|
dst := cmd.Args().Get(2)
|
||||||
if src == "" {
|
if src == "" {
|
||||||
log.Fatal("missing <src> argument")
|
log.Fatal("missing <src> argument")
|
||||||
}
|
}
|
||||||
|
@ -17,22 +17,19 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/lint"
|
"coopcloud.tech/abra/pkg/lint"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appDeployCommand = cli.Command{
|
var appDeployCommand = cli.Command{
|
||||||
Name: "deploy",
|
Name: "deploy",
|
||||||
Aliases: []string{"d"},
|
Aliases: []string{"d"},
|
||||||
Usage: "Deploy an app",
|
Usage: "Deploy an app",
|
||||||
ArgsUsage: "<domain> [<version>]",
|
UsageText: "abra app deploy <domain> [<version>] [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.ForceFlag,
|
internal.ForceFlag,
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
internal.NoDomainChecksFlag,
|
internal.NoDomainChecksFlag,
|
||||||
internal.DontWaitConvergeFlag,
|
internal.DontWaitConvergeFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Description: `Deploy an app.
|
Description: `Deploy an app.
|
||||||
@ -40,21 +37,20 @@ var appDeployCommand = cli.Command{
|
|||||||
This command supports chaos operations. Use "--chaos" to deploy your recipe
|
This command supports chaos operations. Use "--chaos" to deploy your recipe
|
||||||
checkout as-is. Recipe commit hashes are also supported values for
|
checkout as-is. Recipe commit hashes are also supported values for
|
||||||
"[<version>]". Please note, "upgrade"/"rollback" do not support chaos
|
"[<version>]". Please note, "upgrade"/"rollback" do not support chaos
|
||||||
operations.
|
operations.`,
|
||||||
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
EXAMPLE:
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
abra app deploy foo.example.com
|
|
||||||
abra app deploy foo.example.com 1.2.3+3.2.1
|
|
||||||
abra app deploy foo.example.com 1e83340e`,
|
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
var warnMessages []string
|
var warnMessages []string
|
||||||
|
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(cmd)
|
||||||
stackName := app.StackName()
|
stackName := app.StackName()
|
||||||
|
|
||||||
specificVersion := c.Args().Get(1)
|
specificVersion := cmd.Args().Get(1)
|
||||||
|
if specificVersion == "" {
|
||||||
|
specificVersion = app.Recipe.Version
|
||||||
|
}
|
||||||
|
|
||||||
if specificVersion != "" && internal.Chaos {
|
if specificVersion != "" && internal.Chaos {
|
||||||
log.Fatal("cannot use <version> and --chaos together")
|
log.Fatal("cannot use <version> and --chaos together")
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
@ -12,7 +13,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/tagcmp"
|
"coopcloud.tech/tagcmp"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -70,26 +71,24 @@ type serverStatus struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var appListCommand = cli.Command{
|
var appListCommand = cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List all managed apps",
|
Usage: "List all managed apps",
|
||||||
Description: `
|
UsageText: "abra app list [options]",
|
||||||
Read the local file system listing of apps and servers (e.g. ~/.abra/) to
|
Description: `Generate a report of all managed apps.
|
||||||
generate a report of all your apps.
|
|
||||||
|
|
||||||
By passing the "--status/-S" flag, you can query all your servers for the
|
By passing the "--status/-S" flag, you can query all your servers for the
|
||||||
actual live deployment status. Depending on how many servers you manage, this
|
actual live deployment status. Depending on how many servers you manage, this
|
||||||
can take some time.`,
|
can take some time.`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.MachineReadableFlag,
|
internal.MachineReadableFlag,
|
||||||
statusFlag,
|
statusFlag,
|
||||||
listAppServerFlag,
|
listAppServerFlag,
|
||||||
recipeFlag,
|
recipeFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
appFiles, err := appPkg.LoadAppFiles(listAppServer)
|
appFiles, err := appPkg.LoadAppFiles(listAppServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -19,23 +19,23 @@ import (
|
|||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
dockerClient "github.com/docker/docker/client"
|
dockerClient "github.com/docker/docker/client"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appLogsCommand = cli.Command{
|
var appLogsCommand = cli.Command{
|
||||||
Name: "logs",
|
Name: "logs",
|
||||||
Aliases: []string{"l"},
|
Aliases: []string{"l"},
|
||||||
ArgsUsage: "<domain> [<service>]",
|
|
||||||
Usage: "Tail app logs",
|
Usage: "Tail app logs",
|
||||||
|
UsageText: "abra app logs <domain> [<service>] [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.StdErrOnlyFlag,
|
internal.StdErrOnlyFlag,
|
||||||
internal.SinceLogsFlag,
|
internal.SinceLogsFlag,
|
||||||
internal.DebugFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
stackName := app.StackName()
|
stackName := app.StackName()
|
||||||
|
|
||||||
if err := app.Recipe.EnsureExists(); err != nil {
|
if err := app.Recipe.EnsureExists(); err != nil {
|
||||||
@ -56,7 +56,7 @@ var appLogsCommand = cli.Command{
|
|||||||
log.Fatalf("%s is not deployed?", app.Name)
|
log.Fatalf("%s is not deployed?", app.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceName := c.Args().Get(1)
|
serviceName := cmd.Args().Get(1)
|
||||||
serviceNames := []string{}
|
serviceNames := []string{}
|
||||||
if serviceName != "" {
|
if serviceName != "" {
|
||||||
serviceNames = []string{serviceName}
|
serviceNames = []string{serviceName}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
@ -16,12 +17,13 @@ import (
|
|||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/charmbracelet/lipgloss/table"
|
"github.com/charmbracelet/lipgloss/table"
|
||||||
dockerClient "github.com/docker/docker/client"
|
dockerClient "github.com/docker/docker/client"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appNewDescription = `
|
var appNewDescription = `Creates a new app from a default recipe.
|
||||||
Creates a new app from a default recipe. This new app configuration is stored
|
|
||||||
in your $ABRA_DIR directory under the appropriate server.
|
This new app configuration is stored in your $ABRA_DIR directory under the
|
||||||
|
appropriate server.
|
||||||
|
|
||||||
This command does not deploy your app for you. You will need to run "abra app
|
This command does not deploy your app for you. You will need to run "abra app
|
||||||
deploy <domain>" to do so.
|
deploy <domain>" to do so.
|
||||||
@ -44,30 +46,28 @@ var appNewCommand = cli.Command{
|
|||||||
Name: "new",
|
Name: "new",
|
||||||
Aliases: []string{"n"},
|
Aliases: []string{"n"},
|
||||||
Usage: "Create a new app",
|
Usage: "Create a new app",
|
||||||
|
UsageText: "abra app new [<recipe>] [<version>] [options]",
|
||||||
Description: appNewDescription,
|
Description: appNewDescription,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.NewAppServerFlag,
|
internal.NewAppServerFlag,
|
||||||
internal.DomainFlag,
|
internal.DomainFlag,
|
||||||
internal.PassFlag,
|
internal.PassFlag,
|
||||||
internal.SecretsFlag,
|
internal.SecretsFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
ArgsUsage: "[<recipe>] [<version>]",
|
HideHelp: true,
|
||||||
BashComplete: func(ctx *cli.Context) {
|
ShellComplete: func(ctx context.Context, cmd *cli.Command) {
|
||||||
args := ctx.Args()
|
args := cmd.Args()
|
||||||
switch args.Len() {
|
switch args.Len() {
|
||||||
case 0:
|
case 0:
|
||||||
autocomplete.RecipeNameComplete(ctx)
|
autocomplete.RecipeNameComplete(ctx, cmd)
|
||||||
case 1:
|
case 1:
|
||||||
autocomplete.RecipeVersionComplete(ctx.Args().Get(0))
|
autocomplete.RecipeVersionComplete(cmd.Args().Get(0))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
recipe := internal.ValidateRecipe(c)
|
recipe := internal.ValidateRecipe(cmd)
|
||||||
|
|
||||||
var version string
|
var version string
|
||||||
if !internal.Chaos {
|
if !internal.Chaos {
|
||||||
@ -80,7 +80,7 @@ var appNewCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Args().Get(1) == "" {
|
if cmd.Args().Get(1) == "" {
|
||||||
recipeVersions, err := recipe.GetRecipeVersions()
|
recipeVersions, err := recipe.GetRecipeVersions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -101,7 +101,7 @@ var appNewCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
version = c.Args().Get(1)
|
version = cmd.Args().Get(1)
|
||||||
if _, err := recipe.EnsureVersion(version); err != nil {
|
if _, err := recipe.EnsureVersion(version); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -18,25 +18,25 @@ import (
|
|||||||
containerTypes "github.com/docker/docker/api/types/container"
|
containerTypes "github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
dockerClient "github.com/docker/docker/client"
|
dockerClient "github.com/docker/docker/client"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appPsCommand = cli.Command{
|
var appPsCommand = cli.Command{
|
||||||
Name: "ps",
|
Name: "ps",
|
||||||
Aliases: []string{"p"},
|
Aliases: []string{"p"},
|
||||||
Usage: "Check app status",
|
Usage: "Check app status",
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app ps <domain> [options]",
|
||||||
Description: "Show status of a deployed app.",
|
Description: "Show status of a deployed app.",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.MachineReadableFlag,
|
internal.MachineReadableFlag,
|
||||||
internal.DebugFlag,
|
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
internal.OfflineFlag,
|
internal.OfflineFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -12,16 +12,15 @@ import (
|
|||||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appRemoveCommand = cli.Command{
|
var appRemoveCommand = cli.Command{
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
Aliases: []string{"rm"},
|
Aliases: []string{"rm"},
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app remove <domain> [options]",
|
||||||
Usage: "Remove all app data, locally and remotely",
|
Usage: "Remove all app data, locally and remotely",
|
||||||
Description: `
|
Description: `Remove everything related to an app which is already undeployed.
|
||||||
This command removes everything related to an app which is already undeployed.
|
|
||||||
|
|
||||||
By default, it will prompt for confirmation before proceeding. All secrets,
|
By default, it will prompt for confirmation before proceeding. All secrets,
|
||||||
volumes and the local app env file will be deleted.
|
volumes and the local app env file will be deleted.
|
||||||
@ -39,14 +38,12 @@ To delete everything without prompt, use the "--force/-f" or the "--no-input/n"
|
|||||||
flag.`,
|
flag.`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.ForceFlag,
|
internal.ForceFlag,
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if !internal.Force && !internal.NoInput {
|
if !internal.Force && !internal.NoInput {
|
||||||
log.Warnf("ALERTA ALERTA: this will completely remove %s data and config locally and remotely", app.Name)
|
log.Warnf("ALERTA ALERTA: this will completely remove %s data and config locally and remotely", app.Name)
|
||||||
|
@ -12,41 +12,35 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
upstream "coopcloud.tech/abra/pkg/upstream/service"
|
upstream "coopcloud.tech/abra/pkg/upstream/service"
|
||||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appRestartCommand = cli.Command{
|
var appRestartCommand = cli.Command{
|
||||||
Name: "restart",
|
Name: "restart",
|
||||||
Aliases: []string{"re"},
|
Aliases: []string{"re"},
|
||||||
Usage: "Restart an app",
|
Usage: "Restart an app",
|
||||||
ArgsUsage: "<domain> [<service>]",
|
UsageText: "abra app restart <domain> [<service>] [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.AllServicesFlag,
|
internal.AllServicesFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Description: `
|
Description: `This command restarts services within a deployed app.
|
||||||
This command restarts services within a deployed app.
|
|
||||||
|
|
||||||
Run "abra app ps <domain>" to see a list of service names.
|
Run "abra app ps <domain>" to see a list of service names.
|
||||||
|
|
||||||
Pass "--all-services/-a" to restart all services.
|
Pass "--all-services/-a" to restart all services.`,
|
||||||
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
EXAMPLE:
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
abra app restart example.com app`,
|
app := internal.ValidateApp(cmd)
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
app := internal.ValidateApp(c)
|
|
||||||
if err := app.Recipe.Ensure(false, false); err != nil {
|
if err := app.Recipe.Ensure(false, false); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceName := c.Args().Get(1)
|
serviceName := cmd.Args().Get(1)
|
||||||
if serviceName == "" && !internal.AllServices {
|
if serviceName == "" && !internal.AllServices {
|
||||||
err := errors.New("missing <service>")
|
err := errors.New("missing <service>")
|
||||||
internal.ShowSubcommandHelpAndError(c, err)
|
internal.ShowSubcommandHelpAndError(cmd, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if serviceName != "" && internal.AllServices {
|
if serviceName != "" && internal.AllServices {
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var targetPath string
|
var targetPath string
|
||||||
@ -22,16 +23,15 @@ var appRestoreCommand = cli.Command{
|
|||||||
Name: "restore",
|
Name: "restore",
|
||||||
Aliases: []string{"rs"},
|
Aliases: []string{"rs"},
|
||||||
Usage: "Restore an app backup",
|
Usage: "Restore an app backup",
|
||||||
ArgsUsage: "<domain> <service>",
|
UsageText: "abra app restore <domain> <service> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
targetPathFlag,
|
targetPathFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -16,44 +16,36 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appRollbackCommand = cli.Command{
|
var appRollbackCommand = cli.Command{
|
||||||
Name: "rollback",
|
Name: "rollback",
|
||||||
Aliases: []string{"rl"},
|
Aliases: []string{"rl"},
|
||||||
Usage: "Roll an app back to a previous version",
|
Usage: "Roll an app back to a previous version",
|
||||||
ArgsUsage: "<domain> [<version>]",
|
UsageText: "abra app rollback <domain> [<version>] [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.ForceFlag,
|
internal.ForceFlag,
|
||||||
internal.NoDomainChecksFlag,
|
internal.NoDomainChecksFlag,
|
||||||
internal.DontWaitConvergeFlag,
|
internal.DontWaitConvergeFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Description: `
|
Description: `This command rolls an app back to a previous version.
|
||||||
This command rolls an app back to a previous version.
|
|
||||||
|
|
||||||
Unlike "deploy", chaos operations are not supported here. Only recipe versions
|
Unlike "deploy", chaos operations are not supported here. Only recipe versions
|
||||||
are supported values for "[<version>]".
|
are supported values for "[<version>]".
|
||||||
|
|
||||||
A rollback can be destructive, please ensure you have a copy of your app data
|
A rollback can be destructive, please ensure you have a copy of your app data
|
||||||
beforehand.
|
beforehand.`,
|
||||||
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
EXAMPLE:
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
abra app rollback foo.example.com
|
|
||||||
abra app rollback foo.example.com 1.2.3+3.2.1`,
|
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
var warnMessages []string
|
var warnMessages []string
|
||||||
|
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(cmd)
|
||||||
stackName := app.StackName()
|
stackName := app.StackName()
|
||||||
|
|
||||||
specificVersion := c.Args().Get(1)
|
specificVersion := cmd.Args().Get(1)
|
||||||
if specificVersion != "" {
|
if specificVersion != "" {
|
||||||
log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion)
|
log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion)
|
||||||
app.Recipe.Version = specificVersion
|
app.Recipe.Version = specificVersion
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var user string
|
var user string
|
||||||
@ -36,23 +36,23 @@ var appRunCommand = cli.Command{
|
|||||||
Name: "run",
|
Name: "run",
|
||||||
Aliases: []string{"r"},
|
Aliases: []string{"r"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
noTTYFlag,
|
noTTYFlag,
|
||||||
userFlag,
|
userFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
ArgsUsage: "<domain> <service> <args>...",
|
Usage: "Run a command in an app service",
|
||||||
Usage: "Run a command in a service container",
|
UsageText: "abra app run <domain> <service> <args> [options]",
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
if c.Args().Len() < 2 {
|
if cmd.Args().Len() < 2 {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no <service> provided?"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("no <service> provided?"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Args().Len() < 3 {
|
if cmd.Args().Len() < 3 {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no <args> provided?"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("no <args> provided?"))
|
||||||
}
|
}
|
||||||
|
|
||||||
cl, err := client.New(app.Server)
|
cl, err := client.New(app.Server)
|
||||||
@ -60,7 +60,7 @@ var appRunCommand = cli.Command{
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceName := c.Args().Get(1)
|
serviceName := cmd.Args().Get(1)
|
||||||
stackAndServiceName := fmt.Sprintf("^%s_%s", app.StackName(), serviceName)
|
stackAndServiceName := fmt.Sprintf("^%s_%s", app.StackName(), serviceName)
|
||||||
filters := filters.NewArgs()
|
filters := filters.NewArgs()
|
||||||
filters.Add("name", stackAndServiceName)
|
filters.Add("name", stackAndServiceName)
|
||||||
@ -70,12 +70,12 @@ var appRunCommand = cli.Command{
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := c.Args().Slice()[2:]
|
c := cmd.Args().Slice()[2:]
|
||||||
execCreateOpts := types.ExecConfig{
|
execCreateOpts := types.ExecConfig{
|
||||||
AttachStderr: true,
|
AttachStderr: true,
|
||||||
AttachStdin: true,
|
AttachStdin: true,
|
||||||
AttachStdout: true,
|
AttachStdout: true,
|
||||||
Cmd: cmd,
|
Cmd: c,
|
||||||
Detach: false,
|
Detach: false,
|
||||||
Tty: true,
|
Tty: true,
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/secret"
|
"coopcloud.tech/abra/pkg/secret"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
dockerClient "github.com/docker/docker/client"
|
dockerClient "github.com/docker/docker/client"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -44,31 +44,30 @@ var appSecretGenerateCommand = cli.Command{
|
|||||||
Name: "generate",
|
Name: "generate",
|
||||||
Aliases: []string{"g"},
|
Aliases: []string{"g"},
|
||||||
Usage: "Generate secrets",
|
Usage: "Generate secrets",
|
||||||
ArgsUsage: "<domain> <secret> <version>",
|
UsageText: "abra app secret generate <domain> <secret> <version> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
allSecretsFlag,
|
allSecretsFlag,
|
||||||
internal.PassFlag,
|
internal.PassFlag,
|
||||||
internal.MachineReadableFlag,
|
internal.MachineReadableFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Args().Len() == 1 && !allSecrets {
|
if cmd.Args().Len() == 1 && !allSecrets {
|
||||||
err := errors.New("missing arguments <secret>/<version> or '--all'")
|
err := errors.New("missing arguments <secret>/<version> or '--all'")
|
||||||
internal.ShowSubcommandHelpAndError(c, err)
|
internal.ShowSubcommandHelpAndError(cmd, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Args().Get(1) != "" && allSecrets {
|
if cmd.Args().Get(1) != "" && allSecrets {
|
||||||
err := errors.New("cannot use '<secret> <version>' and '--all' together")
|
err := errors.New("cannot use '<secret> <version>' and '--all' together")
|
||||||
internal.ShowSubcommandHelpAndError(c, err)
|
internal.ShowSubcommandHelpAndError(cmd, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
composeFiles, err := app.Recipe.GetComposeFiles(app.Env)
|
composeFiles, err := app.Recipe.GetComposeFiles(app.Env)
|
||||||
@ -82,8 +81,8 @@ var appSecretGenerateCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !allSecrets {
|
if !allSecrets {
|
||||||
secretName := c.Args().Get(1)
|
secretName := cmd.Args().Get(1)
|
||||||
secretVersion := c.Args().Get(2)
|
secretVersion := cmd.Args().Get(2)
|
||||||
s, ok := secrets[secretName]
|
s, ok := secrets[secretName]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Fatalf("%s doesn't exist in the env config?", secretName)
|
log.Fatalf("%s doesn't exist in the env config?", secretName)
|
||||||
@ -154,39 +153,32 @@ var appSecretGenerateCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var appSecretInsertCommand = cli.Command{
|
var appSecretInsertCommand = cli.Command{
|
||||||
Name: "insert",
|
Name: "insert",
|
||||||
Aliases: []string{"i"},
|
Aliases: []string{"i"},
|
||||||
Usage: "Insert secret",
|
Usage: "Insert secret",
|
||||||
|
UsageText: "abra app secret insert <domain> <secret> <version> <data> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.PassFlag,
|
internal.PassFlag,
|
||||||
internal.FileFlag,
|
internal.FileFlag,
|
||||||
internal.TrimFlag,
|
internal.TrimFlag,
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
ArgsUsage: "<domain> <secret-name> <version> <data>",
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
HideHelpCommand: true,
|
||||||
Description: `
|
Description: `This command inserts a secret into an app environment.
|
||||||
This command inserts a secret into an app environment.
|
|
||||||
|
|
||||||
This can be useful when you want to manually generate secrets for an app
|
This can be useful when you want to manually generate secrets for an app
|
||||||
environment. Typically, you can let Abra generate them for you on app creation
|
environment. Typically, you can let Abra generate them for you on app creation
|
||||||
(see "abra app new --secrets" for more).
|
(see "abra app new --secrets" for more).`,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
Example:
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
abra app secret insert myapp db_pass v1 mySecretPassword
|
|
||||||
|
|
||||||
`,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
app := internal.ValidateApp(c)
|
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Args().Len() != 4 {
|
if cmd.Args().Len() != 4 {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments?"))
|
||||||
}
|
}
|
||||||
|
|
||||||
cl, err := client.New(app.Server)
|
cl, err := client.New(app.Server)
|
||||||
@ -194,9 +186,9 @@ Example:
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
name := c.Args().Get(1)
|
name := cmd.Args().Get(1)
|
||||||
version := c.Args().Get(2)
|
version := cmd.Args().Get(2)
|
||||||
data := c.Args().Get(3)
|
data := cmd.Args().Get(3)
|
||||||
|
|
||||||
if internal.File {
|
if internal.File {
|
||||||
raw, err := os.ReadFile(data)
|
raw, err := os.ReadFile(data)
|
||||||
@ -247,29 +239,28 @@ func secretRm(cl *dockerClient.Client, app appPkg.App, secretName, parsed string
|
|||||||
}
|
}
|
||||||
|
|
||||||
var appSecretRmCommand = cli.Command{
|
var appSecretRmCommand = cli.Command{
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
Aliases: []string{"rm"},
|
Aliases: []string{"rm"},
|
||||||
Usage: "Remove a secret",
|
Usage: "Remove a secret",
|
||||||
|
UsageText: "abra app remove <domainabra app remove <domain> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
internal.NoInputFlag,
|
||||||
rmAllSecretsFlag,
|
rmAllSecretsFlag,
|
||||||
internal.PassRemoveFlag,
|
internal.PassRemoveFlag,
|
||||||
internal.OfflineFlag,
|
internal.OfflineFlag,
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
ArgsUsage: "<domain> [<secret-name>]",
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
|
||||||
Description: `
|
Description: `
|
||||||
This command removes app secrets.
|
This command removes app secrets.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
abra app secret remove myapp db_pass
|
abra app secret remove myapp db_pass`,
|
||||||
`,
|
HideHelp: true,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(cmd)
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -284,12 +275,12 @@ Example:
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Args().Get(1) != "" && rmAllSecrets {
|
if cmd.Args().Get(1) != "" && rmAllSecrets {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("cannot use '<secret-name>' and '--all' together"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("cannot use '<secret-name>' and '--all' together"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Args().Get(1) == "" && !rmAllSecrets {
|
if cmd.Args().Get(1) == "" && !rmAllSecrets {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no secret(s) specified?"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("no secret(s) specified?"))
|
||||||
}
|
}
|
||||||
|
|
||||||
cl, err := client.New(app.Server)
|
cl, err := client.New(app.Server)
|
||||||
@ -313,7 +304,7 @@ Example:
|
|||||||
}
|
}
|
||||||
|
|
||||||
match := false
|
match := false
|
||||||
secretToRm := c.Args().Get(1)
|
secretToRm := cmd.Args().Get(1)
|
||||||
for secretName, val := range secrets {
|
for secretName, val := range secrets {
|
||||||
secretRemoteName := fmt.Sprintf("%s_%s_%s", app.StackName(), secretName, val.Version)
|
secretRemoteName := fmt.Sprintf("%s_%s_%s", app.StackName(), secretName, val.Version)
|
||||||
if _, ok := remoteSecretNames[secretRemoteName]; ok {
|
if _, ok := remoteSecretNames[secretRemoteName]; ok {
|
||||||
@ -351,16 +342,17 @@ var appSecretLsCommand = cli.Command{
|
|||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
internal.OfflineFlag,
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
internal.MachineReadableFlag,
|
internal.MachineReadableFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Usage: "List all secrets",
|
Usage: "List all secrets",
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
UsageText: "abra app secret list [options]",
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
app := internal.ValidateApp(c)
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
app := internal.ValidateApp(cmd)
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -420,8 +412,8 @@ var appSecretCommand = cli.Command{
|
|||||||
Name: "secret",
|
Name: "secret",
|
||||||
Aliases: []string{"s"},
|
Aliases: []string{"s"},
|
||||||
Usage: "Manage app secrets",
|
Usage: "Manage app secrets",
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app secret [command] [arguments] [options]",
|
||||||
Subcommands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&appSecretGenerateCommand,
|
&appSecretGenerateCommand,
|
||||||
&appSecretInsertCommand,
|
&appSecretInsertCommand,
|
||||||
&appSecretRmCommand,
|
&appSecretRmCommand,
|
||||||
|
@ -13,21 +13,19 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/service"
|
"coopcloud.tech/abra/pkg/service"
|
||||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
containerTypes "github.com/docker/docker/api/types/container"
|
containerTypes "github.com/docker/docker/api/types/container"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appServicesCommand = cli.Command{
|
var appServicesCommand = cli.Command{
|
||||||
Name: "services",
|
Name: "services",
|
||||||
Aliases: []string{"sr"},
|
Aliases: []string{"sr"},
|
||||||
Usage: "Display all services of an app",
|
Usage: "Display all services of an app",
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app services <domain> [options]",
|
||||||
Flags: []cli.Flag{
|
Before: internal.SubCommandBefore,
|
||||||
internal.DebugFlag,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
},
|
HideHelp: true,
|
||||||
Before: internal.SubCommandBefore,
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
app := internal.ValidateApp(cmd)
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
app := internal.ValidateApp(c)
|
|
||||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
dockerClient "github.com/docker/docker/client"
|
dockerClient "github.com/docker/docker/client"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var prune bool
|
var prune bool
|
||||||
@ -65,25 +65,24 @@ func pruneApp(cl *dockerClient.Client, app appPkg.App) error {
|
|||||||
var appUndeployCommand = cli.Command{
|
var appUndeployCommand = cli.Command{
|
||||||
Name: "undeploy",
|
Name: "undeploy",
|
||||||
Aliases: []string{"un"},
|
Aliases: []string{"un"},
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app undeploy <domain> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
internal.NoInputFlag,
|
||||||
internal.OfflineFlag,
|
internal.OfflineFlag,
|
||||||
pruneFlag,
|
pruneFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Usage: "Undeploy an app",
|
Usage: "Undeploy an app",
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Description: `
|
HideHelp: true,
|
||||||
This does not destroy any of the application data.
|
Description: `This does not destroy any of the application data.
|
||||||
|
|
||||||
However, you should remain vigilant, as your swarm installation will consider
|
However, you should remain vigilant, as your swarm installation will consider
|
||||||
any previously attached volumes as eligible for pruning once undeployed.
|
any previously attached volumes as eligible for pruning once undeployed.
|
||||||
|
|
||||||
Passing "-p/--prune" does not remove those volumes.`,
|
Passing "-p/--prune" does not remove those volumes.`,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(cmd)
|
||||||
stackName := app.StackName()
|
stackName := app.StackName()
|
||||||
|
|
||||||
cl, err := client.New(app.Server)
|
cl, err := client.New(app.Server)
|
||||||
|
@ -15,45 +15,37 @@ import (
|
|||||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"coopcloud.tech/tagcmp"
|
"coopcloud.tech/tagcmp"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appUpgradeCommand = cli.Command{
|
var appUpgradeCommand = cli.Command{
|
||||||
Name: "upgrade",
|
Name: "upgrade",
|
||||||
Aliases: []string{"up"},
|
Aliases: []string{"up"},
|
||||||
Usage: "Upgrade an app",
|
Usage: "Upgrade an app",
|
||||||
ArgsUsage: "<domain> [<version>]",
|
UsageText: "abra app upgrade <domain> [<version>] [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.ForceFlag,
|
internal.ForceFlag,
|
||||||
internal.NoDomainChecksFlag,
|
internal.NoDomainChecksFlag,
|
||||||
internal.DontWaitConvergeFlag,
|
internal.DontWaitConvergeFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.ReleaseNotesFlag,
|
internal.ReleaseNotesFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Description: `
|
Description: `Upgrade an app.
|
||||||
Upgrade an app.
|
|
||||||
|
|
||||||
Unlike "deploy", chaos operations are not supported here. Only recipe versions
|
Unlike "deploy", chaos operations are not supported here. Only recipe versions
|
||||||
are supported values for "[<version>]".
|
are supported values for "[<version>]".
|
||||||
|
|
||||||
An upgrade can be destructive, please ensure you have a copy of your app data
|
An upgrade can be destructive, please ensure you have a copy of your app data
|
||||||
beforehand.
|
beforehand.`,
|
||||||
|
HideHelp: true,
|
||||||
EXAMPLE:
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
abra app upgrade foo.example.com
|
|
||||||
abra app upgrade foo.example.com 1.2.3+3.2.1`,
|
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
var warnMessages []string
|
var warnMessages []string
|
||||||
|
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(cmd)
|
||||||
stackName := app.StackName()
|
stackName := app.StackName()
|
||||||
|
|
||||||
specificVersion := c.Args().Get(1)
|
specificVersion := cmd.Args().Get(1)
|
||||||
if specificVersion != "" {
|
if specificVersion != "" {
|
||||||
log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion)
|
log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion)
|
||||||
app.Recipe.Version = specificVersion
|
app.Recipe.Version = specificVersion
|
||||||
|
@ -11,22 +11,19 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appVolumeListCommand = cli.Command{
|
var appVolumeListCommand = cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app volume list <domain> [options]",
|
||||||
Flags: []cli.Flag{
|
Before: internal.SubCommandBefore,
|
||||||
internal.DebugFlag,
|
Usage: "List volumes associated with an app",
|
||||||
internal.NoInputFlag,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
},
|
HideHelp: true,
|
||||||
Before: internal.SubCommandBefore,
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
Usage: "List volumes associated with an app",
|
app := internal.ValidateApp(cmd)
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
app := internal.ValidateApp(c)
|
|
||||||
|
|
||||||
cl, err := client.New(app.Server)
|
cl, err := client.New(app.Server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -74,27 +71,26 @@ var appVolumeListCommand = cli.Command{
|
|||||||
var appVolumeRemoveCommand = cli.Command{
|
var appVolumeRemoveCommand = cli.Command{
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
Usage: "Remove volume(s) associated with an app",
|
Usage: "Remove volume(s) associated with an app",
|
||||||
Description: `
|
Description: `Remove volumes associated with an app.
|
||||||
This command supports removing volumes associated with an app. The app in
|
|
||||||
question must be undeployed before you try to remove volumes. See "abra app
|
The app in question must be undeployed before you try to remove volumes. See
|
||||||
undeploy <domain>" for more.
|
"abra app undeploy <domain>" for more.
|
||||||
|
|
||||||
The command is interactive and will show a multiple select input which allows
|
The command is interactive and will show a multiple select input which allows
|
||||||
you to make a seclection. Use the "?" key to see more help on navigating this
|
you to make a seclection. Use the "?" key to see more help on navigating this
|
||||||
interface.
|
interface.
|
||||||
|
|
||||||
Passing "--force/-f" will select all volumes for removal. Be careful.`,
|
Passing "--force/-f" will select all volumes for removal. Be careful.`,
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app volume remove [options] <domain>",
|
||||||
Aliases: []string{"rm"},
|
Aliases: []string{"rm"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
internal.NoInputFlag,
|
||||||
internal.ForceFlag,
|
internal.ForceFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
ShellComplete: autocomplete.AppNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(cmd)
|
||||||
|
|
||||||
cl, err := client.New(app.Server)
|
cl, err := client.New(app.Server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -158,8 +154,8 @@ var appVolumeCommand = cli.Command{
|
|||||||
Name: "volume",
|
Name: "volume",
|
||||||
Aliases: []string{"vl"},
|
Aliases: []string{"vl"},
|
||||||
Usage: "Manage app volumes",
|
Usage: "Manage app volumes",
|
||||||
ArgsUsage: "<domain>",
|
UsageText: "abra app volume [command] [options] [arguments]",
|
||||||
Subcommands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&appVolumeListCommand,
|
&appVolumeListCommand,
|
||||||
&appVolumeRemoveCommand,
|
&appVolumeRemoveCommand,
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package catalogue
|
package catalogue
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -15,25 +16,22 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var catalogueGenerateCommand = cli.Command{
|
var catalogueGenerateCommand = cli.Command{
|
||||||
Name: "generate",
|
Name: "generate",
|
||||||
Aliases: []string{"g"},
|
Aliases: []string{"g"},
|
||||||
Usage: "Generate the recipe catalogue",
|
Usage: "Generate the recipe catalogue",
|
||||||
|
UsageText: "abra catalogue generate [<recipe>] [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.PublishFlag,
|
internal.PublishFlag,
|
||||||
internal.DryFlag,
|
internal.DryFlag,
|
||||||
internal.SkipUpdatesFlag,
|
internal.SkipUpdatesFlag,
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Description: `
|
Description: `Generate a new copy of the recipe catalogue.
|
||||||
Generate a new copy of the recipe catalogue.
|
|
||||||
|
|
||||||
It is possible to generate new metadata for a single recipe by passing
|
It is possible to generate new metadata for a single recipe by passing
|
||||||
<recipe>. The existing local catalogue will be updated, not overwritten.
|
<recipe>. The existing local catalogue will be updated, not overwritten.
|
||||||
@ -45,14 +43,14 @@ If you have a Hub account you can have Abra log you in to avoid this. Pass
|
|||||||
Push your new release to git.coopcloud.tech with "-p/--publish". This requires
|
Push your new release to git.coopcloud.tech with "-p/--publish". This requires
|
||||||
that you have permission to git push to these repositories and have your SSH
|
that you have permission to git push to these repositories and have your SSH
|
||||||
keys configured on your account.`,
|
keys configured on your account.`,
|
||||||
ArgsUsage: "[<recipe>]",
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
HideHelp: true,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
recipeName := c.Args().First()
|
recipeName := cmd.Args().First()
|
||||||
r := recipe.Get(recipeName)
|
r := recipe.Get(recipeName)
|
||||||
|
|
||||||
if recipeName != "" {
|
if recipeName != "" {
|
||||||
internal.ValidateRecipe(c)
|
internal.ValidateRecipe(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !internal.Chaos {
|
if !internal.Chaos {
|
||||||
@ -208,8 +206,8 @@ var CatalogueCommand = cli.Command{
|
|||||||
Name: "catalogue",
|
Name: "catalogue",
|
||||||
Usage: "Manage the recipe catalogue",
|
Usage: "Manage the recipe catalogue",
|
||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
ArgsUsage: "<recipe>",
|
UsageText: "abra catalogue [command] [options] [arguments]",
|
||||||
Subcommands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&catalogueGenerateCommand,
|
&catalogueGenerateCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
101
cli/cli.go
101
cli/cli.go
@ -2,6 +2,7 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -18,31 +19,24 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/web"
|
"coopcloud.tech/abra/pkg/web"
|
||||||
charmLog "github.com/charmbracelet/log"
|
charmLog "github.com/charmbracelet/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AutoCompleteCommand helps people set up auto-complete in their shells
|
// AutoCompleteCommand helps people set up auto-complete in their shells
|
||||||
var AutoCompleteCommand = cli.Command{
|
var AutoCompleteCommand = cli.Command{
|
||||||
Name: "autocomplete",
|
Name: "autocomplete",
|
||||||
Aliases: []string{"ac"},
|
Aliases: []string{"ac"},
|
||||||
Usage: "Configure shell autocompletion",
|
Usage: "Configure shell autocompletion",
|
||||||
Description: `
|
UsageText: "abra autocomplete <shell> [options]",
|
||||||
Set up shell auto-completion.
|
Description: `Set up shell auto-completion.
|
||||||
|
|
||||||
Supported shells are: bash, fish, fizsh & zsh.
|
Supported shells are: bash, fish, fizsh & zsh.`,
|
||||||
|
HideHelp: true,
|
||||||
EXAMPLE:
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
shellType := cmd.Args().First()
|
||||||
abra autocomplete bash`,
|
|
||||||
ArgsUsage: "<shell>",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
internal.DebugFlag,
|
|
||||||
},
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
shellType := c.Args().First()
|
|
||||||
|
|
||||||
if shellType == "" {
|
if shellType == "" {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no shell provided"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("no shell provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
supportedShells := map[string]bool{
|
supportedShells := map[string]bool{
|
||||||
@ -113,33 +107,29 @@ source /etc/fish/completions/abra
|
|||||||
|
|
||||||
// UpgradeCommand upgrades abra in-place.
|
// UpgradeCommand upgrades abra in-place.
|
||||||
var UpgradeCommand = cli.Command{
|
var UpgradeCommand = cli.Command{
|
||||||
Name: "upgrade",
|
Name: "upgrade",
|
||||||
Aliases: []string{"u"},
|
Aliases: []string{"u"},
|
||||||
Usage: "Upgrade abra",
|
Usage: "Upgrade abra",
|
||||||
Description: `
|
UsageText: "abra upgrade [options]",
|
||||||
Upgrade abra in-place with the latest stable or release candidate.
|
Description: `Upgrade abra in-place with the latest stable or release candidate.
|
||||||
|
|
||||||
Use "-r/--rc" to install the latest release candidate. Please bear in mind that
|
Use "--rc/-r" to install the latest release candidate. Please bear in mind that
|
||||||
it may contain absolutely catastrophic deal-breaker bugs. Thank you very much
|
it may contain absolutely catastrophic deal-breaker bugs. Thank you very much
|
||||||
for the testing efforts 💗
|
for the testing efforts 💗`,
|
||||||
|
Flags: []cli.Flag{internal.RCFlag},
|
||||||
EXAMPLE:
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
abra upgrade
|
|
||||||
abra upgrade --rc`,
|
|
||||||
Flags: []cli.Flag{internal.RCFlag},
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
mainURL := "https://install.abra.coopcloud.tech"
|
mainURL := "https://install.abra.coopcloud.tech"
|
||||||
cmd := exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash", mainURL))
|
c := exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash", mainURL))
|
||||||
|
|
||||||
if internal.RC {
|
if internal.RC {
|
||||||
releaseCandidateURL := "https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/installer/installer"
|
releaseCandidateURL := "https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/installer/installer"
|
||||||
cmd = exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash -s -- --rc", releaseCandidateURL))
|
c = exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash -s -- --rc", releaseCandidateURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("attempting to run %s", cmd)
|
log.Debugf("attempting to run %s", c)
|
||||||
|
|
||||||
if err := internal.RunCmd(cmd); err != nil {
|
if err := internal.RunCmd(c); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,18 +137,16 @@ EXAMPLE:
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAbraApp(version, commit string) *cli.App {
|
func newAbraApp(version, commit string) *cli.Command {
|
||||||
app := &cli.App{
|
app := &cli.Command{
|
||||||
Name: "abra",
|
Name: "abra",
|
||||||
Usage: `the Co-op Cloud command-line utility belt 🎩🐇
|
Usage: "The Co-op Cloud command-line utility belt 🎩🐇",
|
||||||
____ ____ _ _
|
UsageText: "abra [command] [arguments] [options]",
|
||||||
/ ___|___ ___ _ __ / ___| | ___ _ _ __| |
|
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
||||||
| | / _ \ _____ / _ \| '_ \ | | | |/ _ \| | | |/ _' |
|
Flags: []cli.Flag{
|
||||||
| |__| (_) |_____| (_) | |_) | | |___| | (_) | |_| | (_| |
|
// NOTE(d1): "GLOBAL OPTIONS" flags
|
||||||
\____\___/ \___/| .__/ \____|_|\___/ \__,_|\__,_|
|
internal.DebugFlag,
|
||||||
|_|
|
},
|
||||||
`,
|
|
||||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&app.AppCommand,
|
&app.AppCommand,
|
||||||
&server.ServerCommand,
|
&server.ServerCommand,
|
||||||
@ -167,12 +155,13 @@ func newAbraApp(version, commit string) *cli.App {
|
|||||||
&UpgradeCommand,
|
&UpgradeCommand,
|
||||||
&AutoCompleteCommand,
|
&AutoCompleteCommand,
|
||||||
},
|
},
|
||||||
BashComplete: autocomplete.SubcommandComplete,
|
EnableShellCompletion: true,
|
||||||
|
UseShortOptionHandling: true,
|
||||||
|
HideHelpCommand: true,
|
||||||
|
ShellComplete: autocomplete.SubcommandComplete,
|
||||||
}
|
}
|
||||||
|
|
||||||
app.EnableBashCompletion = true
|
app.Before = func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
|
||||||
app.Before = func(c *cli.Context) error {
|
|
||||||
paths := []string{
|
paths := []string{
|
||||||
config.ABRA_DIR,
|
config.ABRA_DIR,
|
||||||
config.SERVERS_DIR,
|
config.SERVERS_DIR,
|
||||||
@ -198,6 +187,12 @@ func newAbraApp(version, commit string) *cli.App {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cli.HelpFlag = &cli.BoolFlag{
|
||||||
|
Name: "help",
|
||||||
|
Aliases: []string{"h, H"},
|
||||||
|
Usage: "Show help",
|
||||||
|
}
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +200,7 @@ func newAbraApp(version, commit string) *cli.App {
|
|||||||
func RunApp(version, commit string) {
|
func RunApp(version, commit string) {
|
||||||
app := newAbraApp(version, commit)
|
app := newAbraApp(version, commit)
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(context.Background(), os.Args); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Secrets stores the variable from SecretsFlag
|
// Secrets stores the variable from SecretsFlag
|
||||||
@ -74,7 +75,7 @@ var Chaos bool
|
|||||||
var ChaosFlag = &cli.BoolFlag{
|
var ChaosFlag = &cli.BoolFlag{
|
||||||
Name: "chaos",
|
Name: "chaos",
|
||||||
Aliases: []string{"C"},
|
Aliases: []string{"C"},
|
||||||
Usage: "Proceed with uncommitted recipes changes. Use with care!",
|
Usage: "Ignore uncommitted recipes changes. Use with care!",
|
||||||
Destination: &Chaos,
|
Destination: &Chaos,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +117,7 @@ var OfflineFlag = &cli.BoolFlag{
|
|||||||
Name: "offline",
|
Name: "offline",
|
||||||
Aliases: []string{"o"},
|
Aliases: []string{"o"},
|
||||||
Destination: &Offline,
|
Destination: &Offline,
|
||||||
Usage: "Prefer offline & filesystem access when possible",
|
Usage: "Prefer offline & filesystem access",
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReleaseNotes stores the variable from ReleaseNotesFlag.
|
// ReleaseNotes stores the variable from ReleaseNotesFlag.
|
||||||
@ -138,7 +139,7 @@ var MachineReadableFlag = &cli.BoolFlag{
|
|||||||
Name: "machine",
|
Name: "machine",
|
||||||
Aliases: []string{"m"},
|
Aliases: []string{"m"},
|
||||||
Destination: &MachineReadable,
|
Destination: &MachineReadable,
|
||||||
Usage: "Output in a machine-readable format (where supported)",
|
Usage: "Machine-readable output",
|
||||||
}
|
}
|
||||||
|
|
||||||
// RC signifies the latest release candidate
|
// RC signifies the latest release candidate
|
||||||
@ -319,7 +320,7 @@ var AllServicesFlag = &cli.BoolFlag{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SubCommandBefore wires up pre-action machinery (e.g. --debug handling).
|
// SubCommandBefore wires up pre-action machinery (e.g. --debug handling).
|
||||||
func SubCommandBefore(c *cli.Context) error {
|
func SubCommandBefore(ctx context.Context, cmd *cli.Command) error {
|
||||||
if Debug {
|
if Debug {
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
log.SetOutput(os.Stderr)
|
log.SetOutput(os.Stderr)
|
||||||
|
@ -4,13 +4,13 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ShowSubcommandHelpAndError exits the program on error, logs the error to the
|
// ShowSubcommandHelpAndError exits the program on error, logs the error to the
|
||||||
// terminal, and shows the help command.
|
// terminal, and shows the help command.
|
||||||
func ShowSubcommandHelpAndError(c *cli.Context, err interface{}) {
|
func ShowSubcommandHelpAndError(cmd *cli.Command, err interface{}) {
|
||||||
if err2 := cli.ShowSubcommandHelp(c); err2 != nil {
|
if err2 := cli.ShowSubcommandHelp(cmd); err2 != nil {
|
||||||
log.Error(err2)
|
log.Error(err2)
|
||||||
}
|
}
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
@ -9,12 +9,12 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ValidateRecipe ensures the recipe arg is valid.
|
// ValidateRecipe ensures the recipe arg is valid.
|
||||||
func ValidateRecipe(c *cli.Context) recipe.Recipe {
|
func ValidateRecipe(cmd *cli.Command) recipe.Recipe {
|
||||||
recipeName := c.Args().First()
|
recipeName := cmd.Args().First()
|
||||||
|
|
||||||
if recipeName == "" && !NoInput {
|
if recipeName == "" && !NoInput {
|
||||||
var recipes []string
|
var recipes []string
|
||||||
@ -54,7 +54,7 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if recipeName == "" {
|
if recipeName == "" {
|
||||||
ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
|
ShowSubcommandHelpAndError(cmd, errors.New("no recipe name provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
chosenRecipe := recipe.Get(recipeName)
|
chosenRecipe := recipe.Get(recipeName)
|
||||||
@ -64,7 +64,7 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe {
|
|||||||
}
|
}
|
||||||
_, err = chosenRecipe.GetComposeConfig(nil)
|
_, err = chosenRecipe.GetComposeConfig(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if c.Command.Name == "generate" {
|
if cmd.Name == "generate" {
|
||||||
if strings.Contains(err.Error(), "missing a compose") {
|
if strings.Contains(err.Error(), "missing a compose") {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -83,11 +83,11 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidateApp ensures the app name arg is valid.
|
// ValidateApp ensures the app name arg is valid.
|
||||||
func ValidateApp(c *cli.Context) app.App {
|
func ValidateApp(cmd *cli.Command) app.App {
|
||||||
appName := c.Args().First()
|
appName := cmd.Args().First()
|
||||||
|
|
||||||
if appName == "" {
|
if appName == "" {
|
||||||
ShowSubcommandHelpAndError(c, errors.New("no app provided"))
|
ShowSubcommandHelpAndError(cmd, errors.New("no app provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
app, err := app.Get(appName)
|
app, err := app.Get(appName)
|
||||||
@ -101,8 +101,8 @@ func ValidateApp(c *cli.Context) app.App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidateDomain ensures the domain name arg is valid.
|
// ValidateDomain ensures the domain name arg is valid.
|
||||||
func ValidateDomain(c *cli.Context) string {
|
func ValidateDomain(cmd *cli.Command) string {
|
||||||
domainName := c.Args().First()
|
domainName := cmd.Args().First()
|
||||||
|
|
||||||
if domainName == "" && !NoInput {
|
if domainName == "" && !NoInput {
|
||||||
prompt := &survey.Input{
|
prompt := &survey.Input{
|
||||||
@ -115,7 +115,7 @@ func ValidateDomain(c *cli.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if domainName == "" {
|
if domainName == "" {
|
||||||
ShowSubcommandHelpAndError(c, errors.New("no domain provided"))
|
ShowSubcommandHelpAndError(cmd, errors.New("no domain provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("validated %s as domain argument", domainName)
|
log.Debugf("validated %s as domain argument", domainName)
|
||||||
@ -124,10 +124,10 @@ func ValidateDomain(c *cli.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidateSubCmdFlags ensures flag order conforms to correct order
|
// ValidateSubCmdFlags ensures flag order conforms to correct order
|
||||||
func ValidateSubCmdFlags(c *cli.Context) bool {
|
func ValidateSubCmdFlags(cmd *cli.Command) bool {
|
||||||
for argIdx, arg := range c.Args().Slice() {
|
for argIdx, arg := range cmd.Args().Slice() {
|
||||||
if !strings.HasPrefix(arg, "--") {
|
if !strings.HasPrefix(arg, "--") {
|
||||||
for _, flag := range c.Args().Slice()[argIdx:] {
|
for _, flag := range cmd.Args().Slice()[argIdx:] {
|
||||||
if strings.HasPrefix(flag, "--") {
|
if strings.HasPrefix(flag, "--") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -138,8 +138,8 @@ func ValidateSubCmdFlags(c *cli.Context) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidateServer ensures the server name arg is valid.
|
// ValidateServer ensures the server name arg is valid.
|
||||||
func ValidateServer(c *cli.Context) string {
|
func ValidateServer(cmd *cli.Command) string {
|
||||||
serverName := c.Args().First()
|
serverName := cmd.Args().First()
|
||||||
|
|
||||||
serverNames, err := config.ReadServerNames()
|
serverNames, err := config.ReadServerNames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -164,11 +164,11 @@ func ValidateServer(c *cli.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if serverName == "" {
|
if serverName == "" {
|
||||||
ShowSubcommandHelpAndError(c, errors.New("no server provided"))
|
ShowSubcommandHelpAndError(cmd, errors.New("no server provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !matched {
|
if !matched {
|
||||||
ShowSubcommandHelpAndError(c, errors.New("server doesn't exist?"))
|
ShowSubcommandHelpAndError(cmd, errors.New("server doesn't exist?"))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("validated %s as server argument", serverName)
|
log.Debugf("validated %s as server argument", serverName)
|
||||||
|
@ -1,27 +1,26 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var recipeDiffCommand = cli.Command{
|
var recipeDiffCommand = cli.Command{
|
||||||
Name: "diff",
|
Name: "diff",
|
||||||
Usage: "Show unstaged changes in recipe config",
|
Usage: "Show unstaged changes in recipe config",
|
||||||
Description: "This command requires /usr/bin/git.",
|
Description: "This command requires /usr/bin/git.",
|
||||||
Aliases: []string{"d"},
|
Aliases: []string{"d"},
|
||||||
ArgsUsage: "<recipe>",
|
UsageText: "abra recipe diff <recipe> [options]",
|
||||||
Flags: []cli.Flag{
|
Before: internal.SubCommandBefore,
|
||||||
internal.DebugFlag,
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
internal.NoInputFlag,
|
HideHelp: true,
|
||||||
},
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
Before: internal.SubCommandBefore,
|
r := internal.ValidateRecipe(cmd)
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
r := internal.ValidateRecipe(c)
|
|
||||||
|
|
||||||
if err := gitPkg.DiffUnstaged(r.Dir); err != nil {
|
if err := gitPkg.DiffUnstaged(r.Dir); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -1,32 +1,30 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var recipeFetchCommand = cli.Command{
|
var recipeFetchCommand = cli.Command{
|
||||||
Name: "fetch",
|
Name: "fetch",
|
||||||
Usage: "Fetch recipe(s)",
|
Usage: "Fetch recipe(s)",
|
||||||
Aliases: []string{"f"},
|
Aliases: []string{"f"},
|
||||||
ArgsUsage: "[<recipe>]",
|
UsageText: "abra recipe fetch [<recipe>] [options]",
|
||||||
Description: "Retrieves all recipes if no <recipe> argument is passed",
|
Description: "Retrieves all recipes if no <recipe> argument is passed",
|
||||||
Flags: []cli.Flag{
|
Before: internal.SubCommandBefore,
|
||||||
internal.DebugFlag,
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
internal.NoInputFlag,
|
HideHelp: true,
|
||||||
internal.OfflineFlag,
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
},
|
recipeName := cmd.Args().First()
|
||||||
Before: internal.SubCommandBefore,
|
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
recipeName := c.Args().First()
|
|
||||||
r := recipe.Get(recipeName)
|
r := recipe.Get(recipeName)
|
||||||
if recipeName != "" {
|
if recipeName != "" {
|
||||||
internal.ValidateRecipe(c)
|
internal.ValidateRecipe(cmd)
|
||||||
if err := r.Ensure(false, false); err != nil {
|
if err := r.Ensure(false, false); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
@ -8,25 +9,23 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/lint"
|
"coopcloud.tech/abra/pkg/lint"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var recipeLintCommand = cli.Command{
|
var recipeLintCommand = cli.Command{
|
||||||
Name: "lint",
|
Name: "lint",
|
||||||
Usage: "Lint a recipe",
|
Usage: "Lint a recipe",
|
||||||
Aliases: []string{"l"},
|
Aliases: []string{"l"},
|
||||||
ArgsUsage: "<recipe>",
|
UsageText: "abra recipe lint <recipe> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OnlyErrorFlag,
|
internal.OnlyErrorFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
recipe := internal.ValidateRecipe(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
recipe := internal.ValidateRecipe(cmd)
|
||||||
|
|
||||||
if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -10,7 +11,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pattern string
|
var pattern string
|
||||||
@ -23,17 +24,17 @@ var patternFlag = &cli.StringFlag{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var recipeListCommand = cli.Command{
|
var recipeListCommand = cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Usage: "List available recipes",
|
Usage: "List recipes",
|
||||||
Aliases: []string{"ls"},
|
UsageText: "abra recipe list [options]",
|
||||||
|
Aliases: []string{"ls"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.MachineReadableFlag,
|
internal.MachineReadableFlag,
|
||||||
patternFlag,
|
patternFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
catl, err := recipe.ReadRecipeCatalogue(internal.Offline)
|
catl, err := recipe.ReadRecipeCatalogue(internal.Offline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err.Error())
|
log.Fatal(err.Error())
|
||||||
|
@ -2,6 +2,7 @@ package recipe
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -13,7 +14,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/git"
|
"coopcloud.tech/abra/pkg/git"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// recipeMetadata is the recipe metadata for the README.md
|
// recipeMetadata is the recipe metadata for the README.md
|
||||||
@ -34,27 +35,24 @@ var recipeNewCommand = cli.Command{
|
|||||||
Name: "new",
|
Name: "new",
|
||||||
Aliases: []string{"n"},
|
Aliases: []string{"n"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.GitNameFlag,
|
internal.GitNameFlag,
|
||||||
internal.GitEmailFlag,
|
internal.GitEmailFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Usage: "Create a new recipe",
|
Usage: "Create a new recipe",
|
||||||
ArgsUsage: "<recipe>",
|
UsageText: "abra recipe new <recipe> [options]",
|
||||||
Description: `
|
Description: `Create a new recipe.
|
||||||
Create a new recipe.
|
|
||||||
|
|
||||||
Abra uses the built-in example repository which is available here:
|
Abra uses the built-in example repository which is available here:
|
||||||
|
|
||||||
https://git.coopcloud.tech/coop-cloud/example`,
|
https://git.coopcloud.tech/coop-cloud/example`,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
recipeName := c.Args().First()
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
recipeName := cmd.Args().First()
|
||||||
r := recipe.Get(recipeName)
|
r := recipe.Get(recipeName)
|
||||||
|
|
||||||
if recipeName == "" {
|
if recipeName == "" {
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
|
internal.ShowSubcommandHelpAndError(cmd, errors.New("no recipe name provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(r.Dir); !os.IsNotExist(err) {
|
if _, err := os.Stat(r.Dir); !os.IsNotExist(err) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RecipeCommand defines all recipe related sub-commands.
|
// RecipeCommand defines all recipe related sub-commands.
|
||||||
@ -9,17 +9,17 @@ var RecipeCommand = cli.Command{
|
|||||||
Name: "recipe",
|
Name: "recipe",
|
||||||
Aliases: []string{"r"},
|
Aliases: []string{"r"},
|
||||||
Usage: "Manage recipes",
|
Usage: "Manage recipes",
|
||||||
ArgsUsage: "<recipe>",
|
UsageText: "abra recipe [command] [arguments] [options]",
|
||||||
Description: `
|
Description: `A recipe is a blueprint for an app.
|
||||||
A recipe is a blueprint for an app. It is a bunch of config files which
|
|
||||||
describe how to deploy and maintain an app. Recipes are maintained by the Co-op
|
It is a bunch of config files which describe how to deploy and maintain an app.
|
||||||
Cloud community and you can use Abra to read them, deploy them and create apps
|
Recipes are maintained by the Co-op Cloud community and you can use Abra to
|
||||||
for you.
|
read them, deploy them and create apps for you.
|
||||||
|
|
||||||
Anyone who uses a recipe can become a maintainer. Maintainers typically make
|
Anyone who uses a recipe can become a maintainer. Maintainers typically make
|
||||||
sure the recipe is in good working order and the config upgraded in a timely
|
sure the recipe is in good working order and the config upgraded in a timely
|
||||||
manner.`,
|
manner.`,
|
||||||
Subcommands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&recipeFetchCommand,
|
&recipeFetchCommand,
|
||||||
&recipeLintCommand,
|
&recipeLintCommand,
|
||||||
&recipeListCommand,
|
&recipeListCommand,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -18,17 +19,18 @@ import (
|
|||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/distribution/reference"
|
"github.com/distribution/reference"
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var recipeReleaseCommand = cli.Command{
|
var recipeReleaseCommand = cli.Command{
|
||||||
Name: "release",
|
Name: "release",
|
||||||
Aliases: []string{"rl"},
|
Aliases: []string{"rl"},
|
||||||
Usage: "Release a new recipe version",
|
Usage: "Release a new recipe version",
|
||||||
ArgsUsage: "<recipe> [<version>]",
|
UsageText: "abra recipe release <recipe> [<version>] [options]",
|
||||||
Description: `
|
Description: `Create a new version of a recipe.
|
||||||
Create a new version of a recipe. These versions are then published on the
|
|
||||||
Co-op Cloud recipe catalogue. These versions take the following form:
|
These versions are then published on the Co-op Cloud recipe catalogue. These
|
||||||
|
versions take the following form:
|
||||||
|
|
||||||
a.b.c+x.y.z
|
a.b.c+x.y.z
|
||||||
|
|
||||||
@ -46,19 +48,17 @@ Publish your new release to git.coopcloud.tech with "-p/--publish". This
|
|||||||
requires that you have permission to git push to these repositories and have
|
requires that you have permission to git push to these repositories and have
|
||||||
your SSH keys configured on your account.`,
|
your SSH keys configured on your account.`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.DryFlag,
|
internal.DryFlag,
|
||||||
internal.MajorFlag,
|
internal.MajorFlag,
|
||||||
internal.MinorFlag,
|
internal.MinorFlag,
|
||||||
internal.PatchFlag,
|
internal.PatchFlag,
|
||||||
internal.PublishFlag,
|
internal.PublishFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
recipe := internal.ValidateRecipe(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
recipe := internal.ValidateRecipe(cmd)
|
||||||
|
|
||||||
imagesTmp, err := getImageVersions(recipe)
|
imagesTmp, err := getImageVersions(recipe)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -75,7 +75,7 @@ your SSH keys configured on your account.`,
|
|||||||
log.Fatalf("main app service version for %s is empty?", recipe.Name)
|
log.Fatalf("main app service version for %s is empty?", recipe.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
tagString := c.Args().Get(1)
|
tagString := cmd.Args().Get(1)
|
||||||
if tagString != "" {
|
if tagString != "" {
|
||||||
if _, err := tagcmp.Parse(tagString); err != nil {
|
if _, err := tagcmp.Parse(tagString); err != nil {
|
||||||
log.Fatalf("cannot parse %s, invalid tag specified?", tagString)
|
log.Fatalf("cannot parse %s, invalid tag specified?", tagString)
|
||||||
|
@ -1,32 +1,31 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var recipeResetCommand = cli.Command{
|
var recipeResetCommand = cli.Command{
|
||||||
Name: "reset",
|
Name: "reset",
|
||||||
Usage: "Remove all unstaged changes from recipe config",
|
Usage: "Remove all unstaged changes from recipe config",
|
||||||
Description: "WARNING: this will delete your changes. Be Careful.",
|
Description: "WARNING: this will delete your changes. Be Careful.",
|
||||||
Aliases: []string{"rs"},
|
Aliases: []string{"rs"},
|
||||||
ArgsUsage: "<recipe>",
|
UsageText: "abra recipe reset <recipe> [options]",
|
||||||
Flags: []cli.Flag{
|
Before: internal.SubCommandBefore,
|
||||||
internal.DebugFlag,
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
internal.NoInputFlag,
|
HideHelp: true,
|
||||||
},
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
Before: internal.SubCommandBefore,
|
recipeName := cmd.Args().First()
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
recipeName := c.Args().First()
|
|
||||||
r := recipe.Get(recipeName)
|
r := recipe.Get(recipeName)
|
||||||
|
|
||||||
if recipeName != "" {
|
if recipeName != "" {
|
||||||
internal.ValidateRecipe(c)
|
internal.ValidateRecipe(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := git.PlainOpen(r.Dir)
|
repo, err := git.PlainOpen(r.Dir)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@ -12,35 +13,34 @@ import (
|
|||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var recipeSyncCommand = cli.Command{
|
var recipeSyncCommand = cli.Command{
|
||||||
Name: "sync",
|
Name: "sync",
|
||||||
Aliases: []string{"s"},
|
Aliases: []string{"s"},
|
||||||
Usage: "Sync recipe version label",
|
Usage: "Sync recipe version label",
|
||||||
ArgsUsage: "<recipe> [<version>]",
|
UsageText: "abra recipe lint <recipe> [<version>] [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.DryFlag,
|
internal.DryFlag,
|
||||||
internal.MajorFlag,
|
internal.MajorFlag,
|
||||||
internal.MinorFlag,
|
internal.MinorFlag,
|
||||||
internal.PatchFlag,
|
internal.PatchFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Description: `
|
Description: `Generate labels for the main recipe service.
|
||||||
Generate labels for the main recipe service (i.e. by convention, the service
|
|
||||||
named "app") which corresponds to the following format:
|
By convention, the service named "app" using the following format:
|
||||||
|
|
||||||
coop-cloud.${STACK_NAME}.version=<version>
|
coop-cloud.${STACK_NAME}.version=<version>
|
||||||
|
|
||||||
Where <version> can be specifed on the command-line or Abra can attempt to
|
Where <version> can be specifed on the command-line or Abra can attempt to
|
||||||
auto-generate it for you. The <recipe> configuration will be updated on the
|
auto-generate it for you. The <recipe> configuration will be updated on the
|
||||||
local file system.`,
|
local file system.`,
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
recipe := internal.ValidateRecipe(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
recipe := internal.ValidateRecipe(cmd)
|
||||||
|
|
||||||
mainApp, err := internal.GetMainAppImage(recipe)
|
mainApp, err := internal.GetMainAppImage(recipe)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,7 +59,7 @@ local file system.`,
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nextTag := c.Args().Get(1)
|
nextTag := cmd.Args().Get(1)
|
||||||
if len(tags) == 0 && nextTag == "" {
|
if len(tags) == 0 && nextTag == "" {
|
||||||
log.Warnf("no git tags found for %s", recipe.Name)
|
log.Warnf("no git tags found for %s", recipe.Name)
|
||||||
if internal.NoInput {
|
if internal.NoInput {
|
||||||
|
@ -2,6 +2,7 @@ package recipe
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -19,7 +20,7 @@ import (
|
|||||||
"coopcloud.tech/tagcmp"
|
"coopcloud.tech/tagcmp"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/distribution/reference"
|
"github.com/distribution/reference"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type imgPin struct {
|
type imgPin struct {
|
||||||
@ -27,8 +28,8 @@ type imgPin struct {
|
|||||||
version tagcmp.Tag
|
version tagcmp.Tag
|
||||||
}
|
}
|
||||||
|
|
||||||
// anUpgrade represents a single service upgrade (as within a recipe), and the list of tags that it can be upgraded to,
|
// anUpgrade represents a single service upgrade (as within a recipe), and the
|
||||||
// for serialization purposes.
|
// list of tags that it can be upgraded to, for serialization purposes.
|
||||||
type anUpgrade struct {
|
type anUpgrade struct {
|
||||||
Service string `json:"service"`
|
Service string `json:"service"`
|
||||||
Image string `json:"image"`
|
Image string `json:"image"`
|
||||||
@ -37,13 +38,13 @@ type anUpgrade struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var recipeUpgradeCommand = cli.Command{
|
var recipeUpgradeCommand = cli.Command{
|
||||||
Name: "upgrade",
|
Name: "upgrade",
|
||||||
Aliases: []string{"u"},
|
Aliases: []string{"u"},
|
||||||
Usage: "Upgrade recipe image tags",
|
Usage: "Upgrade recipe image tags",
|
||||||
Description: `
|
UsageText: "abra recipe upgrade [<recipe>] [options]",
|
||||||
Parse all image tags within the given <recipe> configuration and prompt with
|
Description: `Upgrade a given <recipe> configuration.
|
||||||
more recent tags to upgrade to. It will update the relevant compose file tags
|
|
||||||
on the local file system.
|
It will update the relevant compose file tags on the local file system.
|
||||||
|
|
||||||
Some image tags cannot be parsed because they do not follow some sort of
|
Some image tags cannot be parsed because they do not follow some sort of
|
||||||
semver-like convention. In this case, all possible tags will be listed and it
|
semver-like convention. In this case, all possible tags will be listed and it
|
||||||
@ -53,25 +54,19 @@ The command is interactive and will show a select input which allows you to
|
|||||||
make a seclection. Use the "?" key to see more help on navigating this
|
make a seclection. Use the "?" key to see more help on navigating this
|
||||||
interface.
|
interface.
|
||||||
|
|
||||||
You may invoke this command in "wizard" mode and be prompted for input.
|
You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||||
|
|
||||||
EXAMPLE:
|
|
||||||
|
|
||||||
abra recipe upgrade`,
|
|
||||||
ArgsUsage: "<recipe>",
|
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.PatchFlag,
|
internal.PatchFlag,
|
||||||
internal.MinorFlag,
|
internal.MinorFlag,
|
||||||
internal.MajorFlag,
|
internal.MajorFlag,
|
||||||
internal.MachineReadableFlag,
|
internal.MachineReadableFlag,
|
||||||
internal.AllTagsFlag,
|
internal.AllTagsFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
recipe := internal.ValidateRecipe(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
recipe := internal.ValidateRecipe(cmd)
|
||||||
|
|
||||||
if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
@ -9,7 +10,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func sortServiceByName(versions [][]string) func(i, j int) bool {
|
func sortServiceByName(versions [][]string) func(i, j int) bool {
|
||||||
@ -26,19 +27,17 @@ var recipeVersionCommand = cli.Command{
|
|||||||
Name: "versions",
|
Name: "versions",
|
||||||
Aliases: []string{"v"},
|
Aliases: []string{"v"},
|
||||||
Usage: "List recipe versions",
|
Usage: "List recipe versions",
|
||||||
ArgsUsage: "<recipe>",
|
UsageText: "abra recipe version <recipe> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.MachineReadableFlag,
|
internal.MachineReadableFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.RecipeNameComplete,
|
ShellComplete: autocomplete.RecipeNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
var warnMessages []string
|
var warnMessages []string
|
||||||
|
|
||||||
recipe := internal.ValidateRecipe(c)
|
recipe := internal.ValidateRecipe(cmd)
|
||||||
|
|
||||||
catl, err := recipePkg.ReadRecipeCatalogue(internal.Offline)
|
catl, err := recipePkg.ReadRecipeCatalogue(internal.Offline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -13,7 +14,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/server"
|
"coopcloud.tech/abra/pkg/server"
|
||||||
sshPkg "coopcloud.tech/abra/pkg/ssh"
|
sshPkg "coopcloud.tech/abra/pkg/ssh"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var local bool
|
var local bool
|
||||||
@ -93,15 +94,15 @@ func createServerDir(name string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var serverAddCommand = cli.Command{
|
var serverAddCommand = cli.Command{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Aliases: []string{"a"},
|
Aliases: []string{"a"},
|
||||||
Usage: "Add a new server to your configuration",
|
Usage: "Add a new server",
|
||||||
Description: `
|
UsageText: "abra server add <domain> [options]",
|
||||||
Add a new server to your configuration so that it can be managed by Abra.
|
Description: `Add a new server to your configuration so that it can be managed by Abra.
|
||||||
|
|
||||||
Abra relies on the standard SSH command-line and ~/.ssh/config for client
|
Abra relies on the standard SSH command-line and ~/.ssh/config for client
|
||||||
connection details. You must configure an entry per-host in your ~/.ssh/config
|
connection details. You must configure an entry per-host in your ~/.ssh/config
|
||||||
for each server. For example:
|
for each server:
|
||||||
|
|
||||||
Host example.com example
|
Host example.com example
|
||||||
Hostname example.com
|
Hostname example.com
|
||||||
@ -109,10 +110,6 @@ for each server. For example:
|
|||||||
Port 12345
|
Port 12345
|
||||||
IdentityFile ~/.ssh/example@somewhere
|
IdentityFile ~/.ssh/example@somewhere
|
||||||
|
|
||||||
You can then add a server like so:
|
|
||||||
|
|
||||||
abra server add example.com
|
|
||||||
|
|
||||||
If "--local" is passed, then Abra assumes that the current local server is
|
If "--local" is passed, then Abra assumes that the current local server is
|
||||||
intended as the target server. This is useful when you want to have your entire
|
intended as the target server. This is useful when you want to have your entire
|
||||||
Co-op Cloud config located on the server itself, and not on your local
|
Co-op Cloud config located on the server itself, and not on your local
|
||||||
@ -120,28 +117,24 @@ developer machine. The domain is then set to "default".
|
|||||||
|
|
||||||
You can also pass "--no-domain-checks/-D" flag to use any arbitrary name
|
You can also pass "--no-domain-checks/-D" flag to use any arbitrary name
|
||||||
instead of a real domain. The host will be resolved with the "Hostname" entry
|
instead of a real domain. The host will be resolved with the "Hostname" entry
|
||||||
of your ~/.ssh/config. Checks for a valid online domain will be skipped:
|
of your ~/.ssh/config. Checks for a valid online domain will be skipped.`,
|
||||||
|
|
||||||
abra server add -D example`,
|
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
internal.NoDomainChecksFlag,
|
internal.NoDomainChecksFlag,
|
||||||
localFlag,
|
localFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
ArgsUsage: "<name>",
|
HideHelp: true,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
if c.Args().Len() > 0 && local || !internal.ValidateSubCmdFlags(c) {
|
if cmd.Args().Len() > 0 && local || !internal.ValidateSubCmdFlags(cmd) {
|
||||||
err := errors.New("cannot use <name> and --local together")
|
err := errors.New("cannot use <name> and --local together")
|
||||||
internal.ShowSubcommandHelpAndError(c, err)
|
internal.ShowSubcommandHelpAndError(cmd, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var name string
|
var name string
|
||||||
if local {
|
if local {
|
||||||
name = "default"
|
name = "default"
|
||||||
} else {
|
} else {
|
||||||
name = internal.ValidateDomain(c)
|
name = internal.ValidateDomain(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(d1): reasonable 5 second timeout for connections which can't
|
// NOTE(d1): reasonable 5 second timeout for connections which can't
|
||||||
|
@ -1,30 +1,31 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
"coopcloud.tech/abra/pkg/context"
|
contextPkg "coopcloud.tech/abra/pkg/context"
|
||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/docker/cli/cli/connhelper/ssh"
|
"github.com/docker/cli/cli/connhelper/ssh"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var serverListCommand = cli.Command{
|
var serverListCommand = cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List managed servers",
|
Usage: "List managed servers",
|
||||||
|
UsageText: "abra server list [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.MachineReadableFlag,
|
internal.MachineReadableFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
dockerContextStore := context.NewDefaultDockerContextStore()
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
dockerContextStore := contextPkg.NewDefaultDockerContextStore()
|
||||||
contexts, err := dockerContextStore.Store.List()
|
contexts, err := dockerContextStore.Store.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -46,14 +47,14 @@ var serverListCommand = cli.Command{
|
|||||||
var rows [][]string
|
var rows [][]string
|
||||||
for _, serverName := range serverNames {
|
for _, serverName := range serverNames {
|
||||||
var row []string
|
var row []string
|
||||||
for _, ctx := range contexts {
|
for _, dockerCtx := range contexts {
|
||||||
endpoint, err := context.GetContextEndpoint(ctx)
|
endpoint, err := contextPkg.GetContextEndpoint(dockerCtx)
|
||||||
if err != nil && strings.Contains(err.Error(), "does not exist") {
|
if err != nil && strings.Contains(err.Error(), "does not exist") {
|
||||||
// No local context found, we can continue safely
|
// No local context found, we can continue safely
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Name == serverName {
|
if dockerCtx.Name == serverName {
|
||||||
sp, err := ssh.ParseURL(endpoint)
|
sp, err := ssh.ParseURL(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var allFilter bool
|
var allFilter bool
|
||||||
@ -31,26 +31,23 @@ var volumesFilterFlag = &cli.BoolFlag{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var serverPruneCommand = cli.Command{
|
var serverPruneCommand = cli.Command{
|
||||||
Name: "prune",
|
Name: "prune",
|
||||||
Aliases: []string{"p"},
|
Aliases: []string{"p"},
|
||||||
Usage: "Prune resources on a server",
|
Usage: "Prune resources on a server",
|
||||||
Description: `
|
UsageText: "abra server prune <server> [options]",
|
||||||
Prunes unused containers, networks, and dangling images.
|
Description: `Prunes unused containers, networks, and dangling images.
|
||||||
|
|
||||||
Use "-v/--volumes" to remove volumes that are not associated with a deployed
|
Use "-v/--volumes" to remove volumes that are not associated with a deployed
|
||||||
app. This can result in unwanted data loss if not used carefully.`,
|
app. This can result in unwanted data loss if not used carefully.`,
|
||||||
ArgsUsage: "[<server>]",
|
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
allFilterFlag,
|
allFilterFlag,
|
||||||
volumesFilterFlag,
|
volumesFilterFlag,
|
||||||
internal.DebugFlag,
|
|
||||||
internal.OfflineFlag,
|
|
||||||
internal.NoInputFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.ServerNameComplete,
|
ShellComplete: autocomplete.ServerNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
serverName := internal.ValidateServer(c)
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
serverName := internal.ValidateServer(cmd)
|
||||||
|
|
||||||
cl, err := client.New(serverName)
|
cl, err := client.New(serverName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,7 +56,6 @@ app. This can result in unwanted data loss if not used carefully.`,
|
|||||||
|
|
||||||
var args filters.Args
|
var args filters.Args
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
cr, err := cl.ContainersPrune(ctx, args)
|
cr, err := cl.ContainersPrune(ctx, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
@ -9,29 +10,24 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var serverRemoveCommand = cli.Command{
|
var serverRemoveCommand = cli.Command{
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
Aliases: []string{"rm"},
|
Aliases: []string{"rm"},
|
||||||
ArgsUsage: "<server>",
|
UsageText: "abra server remove <domain> [options]",
|
||||||
Usage: "Remove a managed server",
|
Usage: "Remove a managed server",
|
||||||
Description: `
|
Description: `Remove a managed server.
|
||||||
Remove a managed server.
|
|
||||||
|
|
||||||
Abra will remove the internal bookkeeping (~/.abra/servers/...) and underlying
|
Abra will remove the internal bookkeeping ($ABRA_DIR/servers/...) and
|
||||||
client connection context. This server will then be lost in time, like tears in
|
underlying client connection context. This server will then be lost in time,
|
||||||
rain.`,
|
like tears in rain.`,
|
||||||
Flags: []cli.Flag{
|
Before: internal.SubCommandBefore,
|
||||||
internal.DebugFlag,
|
ShellComplete: autocomplete.ServerNameComplete,
|
||||||
internal.NoInputFlag,
|
HideHelp: true,
|
||||||
internal.OfflineFlag,
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
},
|
serverName := internal.ValidateServer(cmd)
|
||||||
Before: internal.SubCommandBefore,
|
|
||||||
BashComplete: autocomplete.ServerNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
serverName := internal.ValidateServer(c)
|
|
||||||
|
|
||||||
if err := client.DeleteContext(serverName); err != nil {
|
if err := client.DeleteContext(serverName); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServerCommand defines the `abra server` command and its subcommands
|
// ServerCommand defines the `abra server` command and its subcommands
|
||||||
var ServerCommand = cli.Command{
|
var ServerCommand = cli.Command{
|
||||||
Name: "server",
|
Name: "server",
|
||||||
Aliases: []string{"s"},
|
Aliases: []string{"s"},
|
||||||
Usage: "Manage servers",
|
Usage: "Manage servers",
|
||||||
Subcommands: []*cli.Command{
|
UsageText: "abra server [command] [arguments] [options]",
|
||||||
|
Commands: []*cli.Command{
|
||||||
&serverAddCommand,
|
&serverAddCommand,
|
||||||
&serverListCommand,
|
&serverListCommand,
|
||||||
&serverRemoveCommand,
|
&serverRemoveCommand,
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
dockerclient "github.com/docker/docker/client"
|
dockerclient "github.com/docker/docker/client"
|
||||||
|
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SERVER = "localhost"
|
const SERVER = "localhost"
|
||||||
@ -46,23 +46,21 @@ var allFlag = &cli.BoolFlag{
|
|||||||
|
|
||||||
// Notify checks for available upgrades
|
// Notify checks for available upgrades
|
||||||
var Notify = cli.Command{
|
var Notify = cli.Command{
|
||||||
Name: "notify",
|
Name: "notify",
|
||||||
Aliases: []string{"n"},
|
Aliases: []string{"n"},
|
||||||
Usage: "Check for available upgrades",
|
Usage: "Check for available upgrades",
|
||||||
|
UsageText: "kadabra notify [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
majorFlag,
|
majorFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Description: `
|
Description: `Notify on new versions for deployed apps.
|
||||||
Read the deployed app versions and look for new versions in the recipe
|
|
||||||
catalogue.
|
|
||||||
|
|
||||||
If a new patch/minor version is available, a notification is printed.
|
If a new patch/minor version is available, a notification is printed.
|
||||||
|
|
||||||
Use "--major" to include new major versions.`,
|
Use "--major" to include new major versions.`,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
cl, err := client.New("default")
|
cl, err := client.New("default")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -97,17 +95,14 @@ var UpgradeApp = cli.Command{
|
|||||||
Name: "upgrade",
|
Name: "upgrade",
|
||||||
Aliases: []string{"u"},
|
Aliases: []string{"u"},
|
||||||
Usage: "Upgrade apps",
|
Usage: "Upgrade apps",
|
||||||
ArgsUsage: "<stack-name> <recipe>",
|
UsageText: "kadabra notify <stack> <recipe> [options]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
internal.DebugFlag,
|
|
||||||
internal.ChaosFlag,
|
internal.ChaosFlag,
|
||||||
majorFlag,
|
majorFlag,
|
||||||
allFlag,
|
allFlag,
|
||||||
internal.OfflineFlag,
|
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Description: `
|
Description: `Upgrade an app by specifying stack name and recipe.
|
||||||
Upgrade an app by specifying stack name and recipe.
|
|
||||||
|
|
||||||
Use "--all" to upgrade every deployed app.
|
Use "--all" to upgrade every deployed app.
|
||||||
|
|
||||||
@ -118,15 +113,16 @@ available, the app is upgraded.
|
|||||||
To include major versions use the "--major" flag. You probably don't want that
|
To include major versions use the "--major" flag. You probably don't want that
|
||||||
as it will break things. Only apps that are not deployed with "--chaos" are
|
as it will break things. Only apps that are not deployed with "--chaos" are
|
||||||
upgraded, to update chaos deployments use the "--chaos" flag. Use it with care.`,
|
upgraded, to update chaos deployments use the "--chaos" flag. Use it with care.`,
|
||||||
Action: func(c *cli.Context) error {
|
HideHelp: true,
|
||||||
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
cl, err := client.New("default")
|
cl, err := client.New("default")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !updateAll {
|
if !updateAll {
|
||||||
stackName := c.Args().Get(0)
|
stackName := cmd.Args().Get(0)
|
||||||
recipeName := c.Args().Get(1)
|
recipeName := cmd.Args().Get(1)
|
||||||
err = tryUpgrade(cl, stackName, recipeName)
|
err = tryUpgrade(cl, stackName, recipeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -470,25 +466,25 @@ func upgrade(cl *dockerclient.Client, stackName, recipeName, upgradeVersion stri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAbraApp(version, commit string) *cli.App {
|
func newKadabraApp(version, commit string) *cli.Command {
|
||||||
app := &cli.App{
|
app := &cli.Command{
|
||||||
Name: "kadabra",
|
Name: "kadabra",
|
||||||
Usage: `The Co-op Cloud auto-updater
|
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
||||||
____ ____ _ _
|
Usage: "The Co-op Cloud auto-updater 🤖 🚀",
|
||||||
/ ___|___ ___ _ __ / ___| | ___ _ _ __| |
|
UsageText: "kadabra [command] [options]",
|
||||||
| | / _ \ _____ / _ \| '_ \ | | | |/ _ \| | | |/ _' |
|
UseShortOptionHandling: true,
|
||||||
| |__| (_) |_____| (_) | |_) | | |___| | (_) | |_| | (_| |
|
HideHelpCommand: true,
|
||||||
\____\___/ \___/| .__/ \____|_|\___/ \__,_|\__,_|
|
Flags: []cli.Flag{
|
||||||
|_|
|
// NOTE(d1): "GLOBAL OPTIONS" flags
|
||||||
`,
|
internal.DebugFlag,
|
||||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
},
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&Notify,
|
&Notify,
|
||||||
&UpgradeApp,
|
&UpgradeApp,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Before = func(c *cli.Context) error {
|
app.Before = func(ctx context.Context, cmd *cli.Command) error {
|
||||||
log.Logger.SetStyles(log.Styles())
|
log.Logger.SetStyles(log.Styles())
|
||||||
charmLog.SetDefault(log.Logger)
|
charmLog.SetDefault(log.Logger)
|
||||||
|
|
||||||
@ -497,14 +493,20 @@ func newAbraApp(version, commit string) *cli.App {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cli.HelpFlag = &cli.BoolFlag{
|
||||||
|
Name: "help",
|
||||||
|
Aliases: []string{"h, H"},
|
||||||
|
Usage: "Show help",
|
||||||
|
}
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunApp runs CLI abra app.
|
// RunApp runs CLI abra app.
|
||||||
func RunApp(version, commit string) {
|
func RunApp(version, commit string) {
|
||||||
app := newAbraApp(version, commit)
|
app := newKadabraApp(version, commit)
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(context.Background(), os.Args); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
go.mod
7
go.mod
@ -2,6 +2,8 @@ module coopcloud.tech/abra
|
|||||||
|
|
||||||
go 1.21
|
go 1.21
|
||||||
|
|
||||||
|
replace github.com/urfave/cli/v3 => github.com/urfave/cli/v3 v3.0.0-alpha9.1.0.20241019193437-5053ec708a44
|
||||||
|
|
||||||
require (
|
require (
|
||||||
coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb
|
coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb
|
||||||
git.coopcloud.tech/coop-cloud/godotenv v1.5.2-0.20231130100509-01bff8284355
|
git.coopcloud.tech/coop-cloud/godotenv v1.5.2-0.20231130100509-01bff8284355
|
||||||
@ -18,7 +20,7 @@ require (
|
|||||||
github.com/moby/term v0.5.0
|
github.com/moby/term v0.5.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/schollz/progressbar/v3 v3.14.4
|
github.com/schollz/progressbar/v3 v3.14.4
|
||||||
github.com/urfave/cli/v2 v2.27.2
|
github.com/urfave/cli/v3 v3.0.0-alpha9
|
||||||
golang.org/x/term v0.22.0
|
golang.org/x/term v0.22.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gotest.tools/v3 v3.5.1
|
gotest.tools/v3 v3.5.1
|
||||||
@ -37,7 +39,6 @@ require (
|
|||||||
github.com/charmbracelet/x/ansi v0.1.3 // indirect
|
github.com/charmbracelet/x/ansi v0.1.3 // indirect
|
||||||
github.com/cloudflare/circl v1.3.9 // indirect
|
github.com/cloudflare/circl v1.3.9 // indirect
|
||||||
github.com/containerd/log v0.1.0 // indirect
|
github.com/containerd/log v0.1.0 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
|
||||||
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
|
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||||
@ -85,14 +86,12 @@ require (
|
|||||||
github.com/prometheus/common v0.55.0 // indirect
|
github.com/prometheus/common v0.55.0 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
github.com/skeema/knownhosts v1.2.2 // indirect
|
github.com/skeema/knownhosts v1.2.2 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.28.0 // indirect
|
go.opentelemetry.io/otel v1.28.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect
|
||||||
|
8
go.sum
8
go.sum
@ -273,7 +273,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
|
|||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
@ -799,7 +798,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
@ -883,8 +881,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
|||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
|
github.com/urfave/cli/v3 v3.0.0-alpha9.1.0.20241019193437-5053ec708a44 h1:BeSTAZEDkDVNv9EOrycIGCkEg+6EhRRgSsbdc93Q3OM=
|
||||||
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
|
github.com/urfave/cli/v3 v3.0.0-alpha9.1.0.20241019193437-5053ec708a44/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
|
||||||
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
|
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
|
||||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||||
@ -906,8 +904,6 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
|
|||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
|
|
||||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
package autocomplete
|
package autocomplete
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"coopcloud.tech/abra/pkg/app"
|
"coopcloud.tech/abra/pkg/app"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AppNameComplete copletes app names.
|
// AppNameComplete copletes app names.
|
||||||
func AppNameComplete(c *cli.Context) {
|
func AppNameComplete(ctx context.Context, cmd *cli.Command) {
|
||||||
appNames, err := app.GetAppNames()
|
appNames, err := app.GetAppNames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err)
|
log.Warn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.NArg() > 0 {
|
if cmd.NArg() > 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,13 +37,13 @@ func ServiceNameComplete(appName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RecipeNameComplete completes recipe names.
|
// RecipeNameComplete completes recipe names.
|
||||||
func RecipeNameComplete(c *cli.Context) {
|
func RecipeNameComplete(ctx context.Context, cmd *cli.Command) {
|
||||||
catl, err := recipe.ReadRecipeCatalogue(false)
|
catl, err := recipe.ReadRecipeCatalogue(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err)
|
log.Warn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.NArg() > 0 {
|
if cmd.NArg() > 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,13 +67,13 @@ func RecipeVersionComplete(recipeName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ServerNameComplete completes server names.
|
// ServerNameComplete completes server names.
|
||||||
func ServerNameComplete(c *cli.Context) {
|
func ServerNameComplete(ctx context.Context, cmd *cli.Command) {
|
||||||
files, err := app.LoadAppFiles("")
|
files, err := app.LoadAppFiles("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.NArg() > 0 {
|
if cmd.NArg() > 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,8 +83,8 @@ func ServerNameComplete(c *cli.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SubcommandComplete completes sub-commands.
|
// SubcommandComplete completes sub-commands.
|
||||||
func SubcommandComplete(c *cli.Context) {
|
func SubcommandComplete(ctx context.Context, cmd *cli.Command) {
|
||||||
if c.NArg() > 0 {
|
if cmd.NArg() > 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,17 +2,31 @@
|
|||||||
|
|
||||||
: ${PROG:=$(basename ${BASH_SOURCE})}
|
: ${PROG:=$(basename ${BASH_SOURCE})}
|
||||||
|
|
||||||
|
# Macs have bash3 for which the bash-completion package doesn't include
|
||||||
|
# _init_completion. This is a minimal version of that function.
|
||||||
|
_cli_init_completion() {
|
||||||
|
COMPREPLY=()
|
||||||
|
_get_comp_words_by_ref "$@" cur prev words cword
|
||||||
|
}
|
||||||
|
|
||||||
_cli_bash_autocomplete() {
|
_cli_bash_autocomplete() {
|
||||||
if [[ "${COMP_WORDS[0]}" != "source" ]]; then
|
if [[ "${COMP_WORDS[0]}" != "source" ]]; then
|
||||||
local cur opts base
|
local cur opts base words
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
if [[ "$cur" == "-"* ]]; then
|
if declare -F _init_completion >/dev/null 2>&1; then
|
||||||
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion )
|
_init_completion -n "=:" || return
|
||||||
else
|
else
|
||||||
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
|
_cli_init_completion -n "=:" || return
|
||||||
fi
|
fi
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
words=("${words[@]:0:$cword}")
|
||||||
|
if [[ "$cur" == "-"* ]]; then
|
||||||
|
requestComp="${words[*]} ${cur} --generate-shell-completion"
|
||||||
|
else
|
||||||
|
requestComp="${words[*]} --generate-shell-completion"
|
||||||
|
fi
|
||||||
|
opts=$(eval "${requestComp}" 2>/dev/null)
|
||||||
|
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
function complete_abra_args
|
function complete_abra_args
|
||||||
set -l cmd (commandline -poc) --generate-bash-completion
|
set -l cmd (commandline -poc) --generate-shell-completion
|
||||||
$cmd
|
$cmd
|
||||||
end
|
end
|
||||||
complete -c abra -f -n "not __fish_seen_subcommand_from -h --help -v --version complete_abra_args" -a "(complete_abra_args)"
|
complete -c abra -f -n "not __fish_seen_subcommand_from -h --help -v --version complete_abra_args" -a "(complete_abra_args)"
|
||||||
|
@ -2,7 +2,7 @@ $fn = $($MyInvocation.MyCommand.Name)
|
|||||||
$name = $fn -replace "(.*)\.ps1$", '$1'
|
$name = $fn -replace "(.*)\.ps1$", '$1'
|
||||||
Register-ArgumentCompleter -Native -CommandName $name -ScriptBlock {
|
Register-ArgumentCompleter -Native -CommandName $name -ScriptBlock {
|
||||||
param($commandName, $wordToComplete, $cursorPosition)
|
param($commandName, $wordToComplete, $cursorPosition)
|
||||||
$other = "$wordToComplete --generate-bash-completion"
|
$other = "$wordToComplete --generate-shell-completion"
|
||||||
Invoke-Expression $other | ForEach-Object {
|
Invoke-Expression $other | ForEach-Object {
|
||||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
#compdef $PROG
|
#compdef abra
|
||||||
|
compdef _abra abra
|
||||||
|
|
||||||
_cli_zsh_autocomplete() {
|
# https://github.com/urfave/cli/blob/main/autocomplete/zsh_autocomplete
|
||||||
|
|
||||||
local -a opts
|
_abra() {
|
||||||
local cur
|
local -a opts
|
||||||
cur=${words[-1]}
|
local cur
|
||||||
if [[ "$cur" == "-"* ]]; then
|
cur=${words[-1]}
|
||||||
opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} ${cur} --generate-bash-completion)}")
|
if [[ "$cur" == "-"* ]]; then
|
||||||
else
|
opts=("${(@f)$(${words[@]:0:#words[@]-1} ${cur} --generate-shell-completion)}")
|
||||||
opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} --generate-bash-completion)}")
|
else
|
||||||
fi
|
opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-shell-completion)}")
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ "${opts[1]}" != "" ]]; then
|
if [[ "${opts[1]}" != "" ]]; then
|
||||||
_describe 'values' opts
|
_describe 'values' opts
|
||||||
else
|
else
|
||||||
_files
|
_files
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compdef _cli_zsh_autocomplete $PROG
|
# don't run the completion function when being source-ed or eval-ed
|
||||||
|
if [ "$funcstack[1]" = "_abra" ]; then
|
||||||
|
_abra
|
||||||
|
fi
|
||||||
|
1
vendor/github.com/Azure/go-ansiterm/winterm/ansi.go
generated
vendored
1
vendor/github.com/Azure/go-ansiterm/winterm/ansi.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
1
vendor/github.com/Azure/go-ansiterm/winterm/api.go
generated
vendored
1
vendor/github.com/Azure/go-ansiterm/winterm/api.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
1
vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go
generated
vendored
1
vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
1
vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go
generated
vendored
1
vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
1
vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go
generated
vendored
1
vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
1
vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go
generated
vendored
1
vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
1
vendor/github.com/Azure/go-ansiterm/winterm/utilities.go
generated
vendored
1
vendor/github.com/Azure/go-ansiterm/winterm/utilities.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
1
vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
generated
vendored
1
vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
4
vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go
generated
vendored
4
vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go
generated
vendored
@ -259,7 +259,7 @@ func (e *Entity) EncryptPrivateKeys(passphrase []byte, config *packet.Config) er
|
|||||||
var keysToEncrypt []*packet.PrivateKey
|
var keysToEncrypt []*packet.PrivateKey
|
||||||
// Add entity private key to encrypt.
|
// Add entity private key to encrypt.
|
||||||
if e.PrivateKey != nil && !e.PrivateKey.Dummy() && !e.PrivateKey.Encrypted {
|
if e.PrivateKey != nil && !e.PrivateKey.Dummy() && !e.PrivateKey.Encrypted {
|
||||||
keysToEncrypt = append(keysToEncrypt, e.PrivateKey)
|
keysToEncrypt = append(keysToEncrypt, e.PrivateKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add subkeys to encrypt.
|
// Add subkeys to encrypt.
|
||||||
@ -284,7 +284,7 @@ func (e *Entity) DecryptPrivateKeys(passphrase []byte) error {
|
|||||||
// Add subkeys to decrypt.
|
// Add subkeys to decrypt.
|
||||||
for _, sub := range e.Subkeys {
|
for _, sub := range e.Subkeys {
|
||||||
if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted {
|
if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted {
|
||||||
keysToDecrypt = append(keysToDecrypt, sub.PrivateKey)
|
keysToDecrypt = append(keysToDecrypt, sub.PrivateKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return packet.DecryptPrivateKeys(keysToDecrypt, passphrase)
|
return packet.DecryptPrivateKeys(keysToDecrypt, passphrase)
|
||||||
|
8
vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go
generated
vendored
8
vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go
generated
vendored
@ -458,7 +458,7 @@ func (pk *PrivateKey) Decrypt(passphrase []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecryptPrivateKeys decrypts all encrypted keys with the given config and passphrase.
|
// DecryptPrivateKeys decrypts all encrypted keys with the given config and passphrase.
|
||||||
// Avoids recomputation of similar s2k key derivations.
|
// Avoids recomputation of similar s2k key derivations.
|
||||||
func DecryptPrivateKeys(keys []*PrivateKey, passphrase []byte) error {
|
func DecryptPrivateKeys(keys []*PrivateKey, passphrase []byte) error {
|
||||||
// Create a cache to avoid recomputation of key derviations for the same passphrase.
|
// Create a cache to avoid recomputation of key derviations for the same passphrase.
|
||||||
s2kCache := &s2k.Cache{}
|
s2kCache := &s2k.Cache{}
|
||||||
@ -485,7 +485,7 @@ func (pk *PrivateKey) encrypt(key []byte, params *s2k.Params, cipherFunction Cip
|
|||||||
if len(key) != cipherFunction.KeySize() {
|
if len(key) != cipherFunction.KeySize() {
|
||||||
return errors.InvalidArgumentError("supplied encryption key has the wrong size")
|
return errors.InvalidArgumentError("supplied encryption key has the wrong size")
|
||||||
}
|
}
|
||||||
|
|
||||||
priv := bytes.NewBuffer(nil)
|
priv := bytes.NewBuffer(nil)
|
||||||
err := pk.serializePrivateKey(priv)
|
err := pk.serializePrivateKey(priv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -497,7 +497,7 @@ func (pk *PrivateKey) encrypt(key []byte, params *s2k.Params, cipherFunction Cip
|
|||||||
pk.s2k, err = pk.s2kParams.Function()
|
pk.s2k, err = pk.s2kParams.Function()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privateKeyBytes := priv.Bytes()
|
privateKeyBytes := priv.Bytes()
|
||||||
pk.sha1Checksum = true
|
pk.sha1Checksum = true
|
||||||
@ -581,7 +581,7 @@ func (pk *PrivateKey) Encrypt(passphrase []byte) error {
|
|||||||
S2KMode: s2k.IteratedSaltedS2K,
|
S2KMode: s2k.IteratedSaltedS2K,
|
||||||
S2KCount: 65536,
|
S2KCount: 65536,
|
||||||
Hash: crypto.SHA256,
|
Hash: crypto.SHA256,
|
||||||
},
|
} ,
|
||||||
DefaultCipher: CipherAES256,
|
DefaultCipher: CipherAES256,
|
||||||
}
|
}
|
||||||
return pk.EncryptWithConfig(passphrase, config)
|
return pk.EncryptWithConfig(passphrase, config)
|
||||||
|
19
vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
generated
vendored
19
vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
generated
vendored
@ -87,10 +87,10 @@ func decodeCount(c uint8) int {
|
|||||||
// encodeMemory converts the Argon2 "memory" in the range parallelism*8 to
|
// encodeMemory converts the Argon2 "memory" in the range parallelism*8 to
|
||||||
// 2**31, inclusive, to an encoded memory. The return value is the
|
// 2**31, inclusive, to an encoded memory. The return value is the
|
||||||
// octet that is actually stored in the GPG file. encodeMemory panics
|
// octet that is actually stored in the GPG file. encodeMemory panics
|
||||||
// if is not in the above range
|
// if is not in the above range
|
||||||
// See OpenPGP crypto refresh Section 3.7.1.4.
|
// See OpenPGP crypto refresh Section 3.7.1.4.
|
||||||
func encodeMemory(memory uint32, parallelism uint8) uint8 {
|
func encodeMemory(memory uint32, parallelism uint8) uint8 {
|
||||||
if memory < (8*uint32(parallelism)) || memory > uint32(2147483648) {
|
if memory < (8 * uint32(parallelism)) || memory > uint32(2147483648) {
|
||||||
panic("Memory argument memory is outside the required range")
|
panic("Memory argument memory is outside the required range")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,8 +199,8 @@ func Generate(rand io.Reader, c *Config) (*Params, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
params = &Params{
|
params = &Params{
|
||||||
mode: SaltedS2K,
|
mode: SaltedS2K,
|
||||||
hashId: hashId,
|
hashId: hashId,
|
||||||
}
|
}
|
||||||
} else { // Enforce IteratedSaltedS2K method otherwise
|
} else { // Enforce IteratedSaltedS2K method otherwise
|
||||||
hashId, ok := algorithm.HashToHashId(c.hash())
|
hashId, ok := algorithm.HashToHashId(c.hash())
|
||||||
@ -211,7 +211,7 @@ func Generate(rand io.Reader, c *Config) (*Params, error) {
|
|||||||
c.S2KMode = IteratedSaltedS2K
|
c.S2KMode = IteratedSaltedS2K
|
||||||
}
|
}
|
||||||
params = &Params{
|
params = &Params{
|
||||||
mode: IteratedSaltedS2K,
|
mode: IteratedSaltedS2K,
|
||||||
hashId: hashId,
|
hashId: hashId,
|
||||||
countByte: c.EncodedCount(),
|
countByte: c.EncodedCount(),
|
||||||
}
|
}
|
||||||
@ -306,12 +306,9 @@ func (params *Params) Dummy() bool {
|
|||||||
|
|
||||||
func (params *Params) salt() []byte {
|
func (params *Params) salt() []byte {
|
||||||
switch params.mode {
|
switch params.mode {
|
||||||
case SaltedS2K, IteratedSaltedS2K:
|
case SaltedS2K, IteratedSaltedS2K: return params.saltBytes[:8]
|
||||||
return params.saltBytes[:8]
|
case Argon2S2K: return params.saltBytes[:Argon2SaltSize]
|
||||||
case Argon2S2K:
|
default: return nil
|
||||||
return params.saltBytes[:Argon2SaltSize]
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go
generated
vendored
2
vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go
generated
vendored
@ -5,7 +5,7 @@ package s2k
|
|||||||
// the same parameters.
|
// the same parameters.
|
||||||
type Cache map[Params][]byte
|
type Cache map[Params][]byte
|
||||||
|
|
||||||
// GetOrComputeDerivedKey tries to retrieve the key
|
// GetOrComputeDerivedKey tries to retrieve the key
|
||||||
// for the given s2k parameters from the cache.
|
// for the given s2k parameters from the cache.
|
||||||
// If there is no hit, it derives the key with the s2k function from the passphrase,
|
// If there is no hit, it derives the key with the s2k function from the passphrase,
|
||||||
// updates the cache, and returns the key.
|
// updates the cache, and returns the key.
|
||||||
|
6
vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go
generated
vendored
6
vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go
generated
vendored
@ -50,9 +50,9 @@ type Config struct {
|
|||||||
type Argon2Config struct {
|
type Argon2Config struct {
|
||||||
NumberOfPasses uint8
|
NumberOfPasses uint8
|
||||||
DegreeOfParallelism uint8
|
DegreeOfParallelism uint8
|
||||||
// The memory parameter for Argon2 specifies desired memory usage in kibibytes.
|
// The memory parameter for Argon2 specifies desired memory usage in kibibytes.
|
||||||
// For example memory=64*1024 sets the memory cost to ~64 MB.
|
// For example memory=64*1024 sets the memory cost to ~64 MB.
|
||||||
Memory uint32
|
Memory uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Mode() Mode {
|
func (c *Config) Mode() Mode {
|
||||||
@ -115,7 +115,7 @@ func (c *Argon2Config) EncodedMemory() uint8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
memory := c.Memory
|
memory := c.Memory
|
||||||
lowerBound := uint32(c.Parallelism()) * 8
|
lowerBound := uint32(c.Parallelism())*8
|
||||||
upperBound := uint32(2147483648)
|
upperBound := uint32(2147483648)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
2
vendor/github.com/beorn7/perks/quantile/stream.go
generated
vendored
2
vendor/github.com/beorn7/perks/quantile/stream.go
generated
vendored
@ -9,7 +9,7 @@
|
|||||||
//
|
//
|
||||||
// For more detailed information about the algorithm used, see:
|
// For more detailed information about the algorithm used, see:
|
||||||
//
|
//
|
||||||
// # Effective Computation of Biased Quantiles over Data Streams
|
// Effective Computation of Biased Quantiles over Data Streams
|
||||||
//
|
//
|
||||||
// http://www.cs.rutgers.edu/~muthu/bquant.pdf
|
// http://www.cs.rutgers.edu/~muthu/bquant.pdf
|
||||||
package quantile
|
package quantile
|
||||||
|
38
vendor/github.com/cenkalti/backoff/v4/exponential.go
generated
vendored
38
vendor/github.com/cenkalti/backoff/v4/exponential.go
generated
vendored
@ -11,17 +11,17 @@ period for each retry attempt using a randomization function that grows exponent
|
|||||||
|
|
||||||
NextBackOff() is calculated using the following formula:
|
NextBackOff() is calculated using the following formula:
|
||||||
|
|
||||||
randomized interval =
|
randomized interval =
|
||||||
RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
|
RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
|
||||||
|
|
||||||
In other words NextBackOff() will range between the randomization factor
|
In other words NextBackOff() will range between the randomization factor
|
||||||
percentage below and above the retry interval.
|
percentage below and above the retry interval.
|
||||||
|
|
||||||
For example, given the following parameters:
|
For example, given the following parameters:
|
||||||
|
|
||||||
RetryInterval = 2
|
RetryInterval = 2
|
||||||
RandomizationFactor = 0.5
|
RandomizationFactor = 0.5
|
||||||
Multiplier = 2
|
Multiplier = 2
|
||||||
|
|
||||||
the actual backoff period used in the next retry attempt will range between 1 and 3 seconds,
|
the actual backoff period used in the next retry attempt will range between 1 and 3 seconds,
|
||||||
multiplied by the exponential, that is, between 2 and 6 seconds.
|
multiplied by the exponential, that is, between 2 and 6 seconds.
|
||||||
@ -36,18 +36,18 @@ The elapsed time can be reset by calling Reset().
|
|||||||
Example: Given the following default arguments, for 10 tries the sequence will be,
|
Example: Given the following default arguments, for 10 tries the sequence will be,
|
||||||
and assuming we go over the MaxElapsedTime on the 10th try:
|
and assuming we go over the MaxElapsedTime on the 10th try:
|
||||||
|
|
||||||
Request # RetryInterval (seconds) Randomized Interval (seconds)
|
Request # RetryInterval (seconds) Randomized Interval (seconds)
|
||||||
|
|
||||||
1 0.5 [0.25, 0.75]
|
1 0.5 [0.25, 0.75]
|
||||||
2 0.75 [0.375, 1.125]
|
2 0.75 [0.375, 1.125]
|
||||||
3 1.125 [0.562, 1.687]
|
3 1.125 [0.562, 1.687]
|
||||||
4 1.687 [0.8435, 2.53]
|
4 1.687 [0.8435, 2.53]
|
||||||
5 2.53 [1.265, 3.795]
|
5 2.53 [1.265, 3.795]
|
||||||
6 3.795 [1.897, 5.692]
|
6 3.795 [1.897, 5.692]
|
||||||
7 5.692 [2.846, 8.538]
|
7 5.692 [2.846, 8.538]
|
||||||
8 8.538 [4.269, 12.807]
|
8 8.538 [4.269, 12.807]
|
||||||
9 12.807 [6.403, 19.210]
|
9 12.807 [6.403, 19.210]
|
||||||
10 19.210 backoff.Stop
|
10 19.210 backoff.Stop
|
||||||
|
|
||||||
Note: Implementation is not thread-safe.
|
Note: Implementation is not thread-safe.
|
||||||
*/
|
*/
|
||||||
@ -167,8 +167,7 @@ func (b *ExponentialBackOff) Reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NextBackOff calculates the next backoff interval using the formula:
|
// NextBackOff calculates the next backoff interval using the formula:
|
||||||
//
|
// Randomized interval = RetryInterval * (1 ± RandomizationFactor)
|
||||||
// Randomized interval = RetryInterval * (1 ± RandomizationFactor)
|
|
||||||
func (b *ExponentialBackOff) NextBackOff() time.Duration {
|
func (b *ExponentialBackOff) NextBackOff() time.Duration {
|
||||||
// Make sure we have not gone over the maximum elapsed time.
|
// Make sure we have not gone over the maximum elapsed time.
|
||||||
elapsed := b.GetElapsedTime()
|
elapsed := b.GetElapsedTime()
|
||||||
@ -201,8 +200,7 @@ func (b *ExponentialBackOff) incrementCurrentInterval() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a random value from the following interval:
|
// Returns a random value from the following interval:
|
||||||
//
|
// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval].
|
||||||
// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval].
|
|
||||||
func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration {
|
func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration {
|
||||||
if randomizationFactor == 0 {
|
if randomizationFactor == 0 {
|
||||||
return currentInterval // make sure no randomness is used when randomizationFactor is 0.
|
return currentInterval // make sure no randomness is used when randomizationFactor is 0.
|
||||||
|
4
vendor/github.com/containers/image/docker/reference/reference.go
generated
vendored
4
vendor/github.com/containers/image/docker/reference/reference.go
generated
vendored
@ -3,13 +3,13 @@
|
|||||||
//
|
//
|
||||||
// Grammar
|
// Grammar
|
||||||
//
|
//
|
||||||
// reference := name [ ":" tag ] [ "@" digest ]
|
// reference := name [ ":" tag ] [ "@" digest ]
|
||||||
// name := [domain '/'] path-component ['/' path-component]*
|
// name := [domain '/'] path-component ['/' path-component]*
|
||||||
// domain := domain-component ['.' domain-component]* [':' port-number]
|
// domain := domain-component ['.' domain-component]* [':' port-number]
|
||||||
// domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
|
// domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
|
||||||
// port-number := /[0-9]+/
|
// port-number := /[0-9]+/
|
||||||
// path-component := alpha-numeric [separator alpha-numeric]*
|
// path-component := alpha-numeric [separator alpha-numeric]*
|
||||||
// alpha-numeric := /[a-z0-9]+/
|
// alpha-numeric := /[a-z0-9]+/
|
||||||
// separator := /[_.]|__|[-]*/
|
// separator := /[_.]|__|[-]*/
|
||||||
//
|
//
|
||||||
// tag := /[\w][\w.-]{0,127}/
|
// tag := /[\w][\w.-]{0,127}/
|
||||||
|
1
vendor/github.com/containers/image/pkg/docker/config/config_unsupported.go
generated
vendored
1
vendor/github.com/containers/image/pkg/docker/config/config_unsupported.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build !linux && (!386 || !amd64)
|
|
||||||
// +build !linux
|
// +build !linux
|
||||||
// +build !386 !amd64
|
// +build !386 !amd64
|
||||||
|
|
||||||
|
1
vendor/github.com/containers/image/pkg/keyctl/key.go
generated
vendored
1
vendor/github.com/containers/image/pkg/keyctl/key.go
generated
vendored
@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build linux
|
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package keyctl
|
package keyctl
|
||||||
|
1
vendor/github.com/containers/image/pkg/keyctl/keyring.go
generated
vendored
1
vendor/github.com/containers/image/pkg/keyctl/keyring.go
generated
vendored
@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build linux
|
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
// Package keyctl is a Go interface to linux kernel keyrings (keyctl interface)
|
// Package keyctl is a Go interface to linux kernel keyrings (keyctl interface)
|
||||||
|
1
vendor/github.com/containers/image/pkg/keyctl/perm.go
generated
vendored
1
vendor/github.com/containers/image/pkg/keyctl/perm.go
generated
vendored
@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build linux
|
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package keyctl
|
package keyctl
|
||||||
|
1
vendor/github.com/containers/image/pkg/keyctl/sys_linux.go
generated
vendored
1
vendor/github.com/containers/image/pkg/keyctl/sys_linux.go
generated
vendored
@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build linux
|
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package keyctl
|
package keyctl
|
||||||
|
29
vendor/github.com/containers/image/types/types.go
generated
vendored
29
vendor/github.com/containers/image/types/types.go
generated
vendored
@ -131,25 +131,24 @@ type BICReplacementCandidate struct {
|
|||||||
// BlobInfoCache records data useful for reusing blobs, or substituing equivalent ones, to avoid unnecessary blob copies.
|
// BlobInfoCache records data useful for reusing blobs, or substituing equivalent ones, to avoid unnecessary blob copies.
|
||||||
//
|
//
|
||||||
// It records two kinds of data:
|
// It records two kinds of data:
|
||||||
|
// - Sets of corresponding digest vs. uncompressed digest ("DiffID") pairs:
|
||||||
|
// One of the two digests is known to be uncompressed, and a single uncompressed digest may correspond to more than one compressed digest.
|
||||||
|
// This allows matching compressed layer blobs to existing local uncompressed layers (to avoid unnecessary download and decompresssion),
|
||||||
|
// or uncompressed layer blobs to existing remote compressed layers (to avoid unnecessary compression and upload)/
|
||||||
//
|
//
|
||||||
// - Sets of corresponding digest vs. uncompressed digest ("DiffID") pairs:
|
// It is allowed to record an (uncompressed digest, the same uncompressed digest) correspondence, to express that the digest is known
|
||||||
// One of the two digests is known to be uncompressed, and a single uncompressed digest may correspond to more than one compressed digest.
|
// to be uncompressed (i.e. that a conversion from schema1 does not have to decompress the blob to compute a DiffID value).
|
||||||
// This allows matching compressed layer blobs to existing local uncompressed layers (to avoid unnecessary download and decompresssion),
|
|
||||||
// or uncompressed layer blobs to existing remote compressed layers (to avoid unnecessary compression and upload)/
|
|
||||||
//
|
//
|
||||||
// It is allowed to record an (uncompressed digest, the same uncompressed digest) correspondence, to express that the digest is known
|
// This mapping is primarily maintained in generic copy.Image code, but transports may want to contribute more data points if they independently
|
||||||
// to be uncompressed (i.e. that a conversion from schema1 does not have to decompress the blob to compute a DiffID value).
|
// compress/decompress blobs for their own purposes.
|
||||||
//
|
//
|
||||||
// This mapping is primarily maintained in generic copy.Image code, but transports may want to contribute more data points if they independently
|
// - Known blob locations, managed by individual transports:
|
||||||
// compress/decompress blobs for their own purposes.
|
// The transports call RecordKnownLocation when encountering a blob that could possibly be reused (typically in GetBlob/PutBlob/TryReusingBlob),
|
||||||
|
// recording transport-specific information that allows the transport to reuse the blob in the future;
|
||||||
|
// then, TryReusingBlob implementations can call CandidateLocations to look up previously recorded blob locations that could be reused.
|
||||||
//
|
//
|
||||||
// - Known blob locations, managed by individual transports:
|
// Each transport defines its own “scopes” within which blob reuse is possible (e.g. in, the docker/distribution case, blobs
|
||||||
// The transports call RecordKnownLocation when encountering a blob that could possibly be reused (typically in GetBlob/PutBlob/TryReusingBlob),
|
// can be directly reused within a registry, or mounted across registries within a registry server.)
|
||||||
// recording transport-specific information that allows the transport to reuse the blob in the future;
|
|
||||||
// then, TryReusingBlob implementations can call CandidateLocations to look up previously recorded blob locations that could be reused.
|
|
||||||
//
|
|
||||||
// Each transport defines its own “scopes” within which blob reuse is possible (e.g. in, the docker/distribution case, blobs
|
|
||||||
// can be directly reused within a registry, or mounted across registries within a registry server.)
|
|
||||||
//
|
//
|
||||||
// None of the methods return an error indication: errors when neither reading from, nor writing to, the cache, should be fatal;
|
// None of the methods return an error indication: errors when neither reading from, nor writing to, the cache, should be fatal;
|
||||||
// users of the cahce should just fall back to copying the blobs the usual way.
|
// users of the cahce should just fall back to copying the blobs the usual way.
|
||||||
|
21
vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
generated
vendored
21
vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2014 Brian Goff
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
16
vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
generated
vendored
16
vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
package md2man
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/russross/blackfriday/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Render converts a markdown document into a roff formatted document.
|
|
||||||
func Render(doc []byte) []byte {
|
|
||||||
renderer := NewRoffRenderer()
|
|
||||||
|
|
||||||
return blackfriday.Run(doc,
|
|
||||||
[]blackfriday.Option{
|
|
||||||
blackfriday.WithRenderer(renderer),
|
|
||||||
blackfriday.WithExtensions(renderer.GetExtensions()),
|
|
||||||
}...)
|
|
||||||
}
|
|
382
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
generated
vendored
382
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
generated
vendored
@ -1,382 +0,0 @@
|
|||||||
package md2man
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/russross/blackfriday/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// roffRenderer implements the blackfriday.Renderer interface for creating
|
|
||||||
// roff format (manpages) from markdown text
|
|
||||||
type roffRenderer struct {
|
|
||||||
extensions blackfriday.Extensions
|
|
||||||
listCounters []int
|
|
||||||
firstHeader bool
|
|
||||||
firstDD bool
|
|
||||||
listDepth int
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
titleHeader = ".TH "
|
|
||||||
topLevelHeader = "\n\n.SH "
|
|
||||||
secondLevelHdr = "\n.SH "
|
|
||||||
otherHeader = "\n.SS "
|
|
||||||
crTag = "\n"
|
|
||||||
emphTag = "\\fI"
|
|
||||||
emphCloseTag = "\\fP"
|
|
||||||
strongTag = "\\fB"
|
|
||||||
strongCloseTag = "\\fP"
|
|
||||||
breakTag = "\n.br\n"
|
|
||||||
paraTag = "\n.PP\n"
|
|
||||||
hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n"
|
|
||||||
linkTag = "\n\\[la]"
|
|
||||||
linkCloseTag = "\\[ra]"
|
|
||||||
codespanTag = "\\fB"
|
|
||||||
codespanCloseTag = "\\fR"
|
|
||||||
codeTag = "\n.EX\n"
|
|
||||||
codeCloseTag = ".EE\n" // Do not prepend a newline character since code blocks, by definition, include a newline already (or at least as how blackfriday gives us on).
|
|
||||||
quoteTag = "\n.PP\n.RS\n"
|
|
||||||
quoteCloseTag = "\n.RE\n"
|
|
||||||
listTag = "\n.RS\n"
|
|
||||||
listCloseTag = "\n.RE\n"
|
|
||||||
dtTag = "\n.TP\n"
|
|
||||||
dd2Tag = "\n"
|
|
||||||
tableStart = "\n.TS\nallbox;\n"
|
|
||||||
tableEnd = ".TE\n"
|
|
||||||
tableCellStart = "T{\n"
|
|
||||||
tableCellEnd = "\nT}\n"
|
|
||||||
tablePreprocessor = `'\" t`
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewRoffRenderer creates a new blackfriday Renderer for generating roff documents
|
|
||||||
// from markdown
|
|
||||||
func NewRoffRenderer() *roffRenderer { // nolint: golint
|
|
||||||
var extensions blackfriday.Extensions
|
|
||||||
|
|
||||||
extensions |= blackfriday.NoIntraEmphasis
|
|
||||||
extensions |= blackfriday.Tables
|
|
||||||
extensions |= blackfriday.FencedCode
|
|
||||||
extensions |= blackfriday.SpaceHeadings
|
|
||||||
extensions |= blackfriday.Footnotes
|
|
||||||
extensions |= blackfriday.Titleblock
|
|
||||||
extensions |= blackfriday.DefinitionLists
|
|
||||||
return &roffRenderer{
|
|
||||||
extensions: extensions,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetExtensions returns the list of extensions used by this renderer implementation
|
|
||||||
func (r *roffRenderer) GetExtensions() blackfriday.Extensions {
|
|
||||||
return r.extensions
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenderHeader handles outputting the header at document start
|
|
||||||
func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) {
|
|
||||||
// We need to walk the tree to check if there are any tables.
|
|
||||||
// If there are, we need to enable the roff table preprocessor.
|
|
||||||
ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
|
|
||||||
if node.Type == blackfriday.Table {
|
|
||||||
out(w, tablePreprocessor+"\n")
|
|
||||||
return blackfriday.Terminate
|
|
||||||
}
|
|
||||||
return blackfriday.GoToNext
|
|
||||||
})
|
|
||||||
|
|
||||||
// disable hyphenation
|
|
||||||
out(w, ".nh\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenderFooter handles outputting the footer at the document end; the roff
|
|
||||||
// renderer has no footer information
|
|
||||||
func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenderNode is called for each node in a markdown document; based on the node
|
|
||||||
// type the equivalent roff output is sent to the writer
|
|
||||||
func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
|
|
||||||
walkAction := blackfriday.GoToNext
|
|
||||||
|
|
||||||
switch node.Type {
|
|
||||||
case blackfriday.Text:
|
|
||||||
escapeSpecialChars(w, node.Literal)
|
|
||||||
case blackfriday.Softbreak:
|
|
||||||
out(w, crTag)
|
|
||||||
case blackfriday.Hardbreak:
|
|
||||||
out(w, breakTag)
|
|
||||||
case blackfriday.Emph:
|
|
||||||
if entering {
|
|
||||||
out(w, emphTag)
|
|
||||||
} else {
|
|
||||||
out(w, emphCloseTag)
|
|
||||||
}
|
|
||||||
case blackfriday.Strong:
|
|
||||||
if entering {
|
|
||||||
out(w, strongTag)
|
|
||||||
} else {
|
|
||||||
out(w, strongCloseTag)
|
|
||||||
}
|
|
||||||
case blackfriday.Link:
|
|
||||||
// Don't render the link text for automatic links, because this
|
|
||||||
// will only duplicate the URL in the roff output.
|
|
||||||
// See https://daringfireball.net/projects/markdown/syntax#autolink
|
|
||||||
if !bytes.Equal(node.LinkData.Destination, node.FirstChild.Literal) {
|
|
||||||
out(w, string(node.FirstChild.Literal))
|
|
||||||
}
|
|
||||||
// Hyphens in a link must be escaped to avoid word-wrap in the rendered man page.
|
|
||||||
escapedLink := strings.ReplaceAll(string(node.LinkData.Destination), "-", "\\-")
|
|
||||||
out(w, linkTag+escapedLink+linkCloseTag)
|
|
||||||
walkAction = blackfriday.SkipChildren
|
|
||||||
case blackfriday.Image:
|
|
||||||
// ignore images
|
|
||||||
walkAction = blackfriday.SkipChildren
|
|
||||||
case blackfriday.Code:
|
|
||||||
out(w, codespanTag)
|
|
||||||
escapeSpecialChars(w, node.Literal)
|
|
||||||
out(w, codespanCloseTag)
|
|
||||||
case blackfriday.Document:
|
|
||||||
break
|
|
||||||
case blackfriday.Paragraph:
|
|
||||||
// roff .PP markers break lists
|
|
||||||
if r.listDepth > 0 {
|
|
||||||
return blackfriday.GoToNext
|
|
||||||
}
|
|
||||||
if entering {
|
|
||||||
out(w, paraTag)
|
|
||||||
} else {
|
|
||||||
out(w, crTag)
|
|
||||||
}
|
|
||||||
case blackfriday.BlockQuote:
|
|
||||||
if entering {
|
|
||||||
out(w, quoteTag)
|
|
||||||
} else {
|
|
||||||
out(w, quoteCloseTag)
|
|
||||||
}
|
|
||||||
case blackfriday.Heading:
|
|
||||||
r.handleHeading(w, node, entering)
|
|
||||||
case blackfriday.HorizontalRule:
|
|
||||||
out(w, hruleTag)
|
|
||||||
case blackfriday.List:
|
|
||||||
r.handleList(w, node, entering)
|
|
||||||
case blackfriday.Item:
|
|
||||||
r.handleItem(w, node, entering)
|
|
||||||
case blackfriday.CodeBlock:
|
|
||||||
out(w, codeTag)
|
|
||||||
escapeSpecialChars(w, node.Literal)
|
|
||||||
out(w, codeCloseTag)
|
|
||||||
case blackfriday.Table:
|
|
||||||
r.handleTable(w, node, entering)
|
|
||||||
case blackfriday.TableHead:
|
|
||||||
case blackfriday.TableBody:
|
|
||||||
case blackfriday.TableRow:
|
|
||||||
// no action as cell entries do all the nroff formatting
|
|
||||||
return blackfriday.GoToNext
|
|
||||||
case blackfriday.TableCell:
|
|
||||||
r.handleTableCell(w, node, entering)
|
|
||||||
case blackfriday.HTMLSpan:
|
|
||||||
// ignore other HTML tags
|
|
||||||
case blackfriday.HTMLBlock:
|
|
||||||
if bytes.HasPrefix(node.Literal, []byte("<!--")) {
|
|
||||||
break // ignore comments, no warning
|
|
||||||
}
|
|
||||||
fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String())
|
|
||||||
default:
|
|
||||||
fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String())
|
|
||||||
}
|
|
||||||
return walkAction
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) {
|
|
||||||
if entering {
|
|
||||||
switch node.Level {
|
|
||||||
case 1:
|
|
||||||
if !r.firstHeader {
|
|
||||||
out(w, titleHeader)
|
|
||||||
r.firstHeader = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
out(w, topLevelHeader)
|
|
||||||
case 2:
|
|
||||||
out(w, secondLevelHdr)
|
|
||||||
default:
|
|
||||||
out(w, otherHeader)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) {
|
|
||||||
openTag := listTag
|
|
||||||
closeTag := listCloseTag
|
|
||||||
if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
|
|
||||||
// tags for definition lists handled within Item node
|
|
||||||
openTag = ""
|
|
||||||
closeTag = ""
|
|
||||||
}
|
|
||||||
if entering {
|
|
||||||
r.listDepth++
|
|
||||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
|
||||||
r.listCounters = append(r.listCounters, 1)
|
|
||||||
}
|
|
||||||
out(w, openTag)
|
|
||||||
} else {
|
|
||||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
|
||||||
r.listCounters = r.listCounters[:len(r.listCounters)-1]
|
|
||||||
}
|
|
||||||
out(w, closeTag)
|
|
||||||
r.listDepth--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) {
|
|
||||||
if entering {
|
|
||||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
|
||||||
out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1]))
|
|
||||||
r.listCounters[len(r.listCounters)-1]++
|
|
||||||
} else if node.ListFlags&blackfriday.ListTypeTerm != 0 {
|
|
||||||
// DT (definition term): line just before DD (see below).
|
|
||||||
out(w, dtTag)
|
|
||||||
r.firstDD = true
|
|
||||||
} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
|
|
||||||
// DD (definition description): line that starts with ": ".
|
|
||||||
//
|
|
||||||
// We have to distinguish between the first DD and the
|
|
||||||
// subsequent ones, as there should be no vertical
|
|
||||||
// whitespace between the DT and the first DD.
|
|
||||||
if r.firstDD {
|
|
||||||
r.firstDD = false
|
|
||||||
} else {
|
|
||||||
out(w, dd2Tag)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out(w, ".IP \\(bu 2\n")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out(w, "\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) {
|
|
||||||
if entering {
|
|
||||||
out(w, tableStart)
|
|
||||||
// call walker to count cells (and rows?) so format section can be produced
|
|
||||||
columns := countColumns(node)
|
|
||||||
out(w, strings.Repeat("l ", columns)+"\n")
|
|
||||||
out(w, strings.Repeat("l ", columns)+".\n")
|
|
||||||
} else {
|
|
||||||
out(w, tableEnd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) {
|
|
||||||
if entering {
|
|
||||||
var start string
|
|
||||||
if node.Prev != nil && node.Prev.Type == blackfriday.TableCell {
|
|
||||||
start = "\t"
|
|
||||||
}
|
|
||||||
if node.IsHeader {
|
|
||||||
start += strongTag
|
|
||||||
} else if nodeLiteralSize(node) > 30 {
|
|
||||||
start += tableCellStart
|
|
||||||
}
|
|
||||||
out(w, start)
|
|
||||||
} else {
|
|
||||||
var end string
|
|
||||||
if node.IsHeader {
|
|
||||||
end = strongCloseTag
|
|
||||||
} else if nodeLiteralSize(node) > 30 {
|
|
||||||
end = tableCellEnd
|
|
||||||
}
|
|
||||||
if node.Next == nil && end != tableCellEnd {
|
|
||||||
// Last cell: need to carriage return if we are at the end of the
|
|
||||||
// header row and content isn't wrapped in a "tablecell"
|
|
||||||
end += crTag
|
|
||||||
}
|
|
||||||
out(w, end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeLiteralSize(node *blackfriday.Node) int {
|
|
||||||
total := 0
|
|
||||||
for n := node.FirstChild; n != nil; n = n.FirstChild {
|
|
||||||
total += len(n.Literal)
|
|
||||||
}
|
|
||||||
return total
|
|
||||||
}
|
|
||||||
|
|
||||||
// because roff format requires knowing the column count before outputting any table
|
|
||||||
// data we need to walk a table tree and count the columns
|
|
||||||
func countColumns(node *blackfriday.Node) int {
|
|
||||||
var columns int
|
|
||||||
|
|
||||||
node.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
|
|
||||||
switch node.Type {
|
|
||||||
case blackfriday.TableRow:
|
|
||||||
if !entering {
|
|
||||||
return blackfriday.Terminate
|
|
||||||
}
|
|
||||||
case blackfriday.TableCell:
|
|
||||||
if entering {
|
|
||||||
columns++
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
return blackfriday.GoToNext
|
|
||||||
})
|
|
||||||
return columns
|
|
||||||
}
|
|
||||||
|
|
||||||
func out(w io.Writer, output string) {
|
|
||||||
io.WriteString(w, output) // nolint: errcheck
|
|
||||||
}
|
|
||||||
|
|
||||||
func escapeSpecialChars(w io.Writer, text []byte) {
|
|
||||||
scanner := bufio.NewScanner(bytes.NewReader(text))
|
|
||||||
|
|
||||||
// count the number of lines in the text
|
|
||||||
// we need to know this to avoid adding a newline after the last line
|
|
||||||
n := bytes.Count(text, []byte{'\n'})
|
|
||||||
idx := 0
|
|
||||||
|
|
||||||
for scanner.Scan() {
|
|
||||||
dt := scanner.Bytes()
|
|
||||||
if idx < n {
|
|
||||||
idx++
|
|
||||||
dt = append(dt, '\n')
|
|
||||||
}
|
|
||||||
escapeSpecialCharsLine(w, dt)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func escapeSpecialCharsLine(w io.Writer, text []byte) {
|
|
||||||
for i := 0; i < len(text); i++ {
|
|
||||||
// escape initial apostrophe or period
|
|
||||||
if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') {
|
|
||||||
out(w, "\\&")
|
|
||||||
}
|
|
||||||
|
|
||||||
// directly copy normal characters
|
|
||||||
org := i
|
|
||||||
|
|
||||||
for i < len(text) && text[i] != '\\' {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if i > org {
|
|
||||||
w.Write(text[org:i]) // nolint: errcheck
|
|
||||||
}
|
|
||||||
|
|
||||||
// escape a character
|
|
||||||
if i >= len(text) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write([]byte{'\\', text[i]}) // nolint: errcheck
|
|
||||||
}
|
|
||||||
}
|
|
1
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
1
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
@ -18,7 +18,6 @@
|
|||||||
// tag is deprecated and thus should not be used.
|
// tag is deprecated and thus should not be used.
|
||||||
// Go versions prior to 1.4 are disabled because they use a different layout
|
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||||
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||||
//go:build !js && !appengine && !safe && !disableunsafe && go1.4
|
|
||||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||||
|
|
||||||
package spew
|
package spew
|
||||||
|
1
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
1
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
@ -16,7 +16,6 @@
|
|||||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||||
// tag is deprecated and thus should not be used.
|
// tag is deprecated and thus should not be used.
|
||||||
//go:build js || appengine || safe || disableunsafe || !go1.4
|
|
||||||
// +build js appengine safe disableunsafe !go1.4
|
// +build js appengine safe disableunsafe !go1.4
|
||||||
|
|
||||||
package spew
|
package spew
|
||||||
|
30
vendor/github.com/davecgh/go-spew/spew/config.go
generated
vendored
30
vendor/github.com/davecgh/go-spew/spew/config.go
generated
vendored
@ -254,15 +254,15 @@ pointer addresses used to indirect to the final value. It provides the
|
|||||||
following features over the built-in printing facilities provided by the fmt
|
following features over the built-in printing facilities provided by the fmt
|
||||||
package:
|
package:
|
||||||
|
|
||||||
- Pointers are dereferenced and followed
|
* Pointers are dereferenced and followed
|
||||||
- Circular data structures are detected and handled properly
|
* Circular data structures are detected and handled properly
|
||||||
- Custom Stringer/error interfaces are optionally invoked, including
|
* Custom Stringer/error interfaces are optionally invoked, including
|
||||||
on unexported types
|
on unexported types
|
||||||
- Custom types which only implement the Stringer/error interfaces via
|
* Custom types which only implement the Stringer/error interfaces via
|
||||||
a pointer receiver are optionally invoked when passing non-pointer
|
a pointer receiver are optionally invoked when passing non-pointer
|
||||||
variables
|
variables
|
||||||
- Byte arrays and slices are dumped like the hexdump -C command which
|
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||||
includes offsets, byte values in hex, and ASCII output
|
includes offsets, byte values in hex, and ASCII output
|
||||||
|
|
||||||
The configuration options are controlled by modifying the public members
|
The configuration options are controlled by modifying the public members
|
||||||
of c. See ConfigState for options documentation.
|
of c. See ConfigState for options documentation.
|
||||||
@ -295,12 +295,12 @@ func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{})
|
|||||||
|
|
||||||
// NewDefaultConfig returns a ConfigState with the following default settings.
|
// NewDefaultConfig returns a ConfigState with the following default settings.
|
||||||
//
|
//
|
||||||
// Indent: " "
|
// Indent: " "
|
||||||
// MaxDepth: 0
|
// MaxDepth: 0
|
||||||
// DisableMethods: false
|
// DisableMethods: false
|
||||||
// DisablePointerMethods: false
|
// DisablePointerMethods: false
|
||||||
// ContinueOnMethod: false
|
// ContinueOnMethod: false
|
||||||
// SortKeys: false
|
// SortKeys: false
|
||||||
func NewDefaultConfig() *ConfigState {
|
func NewDefaultConfig() *ConfigState {
|
||||||
return &ConfigState{Indent: " "}
|
return &ConfigState{Indent: " "}
|
||||||
}
|
}
|
||||||
|
128
vendor/github.com/davecgh/go-spew/spew/doc.go
generated
vendored
128
vendor/github.com/davecgh/go-spew/spew/doc.go
generated
vendored
@ -21,36 +21,35 @@ debugging.
|
|||||||
A quick overview of the additional features spew provides over the built-in
|
A quick overview of the additional features spew provides over the built-in
|
||||||
printing facilities for Go data types are as follows:
|
printing facilities for Go data types are as follows:
|
||||||
|
|
||||||
- Pointers are dereferenced and followed
|
* Pointers are dereferenced and followed
|
||||||
- Circular data structures are detected and handled properly
|
* Circular data structures are detected and handled properly
|
||||||
- Custom Stringer/error interfaces are optionally invoked, including
|
* Custom Stringer/error interfaces are optionally invoked, including
|
||||||
on unexported types
|
on unexported types
|
||||||
- Custom types which only implement the Stringer/error interfaces via
|
* Custom types which only implement the Stringer/error interfaces via
|
||||||
a pointer receiver are optionally invoked when passing non-pointer
|
a pointer receiver are optionally invoked when passing non-pointer
|
||||||
variables
|
variables
|
||||||
- Byte arrays and slices are dumped like the hexdump -C command which
|
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||||
includes offsets, byte values in hex, and ASCII output (only when using
|
includes offsets, byte values in hex, and ASCII output (only when using
|
||||||
Dump style)
|
Dump style)
|
||||||
|
|
||||||
There are two different approaches spew allows for dumping Go data structures:
|
There are two different approaches spew allows for dumping Go data structures:
|
||||||
|
|
||||||
- Dump style which prints with newlines, customizable indentation,
|
* Dump style which prints with newlines, customizable indentation,
|
||||||
and additional debug information such as types and all pointer addresses
|
and additional debug information such as types and all pointer addresses
|
||||||
used to indirect to the final value
|
used to indirect to the final value
|
||||||
- A custom Formatter interface that integrates cleanly with the standard fmt
|
* A custom Formatter interface that integrates cleanly with the standard fmt
|
||||||
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
|
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
|
||||||
similar to the default %v while providing the additional functionality
|
similar to the default %v while providing the additional functionality
|
||||||
outlined above and passing unsupported format verbs such as %x and %q
|
outlined above and passing unsupported format verbs such as %x and %q
|
||||||
along to fmt
|
along to fmt
|
||||||
|
|
||||||
# Quick Start
|
Quick Start
|
||||||
|
|
||||||
This section demonstrates how to quickly get started with spew. See the
|
This section demonstrates how to quickly get started with spew. See the
|
||||||
sections below for further details on formatting and configuration options.
|
sections below for further details on formatting and configuration options.
|
||||||
|
|
||||||
To dump a variable with full newlines, indentation, type, and pointer
|
To dump a variable with full newlines, indentation, type, and pointer
|
||||||
information use Dump, Fdump, or Sdump:
|
information use Dump, Fdump, or Sdump:
|
||||||
|
|
||||||
spew.Dump(myVar1, myVar2, ...)
|
spew.Dump(myVar1, myVar2, ...)
|
||||||
spew.Fdump(someWriter, myVar1, myVar2, ...)
|
spew.Fdump(someWriter, myVar1, myVar2, ...)
|
||||||
str := spew.Sdump(myVar1, myVar2, ...)
|
str := spew.Sdump(myVar1, myVar2, ...)
|
||||||
@ -59,13 +58,12 @@ Alternatively, if you would prefer to use format strings with a compacted inline
|
|||||||
printing style, use the convenience wrappers Printf, Fprintf, etc with
|
printing style, use the convenience wrappers Printf, Fprintf, etc with
|
||||||
%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
|
%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
|
||||||
%#+v (adds types and pointer addresses):
|
%#+v (adds types and pointer addresses):
|
||||||
|
|
||||||
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||||
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||||
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||||
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||||
|
|
||||||
# Configuration Options
|
Configuration Options
|
||||||
|
|
||||||
Configuration of spew is handled by fields in the ConfigState type. For
|
Configuration of spew is handled by fields in the ConfigState type. For
|
||||||
convenience, all of the top-level functions use a global state available
|
convenience, all of the top-level functions use a global state available
|
||||||
@ -76,52 +74,51 @@ equivalent to the top-level functions. This allows concurrent configuration
|
|||||||
options. See the ConfigState documentation for more details.
|
options. See the ConfigState documentation for more details.
|
||||||
|
|
||||||
The following configuration options are available:
|
The following configuration options are available:
|
||||||
|
* Indent
|
||||||
|
String to use for each indentation level for Dump functions.
|
||||||
|
It is a single space by default. A popular alternative is "\t".
|
||||||
|
|
||||||
- Indent
|
* MaxDepth
|
||||||
String to use for each indentation level for Dump functions.
|
Maximum number of levels to descend into nested data structures.
|
||||||
It is a single space by default. A popular alternative is "\t".
|
There is no limit by default.
|
||||||
|
|
||||||
- MaxDepth
|
* DisableMethods
|
||||||
Maximum number of levels to descend into nested data structures.
|
Disables invocation of error and Stringer interface methods.
|
||||||
There is no limit by default.
|
Method invocation is enabled by default.
|
||||||
|
|
||||||
- DisableMethods
|
* DisablePointerMethods
|
||||||
Disables invocation of error and Stringer interface methods.
|
Disables invocation of error and Stringer interface methods on types
|
||||||
Method invocation is enabled by default.
|
which only accept pointer receivers from non-pointer variables.
|
||||||
|
Pointer method invocation is enabled by default.
|
||||||
|
|
||||||
- DisablePointerMethods
|
* DisablePointerAddresses
|
||||||
Disables invocation of error and Stringer interface methods on types
|
DisablePointerAddresses specifies whether to disable the printing of
|
||||||
which only accept pointer receivers from non-pointer variables.
|
pointer addresses. This is useful when diffing data structures in tests.
|
||||||
Pointer method invocation is enabled by default.
|
|
||||||
|
|
||||||
- DisablePointerAddresses
|
* DisableCapacities
|
||||||
DisablePointerAddresses specifies whether to disable the printing of
|
DisableCapacities specifies whether to disable the printing of
|
||||||
pointer addresses. This is useful when diffing data structures in tests.
|
capacities for arrays, slices, maps and channels. This is useful when
|
||||||
|
diffing data structures in tests.
|
||||||
|
|
||||||
- DisableCapacities
|
* ContinueOnMethod
|
||||||
DisableCapacities specifies whether to disable the printing of
|
Enables recursion into types after invoking error and Stringer interface
|
||||||
capacities for arrays, slices, maps and channels. This is useful when
|
methods. Recursion after method invocation is disabled by default.
|
||||||
diffing data structures in tests.
|
|
||||||
|
|
||||||
- ContinueOnMethod
|
* SortKeys
|
||||||
Enables recursion into types after invoking error and Stringer interface
|
Specifies map keys should be sorted before being printed. Use
|
||||||
methods. Recursion after method invocation is disabled by default.
|
this to have a more deterministic, diffable output. Note that
|
||||||
|
only native types (bool, int, uint, floats, uintptr and string)
|
||||||
|
and types which implement error or Stringer interfaces are
|
||||||
|
supported with other types sorted according to the
|
||||||
|
reflect.Value.String() output which guarantees display
|
||||||
|
stability. Natural map order is used by default.
|
||||||
|
|
||||||
- SortKeys
|
* SpewKeys
|
||||||
Specifies map keys should be sorted before being printed. Use
|
Specifies that, as a last resort attempt, map keys should be
|
||||||
this to have a more deterministic, diffable output. Note that
|
spewed to strings and sorted by those strings. This is only
|
||||||
only native types (bool, int, uint, floats, uintptr and string)
|
considered if SortKeys is true.
|
||||||
and types which implement error or Stringer interfaces are
|
|
||||||
supported with other types sorted according to the
|
|
||||||
reflect.Value.String() output which guarantees display
|
|
||||||
stability. Natural map order is used by default.
|
|
||||||
|
|
||||||
- SpewKeys
|
Dump Usage
|
||||||
Specifies that, as a last resort attempt, map keys should be
|
|
||||||
spewed to strings and sorted by those strings. This is only
|
|
||||||
considered if SortKeys is true.
|
|
||||||
|
|
||||||
# Dump Usage
|
|
||||||
|
|
||||||
Simply call spew.Dump with a list of variables you want to dump:
|
Simply call spew.Dump with a list of variables you want to dump:
|
||||||
|
|
||||||
@ -136,7 +133,7 @@ A third option is to call spew.Sdump to get the formatted output as a string:
|
|||||||
|
|
||||||
str := spew.Sdump(myVar1, myVar2, ...)
|
str := spew.Sdump(myVar1, myVar2, ...)
|
||||||
|
|
||||||
# Sample Dump Output
|
Sample Dump Output
|
||||||
|
|
||||||
See the Dump example for details on the setup of the types and variables being
|
See the Dump example for details on the setup of the types and variables being
|
||||||
shown here.
|
shown here.
|
||||||
@ -153,14 +150,13 @@ shown here.
|
|||||||
|
|
||||||
Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
|
Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
|
||||||
command as shown.
|
command as shown.
|
||||||
|
|
||||||
([]uint8) (len=32 cap=32) {
|
([]uint8) (len=32 cap=32) {
|
||||||
00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
||||||
00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
||||||
00000020 31 32 |12|
|
00000020 31 32 |12|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Custom Formatter
|
Custom Formatter
|
||||||
|
|
||||||
Spew provides a custom formatter that implements the fmt.Formatter interface
|
Spew provides a custom formatter that implements the fmt.Formatter interface
|
||||||
so that it integrates cleanly with standard fmt package printing functions. The
|
so that it integrates cleanly with standard fmt package printing functions. The
|
||||||
@ -174,7 +170,7 @@ standard fmt package for formatting. In addition, the custom formatter ignores
|
|||||||
the width and precision arguments (however they will still work on the format
|
the width and precision arguments (however they will still work on the format
|
||||||
specifiers not handled by the custom formatter).
|
specifiers not handled by the custom formatter).
|
||||||
|
|
||||||
# Custom Formatter Usage
|
Custom Formatter Usage
|
||||||
|
|
||||||
The simplest way to make use of the spew custom formatter is to call one of the
|
The simplest way to make use of the spew custom formatter is to call one of the
|
||||||
convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
|
convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
|
||||||
@ -188,17 +184,15 @@ functions have syntax you are most likely already familiar with:
|
|||||||
|
|
||||||
See the Index for the full list convenience functions.
|
See the Index for the full list convenience functions.
|
||||||
|
|
||||||
# Sample Formatter Output
|
Sample Formatter Output
|
||||||
|
|
||||||
Double pointer to a uint8:
|
Double pointer to a uint8:
|
||||||
|
|
||||||
%v: <**>5
|
%v: <**>5
|
||||||
%+v: <**>(0xf8400420d0->0xf8400420c8)5
|
%+v: <**>(0xf8400420d0->0xf8400420c8)5
|
||||||
%#v: (**uint8)5
|
%#v: (**uint8)5
|
||||||
%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
|
%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
|
||||||
|
|
||||||
Pointer to circular struct with a uint8 field and a pointer to itself:
|
Pointer to circular struct with a uint8 field and a pointer to itself:
|
||||||
|
|
||||||
%v: <*>{1 <*><shown>}
|
%v: <*>{1 <*><shown>}
|
||||||
%+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
|
%+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
|
||||||
%#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
|
%#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
|
||||||
@ -207,7 +201,7 @@ Pointer to circular struct with a uint8 field and a pointer to itself:
|
|||||||
See the Printf example for details on the setup of variables being shown
|
See the Printf example for details on the setup of variables being shown
|
||||||
here.
|
here.
|
||||||
|
|
||||||
# Errors
|
Errors
|
||||||
|
|
||||||
Since it is possible for custom Stringer/error interfaces to panic, spew
|
Since it is possible for custom Stringer/error interfaces to panic, spew
|
||||||
detects them and handles them internally by printing the panic information
|
detects them and handles them internally by printing the panic information
|
||||||
|
18
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
18
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
@ -488,15 +488,15 @@ pointer addresses used to indirect to the final value. It provides the
|
|||||||
following features over the built-in printing facilities provided by the fmt
|
following features over the built-in printing facilities provided by the fmt
|
||||||
package:
|
package:
|
||||||
|
|
||||||
- Pointers are dereferenced and followed
|
* Pointers are dereferenced and followed
|
||||||
- Circular data structures are detected and handled properly
|
* Circular data structures are detected and handled properly
|
||||||
- Custom Stringer/error interfaces are optionally invoked, including
|
* Custom Stringer/error interfaces are optionally invoked, including
|
||||||
on unexported types
|
on unexported types
|
||||||
- Custom types which only implement the Stringer/error interfaces via
|
* Custom types which only implement the Stringer/error interfaces via
|
||||||
a pointer receiver are optionally invoked when passing non-pointer
|
a pointer receiver are optionally invoked when passing non-pointer
|
||||||
variables
|
variables
|
||||||
- Byte arrays and slices are dumped like the hexdump -C command which
|
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||||
includes offsets, byte values in hex, and ASCII output
|
includes offsets, byte values in hex, and ASCII output
|
||||||
|
|
||||||
The configuration options are controlled by an exported package global,
|
The configuration options are controlled by an exported package global,
|
||||||
spew.Config. See ConfigState for options documentation.
|
spew.Config. See ConfigState for options documentation.
|
||||||
|
4
vendor/github.com/docker/go-metrics/namespace.go
generated
vendored
4
vendor/github.com/docker/go-metrics/namespace.go
generated
vendored
@ -37,8 +37,8 @@ type Namespace struct {
|
|||||||
// WithConstLabels returns a namespace with the provided set of labels merged
|
// WithConstLabels returns a namespace with the provided set of labels merged
|
||||||
// with the existing constant labels on the namespace.
|
// with the existing constant labels on the namespace.
|
||||||
//
|
//
|
||||||
// Only metrics created with the returned namespace will get the new constant
|
// Only metrics created with the returned namespace will get the new constant
|
||||||
// labels. The returned namespace must be registered separately.
|
// labels. The returned namespace must be registered separately.
|
||||||
func (n *Namespace) WithConstLabels(labels Labels) *Namespace {
|
func (n *Namespace) WithConstLabels(labels Labels) *Namespace {
|
||||||
n.mu.Lock()
|
n.mu.Lock()
|
||||||
ns := &Namespace{
|
ns := &Namespace{
|
||||||
|
3
vendor/github.com/docker/go/canonical/json/decode.go
generated
vendored
3
vendor/github.com/docker/go/canonical/json/decode.go
generated
vendored
@ -74,13 +74,14 @@ import (
|
|||||||
//
|
//
|
||||||
// The JSON null value unmarshals into an interface, map, pointer, or slice
|
// The JSON null value unmarshals into an interface, map, pointer, or slice
|
||||||
// by setting that Go value to nil. Because null is often used in JSON to mean
|
// by setting that Go value to nil. Because null is often used in JSON to mean
|
||||||
// “not present,” unmarshaling a JSON null into any other Go type has no effect
|
// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
|
||||||
// on the value and produces no error.
|
// on the value and produces no error.
|
||||||
//
|
//
|
||||||
// When unmarshaling quoted strings, invalid UTF-8 or
|
// When unmarshaling quoted strings, invalid UTF-8 or
|
||||||
// invalid UTF-16 surrogate pairs are not treated as an error.
|
// invalid UTF-16 surrogate pairs are not treated as an error.
|
||||||
// Instead, they are replaced by the Unicode replacement
|
// Instead, they are replaced by the Unicode replacement
|
||||||
// character U+FFFD.
|
// character U+FFFD.
|
||||||
|
//
|
||||||
func Unmarshal(data []byte, v interface{}) error {
|
func Unmarshal(data []byte, v interface{}) error {
|
||||||
// Check for well-formedness.
|
// Check for well-formedness.
|
||||||
// Avoids filling out half a data structure
|
// Avoids filling out half a data structure
|
||||||
|
28
vendor/github.com/docker/go/canonical/json/encode.go
generated
vendored
28
vendor/github.com/docker/go/canonical/json/encode.go
generated
vendored
@ -58,7 +58,6 @@ import (
|
|||||||
// becomes a member of the object unless
|
// becomes a member of the object unless
|
||||||
// - the field's tag is "-", or
|
// - the field's tag is "-", or
|
||||||
// - the field is empty and its tag specifies the "omitempty" option.
|
// - the field is empty and its tag specifies the "omitempty" option.
|
||||||
//
|
|
||||||
// The empty values are false, 0, any
|
// The empty values are false, 0, any
|
||||||
// nil pointer or interface value, and any array, slice, map, or string of
|
// nil pointer or interface value, and any array, slice, map, or string of
|
||||||
// length zero. The object's default key string is the struct field name
|
// length zero. The object's default key string is the struct field name
|
||||||
@ -66,28 +65,28 @@ import (
|
|||||||
// the struct field's tag value is the key name, followed by an optional comma
|
// the struct field's tag value is the key name, followed by an optional comma
|
||||||
// and options. Examples:
|
// and options. Examples:
|
||||||
//
|
//
|
||||||
// // Field is ignored by this package.
|
// // Field is ignored by this package.
|
||||||
// Field int `json:"-"`
|
// Field int `json:"-"`
|
||||||
//
|
//
|
||||||
// // Field appears in JSON as key "myName".
|
// // Field appears in JSON as key "myName".
|
||||||
// Field int `json:"myName"`
|
// Field int `json:"myName"`
|
||||||
//
|
//
|
||||||
// // Field appears in JSON as key "myName" and
|
// // Field appears in JSON as key "myName" and
|
||||||
// // the field is omitted from the object if its value is empty,
|
// // the field is omitted from the object if its value is empty,
|
||||||
// // as defined above.
|
// // as defined above.
|
||||||
// Field int `json:"myName,omitempty"`
|
// Field int `json:"myName,omitempty"`
|
||||||
//
|
//
|
||||||
// // Field appears in JSON as key "Field" (the default), but
|
// // Field appears in JSON as key "Field" (the default), but
|
||||||
// // the field is skipped if empty.
|
// // the field is skipped if empty.
|
||||||
// // Note the leading comma.
|
// // Note the leading comma.
|
||||||
// Field int `json:",omitempty"`
|
// Field int `json:",omitempty"`
|
||||||
//
|
//
|
||||||
// The "string" option signals that a field is stored as JSON inside a
|
// The "string" option signals that a field is stored as JSON inside a
|
||||||
// JSON-encoded string. It applies only to fields of string, floating point,
|
// JSON-encoded string. It applies only to fields of string, floating point,
|
||||||
// integer, or boolean types. This extra level of encoding is sometimes used
|
// integer, or boolean types. This extra level of encoding is sometimes used
|
||||||
// when communicating with JavaScript programs:
|
// when communicating with JavaScript programs:
|
||||||
//
|
//
|
||||||
// Int64String int64 `json:",string"`
|
// Int64String int64 `json:",string"`
|
||||||
//
|
//
|
||||||
// The key name will be used if it's a non-empty string consisting of
|
// The key name will be used if it's a non-empty string consisting of
|
||||||
// only Unicode letters, digits, dollar signs, percent signs, hyphens,
|
// only Unicode letters, digits, dollar signs, percent signs, hyphens,
|
||||||
@ -134,6 +133,7 @@ import (
|
|||||||
// JSON cannot represent cyclic data structures and Marshal does not
|
// JSON cannot represent cyclic data structures and Marshal does not
|
||||||
// handle them. Passing cyclic structures to Marshal will result in
|
// handle them. Passing cyclic structures to Marshal will result in
|
||||||
// an infinite recursion.
|
// an infinite recursion.
|
||||||
|
//
|
||||||
func Marshal(v interface{}) ([]byte, error) {
|
func Marshal(v interface{}) ([]byte, error) {
|
||||||
return marshal(v, false)
|
return marshal(v, false)
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/docker/go/canonical/json/fold.go
generated
vendored
5
vendor/github.com/docker/go/canonical/json/fold.go
generated
vendored
@ -24,9 +24,8 @@ const (
|
|||||||
// 4) simpleLetterEqualFold, no specials, no non-letters.
|
// 4) simpleLetterEqualFold, no specials, no non-letters.
|
||||||
//
|
//
|
||||||
// The letters S and K are special because they map to 3 runes, not just 2:
|
// The letters S and K are special because they map to 3 runes, not just 2:
|
||||||
// - S maps to s and to U+017F 'ſ' Latin small letter long s
|
// * S maps to s and to U+017F 'ſ' Latin small letter long s
|
||||||
// - k maps to K and to U+212A 'K' Kelvin sign
|
// * k maps to K and to U+212A 'K' Kelvin sign
|
||||||
//
|
|
||||||
// See https://play.golang.org/p/tTxjOc0OGo
|
// See https://play.golang.org/p/tTxjOc0OGo
|
||||||
//
|
//
|
||||||
// The returned function is specialized for matching against s and
|
// The returned function is specialized for matching against s and
|
||||||
|
1
vendor/github.com/docker/go/canonical/json/stream.go
generated
vendored
1
vendor/github.com/docker/go/canonical/json/stream.go
generated
vendored
@ -242,6 +242,7 @@ var _ Unmarshaler = (*RawMessage)(nil)
|
|||||||
// Number, for JSON numbers
|
// Number, for JSON numbers
|
||||||
// string, for JSON string literals
|
// string, for JSON string literals
|
||||||
// nil, for JSON null
|
// nil, for JSON null
|
||||||
|
//
|
||||||
type Token interface{}
|
type Token interface{}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
4
vendor/github.com/emirpasic/gods/containers/iterator.go
generated
vendored
4
vendor/github.com/emirpasic/gods/containers/iterator.go
generated
vendored
@ -72,7 +72,7 @@ type IteratorWithKey interface {
|
|||||||
//
|
//
|
||||||
// Essentially it is the same as IteratorWithIndex, but provides additional:
|
// Essentially it is the same as IteratorWithIndex, but provides additional:
|
||||||
//
|
//
|
||||||
// # Prev() function to enable traversal in reverse
|
// Prev() function to enable traversal in reverse
|
||||||
//
|
//
|
||||||
// Last() function to move the iterator to the last element.
|
// Last() function to move the iterator to the last element.
|
||||||
//
|
//
|
||||||
@ -105,7 +105,7 @@ type ReverseIteratorWithIndex interface {
|
|||||||
//
|
//
|
||||||
// Essentially it is the same as IteratorWithKey, but provides additional:
|
// Essentially it is the same as IteratorWithKey, but provides additional:
|
||||||
//
|
//
|
||||||
// # Prev() function to enable traversal in reverse
|
// Prev() function to enable traversal in reverse
|
||||||
//
|
//
|
||||||
// Last() function to move the iterator to the last element.
|
// Last() function to move the iterator to the last element.
|
||||||
type ReverseIteratorWithKey interface {
|
type ReverseIteratorWithKey interface {
|
||||||
|
2
vendor/github.com/emirpasic/gods/lists/arraylist/arraylist.go
generated
vendored
2
vendor/github.com/emirpasic/gods/lists/arraylist/arraylist.go
generated
vendored
@ -102,7 +102,7 @@ func (list *List) Values() []interface{} {
|
|||||||
return newElements
|
return newElements
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexOf returns index of provided element
|
//IndexOf returns index of provided element
|
||||||
func (list *List) IndexOf(value interface{}) int {
|
func (list *List) IndexOf(value interface{}) int {
|
||||||
if list.size == 0 {
|
if list.size == 0 {
|
||||||
return -1
|
return -1
|
||||||
|
7
vendor/github.com/emirpasic/gods/utils/comparator.go
generated
vendored
7
vendor/github.com/emirpasic/gods/utils/comparator.go
generated
vendored
@ -10,10 +10,9 @@ import "time"
|
|||||||
// which will panic if a or b are not of the asserted type.
|
// which will panic if a or b are not of the asserted type.
|
||||||
//
|
//
|
||||||
// Should return a number:
|
// Should return a number:
|
||||||
//
|
// negative , if a < b
|
||||||
// negative , if a < b
|
// zero , if a == b
|
||||||
// zero , if a == b
|
// positive , if a > b
|
||||||
// positive , if a > b
|
|
||||||
type Comparator func(a, b interface{}) int
|
type Comparator func(a, b interface{}) int
|
||||||
|
|
||||||
// StringComparator provides a fast comparison on strings
|
// StringComparator provides a fast comparison on strings
|
||||||
|
2
vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go
generated
vendored
2
vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go
generated
vendored
@ -1,6 +1,4 @@
|
|||||||
//go:build go1.8
|
|
||||||
// +build go1.8
|
// +build go1.8
|
||||||
|
|
||||||
// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
|
// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
|
||||||
|
|
||||||
package httpsnoop
|
package httpsnoop
|
||||||
|
2
vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go
generated
vendored
2
vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go
generated
vendored
@ -1,6 +1,4 @@
|
|||||||
//go:build !go1.8
|
|
||||||
// +build !go1.8
|
// +build !go1.8
|
||||||
|
|
||||||
// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
|
// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
|
||||||
|
|
||||||
package httpsnoop
|
package httpsnoop
|
||||||
|
5
vendor/github.com/ghodss/yaml/fields.go
generated
vendored
5
vendor/github.com/ghodss/yaml/fields.go
generated
vendored
@ -347,9 +347,8 @@ const (
|
|||||||
// 4) simpleLetterEqualFold, no specials, no non-letters.
|
// 4) simpleLetterEqualFold, no specials, no non-letters.
|
||||||
//
|
//
|
||||||
// The letters S and K are special because they map to 3 runes, not just 2:
|
// The letters S and K are special because they map to 3 runes, not just 2:
|
||||||
// - S maps to s and to U+017F 'ſ' Latin small letter long s
|
// * S maps to s and to U+017F 'ſ' Latin small letter long s
|
||||||
// - k maps to K and to U+212A 'K' Kelvin sign
|
// * k maps to K and to U+212A 'K' Kelvin sign
|
||||||
//
|
|
||||||
// See http://play.golang.org/p/tTxjOc0OGo
|
// See http://play.golang.org/p/tTxjOc0OGo
|
||||||
//
|
//
|
||||||
// The returned function is specialized for matching against s and
|
// The returned function is specialized for matching against s and
|
||||||
|
12
vendor/github.com/ghodss/yaml/yaml.go
generated
vendored
12
vendor/github.com/ghodss/yaml/yaml.go
generated
vendored
@ -64,12 +64,12 @@ func JSONToYAML(j []byte) ([]byte, error) {
|
|||||||
// this method should be a no-op.
|
// this method should be a no-op.
|
||||||
//
|
//
|
||||||
// Things YAML can do that are not supported by JSON:
|
// Things YAML can do that are not supported by JSON:
|
||||||
// - In YAML you can have binary and null keys in your maps. These are invalid
|
// * In YAML you can have binary and null keys in your maps. These are invalid
|
||||||
// in JSON. (int and float keys are converted to strings.)
|
// in JSON. (int and float keys are converted to strings.)
|
||||||
// - Binary data in YAML with the !!binary tag is not supported. If you want to
|
// * Binary data in YAML with the !!binary tag is not supported. If you want to
|
||||||
// use binary data with this library, encode the data as base64 as usual but do
|
// use binary data with this library, encode the data as base64 as usual but do
|
||||||
// not use the !!binary tag in your YAML. This will ensure the original base64
|
// not use the !!binary tag in your YAML. This will ensure the original base64
|
||||||
// encoded data makes it all the way through to the JSON.
|
// encoded data makes it all the way through to the JSON.
|
||||||
func YAMLToJSON(y []byte) ([]byte, error) {
|
func YAMLToJSON(y []byte) ([]byte, error) {
|
||||||
return yamlToJSON(y, nil)
|
return yamlToJSON(y, nil)
|
||||||
}
|
}
|
||||||
|
89
vendor/github.com/go-git/gcfg/doc.go
generated
vendored
89
vendor/github.com/go-git/gcfg/doc.go
generated
vendored
@ -4,29 +4,29 @@
|
|||||||
// This package is still a work in progress; see the sections below for planned
|
// This package is still a work in progress; see the sections below for planned
|
||||||
// changes.
|
// changes.
|
||||||
//
|
//
|
||||||
// # Syntax
|
// Syntax
|
||||||
//
|
//
|
||||||
// The syntax is based on that used by git config:
|
// The syntax is based on that used by git config:
|
||||||
// http://git-scm.com/docs/git-config#_syntax .
|
// http://git-scm.com/docs/git-config#_syntax .
|
||||||
// There are some (planned) differences compared to the git config format:
|
// There are some (planned) differences compared to the git config format:
|
||||||
// - improve data portability:
|
// - improve data portability:
|
||||||
// - must be encoded in UTF-8 (for now) and must not contain the 0 byte
|
// - must be encoded in UTF-8 (for now) and must not contain the 0 byte
|
||||||
// - include and "path" type is not supported
|
// - include and "path" type is not supported
|
||||||
// (path type may be implementable as a user-defined type)
|
// (path type may be implementable as a user-defined type)
|
||||||
// - internationalization
|
// - internationalization
|
||||||
// - section and variable names can contain unicode letters, unicode digits
|
// - section and variable names can contain unicode letters, unicode digits
|
||||||
// (as defined in http://golang.org/ref/spec#Characters ) and hyphens
|
// (as defined in http://golang.org/ref/spec#Characters ) and hyphens
|
||||||
// (U+002D), starting with a unicode letter
|
// (U+002D), starting with a unicode letter
|
||||||
// - disallow potentially ambiguous or misleading definitions:
|
// - disallow potentially ambiguous or misleading definitions:
|
||||||
// - `[sec.sub]` format is not allowed (deprecated in gitconfig)
|
// - `[sec.sub]` format is not allowed (deprecated in gitconfig)
|
||||||
// - `[sec ""]` is not allowed
|
// - `[sec ""]` is not allowed
|
||||||
// - use `[sec]` for section name "sec" and empty subsection name
|
// - use `[sec]` for section name "sec" and empty subsection name
|
||||||
// - (planned) within a single file, definitions must be contiguous for each:
|
// - (planned) within a single file, definitions must be contiguous for each:
|
||||||
// - section: '[secA]' -> '[secB]' -> '[secA]' is an error
|
// - section: '[secA]' -> '[secB]' -> '[secA]' is an error
|
||||||
// - subsection: '[sec "A"]' -> '[sec "B"]' -> '[sec "A"]' is an error
|
// - subsection: '[sec "A"]' -> '[sec "B"]' -> '[sec "A"]' is an error
|
||||||
// - multivalued variable: 'multi=a' -> 'other=x' -> 'multi=b' is an error
|
// - multivalued variable: 'multi=a' -> 'other=x' -> 'multi=b' is an error
|
||||||
//
|
//
|
||||||
// # Data structure
|
// Data structure
|
||||||
//
|
//
|
||||||
// The functions in this package read values into a user-defined struct.
|
// The functions in this package read values into a user-defined struct.
|
||||||
// Each section corresponds to a struct field in the config struct, and each
|
// Each section corresponds to a struct field in the config struct, and each
|
||||||
@ -56,7 +56,7 @@
|
|||||||
// or when a field is not of a suitable type (either a struct or a map with
|
// or when a field is not of a suitable type (either a struct or a map with
|
||||||
// string keys and pointer-to-struct values).
|
// string keys and pointer-to-struct values).
|
||||||
//
|
//
|
||||||
// # Parsing of values
|
// Parsing of values
|
||||||
//
|
//
|
||||||
// The section structs in the config struct may contain single-valued or
|
// The section structs in the config struct may contain single-valued or
|
||||||
// multi-valued variables. Variables of unnamed slice type (that is, a type
|
// multi-valued variables. Variables of unnamed slice type (that is, a type
|
||||||
@ -98,17 +98,17 @@
|
|||||||
// The types subpackage for provides helpers for parsing "enum-like" and integer
|
// The types subpackage for provides helpers for parsing "enum-like" and integer
|
||||||
// types.
|
// types.
|
||||||
//
|
//
|
||||||
// # Error handling
|
// Error handling
|
||||||
//
|
//
|
||||||
// There are 3 types of errors:
|
// There are 3 types of errors:
|
||||||
//
|
//
|
||||||
// - programmer errors / panics:
|
// - programmer errors / panics:
|
||||||
// - invalid configuration structure
|
// - invalid configuration structure
|
||||||
// - data errors:
|
// - data errors:
|
||||||
// - fatal errors:
|
// - fatal errors:
|
||||||
// - invalid configuration syntax
|
// - invalid configuration syntax
|
||||||
// - warnings:
|
// - warnings:
|
||||||
// - data that doesn't belong to any part of the config structure
|
// - data that doesn't belong to any part of the config structure
|
||||||
//
|
//
|
||||||
// Programmer errors trigger panics. These are should be fixed by the programmer
|
// Programmer errors trigger panics. These are should be fixed by the programmer
|
||||||
// before releasing code that uses gcfg.
|
// before releasing code that uses gcfg.
|
||||||
@ -122,23 +122,24 @@
|
|||||||
// filtered out programmatically. To ignore extra data warnings, wrap the
|
// filtered out programmatically. To ignore extra data warnings, wrap the
|
||||||
// gcfg.Read*Into invocation into a call to gcfg.FatalOnly.
|
// gcfg.Read*Into invocation into a call to gcfg.FatalOnly.
|
||||||
//
|
//
|
||||||
// # TODO
|
// TODO
|
||||||
//
|
//
|
||||||
// The following is a list of changes under consideration:
|
// The following is a list of changes under consideration:
|
||||||
// - documentation
|
// - documentation
|
||||||
// - self-contained syntax documentation
|
// - self-contained syntax documentation
|
||||||
// - more practical examples
|
// - more practical examples
|
||||||
// - move TODOs to issue tracker (eventually)
|
// - move TODOs to issue tracker (eventually)
|
||||||
// - syntax
|
// - syntax
|
||||||
// - reconsider valid escape sequences
|
// - reconsider valid escape sequences
|
||||||
// (gitconfig doesn't support \r in value, \t in subsection name, etc.)
|
// (gitconfig doesn't support \r in value, \t in subsection name, etc.)
|
||||||
// - reading / parsing gcfg files
|
// - reading / parsing gcfg files
|
||||||
// - define internal representation structure
|
// - define internal representation structure
|
||||||
// - support multiple inputs (readers, strings, files)
|
// - support multiple inputs (readers, strings, files)
|
||||||
// - support declaring encoding (?)
|
// - support declaring encoding (?)
|
||||||
// - support varying fields sets for subsections (?)
|
// - support varying fields sets for subsections (?)
|
||||||
// - writing gcfg files
|
// - writing gcfg files
|
||||||
// - error handling
|
// - error handling
|
||||||
// - make error context accessible programmatically?
|
// - make error context accessible programmatically?
|
||||||
// - limit input size?
|
// - limit input size?
|
||||||
|
//
|
||||||
package gcfg // import "github.com/go-git/gcfg"
|
package gcfg // import "github.com/go-git/gcfg"
|
||||||
|
7
vendor/github.com/go-git/gcfg/errors.go
generated
vendored
7
vendor/github.com/go-git/gcfg/errors.go
generated
vendored
@ -8,9 +8,10 @@ import (
|
|||||||
// fatal errors. That is, errors (warnings) indicating data for unknown
|
// fatal errors. That is, errors (warnings) indicating data for unknown
|
||||||
// sections / variables is ignored. Example invocation:
|
// sections / variables is ignored. Example invocation:
|
||||||
//
|
//
|
||||||
// err := gcfg.FatalOnly(gcfg.ReadFileInto(&cfg, configFile))
|
// err := gcfg.FatalOnly(gcfg.ReadFileInto(&cfg, configFile))
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// ...
|
// ...
|
||||||
|
//
|
||||||
func FatalOnly(err error) error {
|
func FatalOnly(err error) error {
|
||||||
return warnings.FatalOnly(err)
|
return warnings.FatalOnly(err)
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/go-git/gcfg/scanner/errors.go
generated
vendored
4
vendor/github.com/go-git/gcfg/scanner/errors.go
generated
vendored
@ -18,6 +18,7 @@ import (
|
|||||||
// The position Pos, if valid, points to the beginning of
|
// The position Pos, if valid, points to the beginning of
|
||||||
// the offending token, and the error condition is described
|
// the offending token, and the error condition is described
|
||||||
// by Msg.
|
// by Msg.
|
||||||
|
//
|
||||||
type Error struct {
|
type Error struct {
|
||||||
Pos token.Position
|
Pos token.Position
|
||||||
Msg string
|
Msg string
|
||||||
@ -35,6 +36,7 @@ func (e Error) Error() string {
|
|||||||
|
|
||||||
// ErrorList is a list of *Errors.
|
// ErrorList is a list of *Errors.
|
||||||
// The zero value for an ErrorList is an empty ErrorList ready to use.
|
// The zero value for an ErrorList is an empty ErrorList ready to use.
|
||||||
|
//
|
||||||
type ErrorList []*Error
|
type ErrorList []*Error
|
||||||
|
|
||||||
// Add adds an Error with given position and error message to an ErrorList.
|
// Add adds an Error with given position and error message to an ErrorList.
|
||||||
@ -64,6 +66,7 @@ func (p ErrorList) Less(i, j int) bool {
|
|||||||
// Sort sorts an ErrorList. *Error entries are sorted by position,
|
// Sort sorts an ErrorList. *Error entries are sorted by position,
|
||||||
// other errors are sorted by error message, and before any *Error
|
// other errors are sorted by error message, and before any *Error
|
||||||
// entry.
|
// entry.
|
||||||
|
//
|
||||||
func (p ErrorList) Sort() {
|
func (p ErrorList) Sort() {
|
||||||
sort.Sort(p)
|
sort.Sort(p)
|
||||||
}
|
}
|
||||||
@ -106,6 +109,7 @@ func (p ErrorList) Err() error {
|
|||||||
// PrintError is a utility function that prints a list of errors to w,
|
// PrintError is a utility function that prints a list of errors to w,
|
||||||
// one error per line, if the err parameter is an ErrorList. Otherwise
|
// one error per line, if the err parameter is an ErrorList. Otherwise
|
||||||
// it prints the err string.
|
// it prints the err string.
|
||||||
|
//
|
||||||
func PrintError(w io.Writer, err error) {
|
func PrintError(w io.Writer, err error) {
|
||||||
if list, ok := err.(ErrorList); ok {
|
if list, ok := err.(ErrorList); ok {
|
||||||
for _, e := range list {
|
for _, e := range list {
|
||||||
|
2
vendor/github.com/go-git/gcfg/set.go
generated
vendored
2
vendor/github.com/go-git/gcfg/set.go
generated
vendored
@ -216,7 +216,7 @@ func newValue(c *warnings.Collector, sect string, vCfg reflect.Value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func set(c *warnings.Collector, cfg interface{}, sect, sub, name string,
|
func set(c *warnings.Collector, cfg interface{}, sect, sub, name string,
|
||||||
value string, blankValue bool, subsectPass bool) error {
|
value string, blankValue bool, subsectPass bool) error {
|
||||||
//
|
//
|
||||||
vPCfg := reflect.ValueOf(cfg)
|
vPCfg := reflect.ValueOf(cfg)
|
||||||
if vPCfg.Kind() != reflect.Ptr || vPCfg.Elem().Kind() != reflect.Struct {
|
if vPCfg.Kind() != reflect.Ptr || vPCfg.Elem().Kind() != reflect.Struct {
|
||||||
|
17
vendor/github.com/go-git/gcfg/token/position.go
generated
vendored
17
vendor/github.com/go-git/gcfg/token/position.go
generated
vendored
@ -18,6 +18,7 @@ import (
|
|||||||
// Position describes an arbitrary source position
|
// Position describes an arbitrary source position
|
||||||
// including the file, line, and column location.
|
// including the file, line, and column location.
|
||||||
// A Position is valid if the line number is > 0.
|
// A Position is valid if the line number is > 0.
|
||||||
|
//
|
||||||
type Position struct {
|
type Position struct {
|
||||||
Filename string // filename, if any
|
Filename string // filename, if any
|
||||||
Offset int // offset, starting at 0
|
Offset int // offset, starting at 0
|
||||||
@ -34,6 +35,7 @@ func (pos *Position) IsValid() bool { return pos.Line > 0 }
|
|||||||
// line:column valid position without file name
|
// line:column valid position without file name
|
||||||
// file invalid position with file name
|
// file invalid position with file name
|
||||||
// - invalid position without file name
|
// - invalid position without file name
|
||||||
|
//
|
||||||
func (pos Position) String() string {
|
func (pos Position) String() string {
|
||||||
s := pos.Filename
|
s := pos.Filename
|
||||||
if pos.IsValid() {
|
if pos.IsValid() {
|
||||||
@ -67,12 +69,14 @@ func (pos Position) String() string {
|
|||||||
// equivalent to comparing the respective source file offsets. If p and q
|
// equivalent to comparing the respective source file offsets. If p and q
|
||||||
// are in different files, p < q is true if the file implied by p was added
|
// are in different files, p < q is true if the file implied by p was added
|
||||||
// to the respective file set before the file implied by q.
|
// to the respective file set before the file implied by q.
|
||||||
|
//
|
||||||
type Pos int
|
type Pos int
|
||||||
|
|
||||||
// The zero value for Pos is NoPos; there is no file and line information
|
// The zero value for Pos is NoPos; there is no file and line information
|
||||||
// associated with it, and NoPos().IsValid() is false. NoPos is always
|
// associated with it, and NoPos().IsValid() is false. NoPos is always
|
||||||
// smaller than any other Pos value. The corresponding Position value
|
// smaller than any other Pos value. The corresponding Position value
|
||||||
// for NoPos is the zero value for Position.
|
// for NoPos is the zero value for Position.
|
||||||
|
//
|
||||||
const NoPos Pos = 0
|
const NoPos Pos = 0
|
||||||
|
|
||||||
// IsValid returns true if the position is valid.
|
// IsValid returns true if the position is valid.
|
||||||
@ -85,6 +89,7 @@ func (p Pos) IsValid() bool {
|
|||||||
|
|
||||||
// A File is a handle for a file belonging to a FileSet.
|
// A File is a handle for a file belonging to a FileSet.
|
||||||
// A File has a name, size, and line offset table.
|
// A File has a name, size, and line offset table.
|
||||||
|
//
|
||||||
type File struct {
|
type File struct {
|
||||||
set *FileSet
|
set *FileSet
|
||||||
name string // file name as provided to AddFile
|
name string // file name as provided to AddFile
|
||||||
@ -122,6 +127,7 @@ func (f *File) LineCount() int {
|
|||||||
// AddLine adds the line offset for a new line.
|
// AddLine adds the line offset for a new line.
|
||||||
// The line offset must be larger than the offset for the previous line
|
// The line offset must be larger than the offset for the previous line
|
||||||
// and smaller than the file size; otherwise the line offset is ignored.
|
// and smaller than the file size; otherwise the line offset is ignored.
|
||||||
|
//
|
||||||
func (f *File) AddLine(offset int) {
|
func (f *File) AddLine(offset int) {
|
||||||
f.set.mutex.Lock()
|
f.set.mutex.Lock()
|
||||||
if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
|
if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
|
||||||
@ -137,6 +143,7 @@ func (f *File) AddLine(offset int) {
|
|||||||
// Each line offset must be larger than the offset for the previous line
|
// Each line offset must be larger than the offset for the previous line
|
||||||
// and smaller than the file size; otherwise SetLines fails and returns
|
// and smaller than the file size; otherwise SetLines fails and returns
|
||||||
// false.
|
// false.
|
||||||
|
//
|
||||||
func (f *File) SetLines(lines []int) bool {
|
func (f *File) SetLines(lines []int) bool {
|
||||||
// verify validity of lines table
|
// verify validity of lines table
|
||||||
size := f.size
|
size := f.size
|
||||||
@ -190,6 +197,7 @@ type lineInfo struct {
|
|||||||
//
|
//
|
||||||
// AddLineInfo is typically used to register alternative position
|
// AddLineInfo is typically used to register alternative position
|
||||||
// information for //line filename:line comments in source files.
|
// information for //line filename:line comments in source files.
|
||||||
|
//
|
||||||
func (f *File) AddLineInfo(offset int, filename string, line int) {
|
func (f *File) AddLineInfo(offset int, filename string, line int) {
|
||||||
f.set.mutex.Lock()
|
f.set.mutex.Lock()
|
||||||
if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size {
|
if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size {
|
||||||
@ -201,6 +209,7 @@ func (f *File) AddLineInfo(offset int, filename string, line int) {
|
|||||||
// Pos returns the Pos value for the given file offset;
|
// Pos returns the Pos value for the given file offset;
|
||||||
// the offset must be <= f.Size().
|
// the offset must be <= f.Size().
|
||||||
// f.Pos(f.Offset(p)) == p.
|
// f.Pos(f.Offset(p)) == p.
|
||||||
|
//
|
||||||
func (f *File) Pos(offset int) Pos {
|
func (f *File) Pos(offset int) Pos {
|
||||||
if offset > f.size {
|
if offset > f.size {
|
||||||
panic("illegal file offset")
|
panic("illegal file offset")
|
||||||
@ -211,6 +220,7 @@ func (f *File) Pos(offset int) Pos {
|
|||||||
// Offset returns the offset for the given file position p;
|
// Offset returns the offset for the given file position p;
|
||||||
// p must be a valid Pos value in that file.
|
// p must be a valid Pos value in that file.
|
||||||
// f.Offset(f.Pos(offset)) == offset.
|
// f.Offset(f.Pos(offset)) == offset.
|
||||||
|
//
|
||||||
func (f *File) Offset(p Pos) int {
|
func (f *File) Offset(p Pos) int {
|
||||||
if int(p) < f.base || int(p) > f.base+f.size {
|
if int(p) < f.base || int(p) > f.base+f.size {
|
||||||
panic("illegal Pos value")
|
panic("illegal Pos value")
|
||||||
@ -220,6 +230,7 @@ func (f *File) Offset(p Pos) int {
|
|||||||
|
|
||||||
// Line returns the line number for the given file position p;
|
// Line returns the line number for the given file position p;
|
||||||
// p must be a Pos value in that file or NoPos.
|
// p must be a Pos value in that file or NoPos.
|
||||||
|
//
|
||||||
func (f *File) Line(p Pos) int {
|
func (f *File) Line(p Pos) int {
|
||||||
// TODO(gri) this can be implemented much more efficiently
|
// TODO(gri) this can be implemented much more efficiently
|
||||||
return f.Position(p).Line
|
return f.Position(p).Line
|
||||||
@ -257,6 +268,7 @@ func (f *File) position(p Pos) (pos Position) {
|
|||||||
|
|
||||||
// Position returns the Position value for the given file position p;
|
// Position returns the Position value for the given file position p;
|
||||||
// p must be a Pos value in that file or NoPos.
|
// p must be a Pos value in that file or NoPos.
|
||||||
|
//
|
||||||
func (f *File) Position(p Pos) (pos Position) {
|
func (f *File) Position(p Pos) (pos Position) {
|
||||||
if p != NoPos {
|
if p != NoPos {
|
||||||
if int(p) < f.base || int(p) > f.base+f.size {
|
if int(p) < f.base || int(p) > f.base+f.size {
|
||||||
@ -273,6 +285,7 @@ func (f *File) Position(p Pos) (pos Position) {
|
|||||||
// A FileSet represents a set of source files.
|
// A FileSet represents a set of source files.
|
||||||
// Methods of file sets are synchronized; multiple goroutines
|
// Methods of file sets are synchronized; multiple goroutines
|
||||||
// may invoke them concurrently.
|
// may invoke them concurrently.
|
||||||
|
//
|
||||||
type FileSet struct {
|
type FileSet struct {
|
||||||
mutex sync.RWMutex // protects the file set
|
mutex sync.RWMutex // protects the file set
|
||||||
base int // base offset for the next file
|
base int // base offset for the next file
|
||||||
@ -289,6 +302,7 @@ func NewFileSet() *FileSet {
|
|||||||
|
|
||||||
// Base returns the minimum base offset that must be provided to
|
// Base returns the minimum base offset that must be provided to
|
||||||
// AddFile when adding the next file.
|
// AddFile when adding the next file.
|
||||||
|
//
|
||||||
func (s *FileSet) Base() int {
|
func (s *FileSet) Base() int {
|
||||||
s.mutex.RLock()
|
s.mutex.RLock()
|
||||||
b := s.base
|
b := s.base
|
||||||
@ -311,6 +325,7 @@ func (s *FileSet) Base() int {
|
|||||||
// with offs in the range [0, size] and thus p in the range [base, base+size].
|
// with offs in the range [0, size] and thus p in the range [base, base+size].
|
||||||
// For convenience, File.Pos may be used to create file-specific position
|
// For convenience, File.Pos may be used to create file-specific position
|
||||||
// values from a file offset.
|
// values from a file offset.
|
||||||
|
//
|
||||||
func (s *FileSet) AddFile(filename string, base, size int) *File {
|
func (s *FileSet) AddFile(filename string, base, size int) *File {
|
||||||
s.mutex.Lock()
|
s.mutex.Lock()
|
||||||
defer s.mutex.Unlock()
|
defer s.mutex.Unlock()
|
||||||
@ -332,6 +347,7 @@ func (s *FileSet) AddFile(filename string, base, size int) *File {
|
|||||||
|
|
||||||
// Iterate calls f for the files in the file set in the order they were added
|
// Iterate calls f for the files in the file set in the order they were added
|
||||||
// until f returns false.
|
// until f returns false.
|
||||||
|
//
|
||||||
func (s *FileSet) Iterate(f func(*File) bool) {
|
func (s *FileSet) Iterate(f func(*File) bool) {
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
var file *File
|
var file *File
|
||||||
@ -370,6 +386,7 @@ func (s *FileSet) file(p Pos) *File {
|
|||||||
// File returns the file that contains the position p.
|
// File returns the file that contains the position p.
|
||||||
// If no such file is found (for instance for p == NoPos),
|
// If no such file is found (for instance for p == NoPos),
|
||||||
// the result is nil.
|
// the result is nil.
|
||||||
|
//
|
||||||
func (s *FileSet) File(p Pos) (f *File) {
|
func (s *FileSet) File(p Pos) (f *File) {
|
||||||
if p != NoPos {
|
if p != NoPos {
|
||||||
s.mutex.RLock()
|
s.mutex.RLock()
|
||||||
|
4
vendor/github.com/go-git/gcfg/token/token.go
generated
vendored
4
vendor/github.com/go-git/gcfg/token/token.go
generated
vendored
@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
// Note that the API for the token package may change to accommodate new
|
// Note that the API for the token package may change to accommodate new
|
||||||
// features or implementation changes in gcfg.
|
// features or implementation changes in gcfg.
|
||||||
|
//
|
||||||
package token
|
package token
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
@ -57,6 +58,7 @@ var tokens = [...]string{
|
|||||||
// sequence (e.g., for the token ASSIGN, the string is "="). For all other
|
// sequence (e.g., for the token ASSIGN, the string is "="). For all other
|
||||||
// tokens the string corresponds to the token constant name (e.g. for the
|
// tokens the string corresponds to the token constant name (e.g. for the
|
||||||
// token IDENT, the string is "IDENT").
|
// token IDENT, the string is "IDENT").
|
||||||
|
//
|
||||||
func (tok Token) String() string {
|
func (tok Token) String() string {
|
||||||
s := ""
|
s := ""
|
||||||
if 0 <= tok && tok < Token(len(tokens)) {
|
if 0 <= tok && tok < Token(len(tokens)) {
|
||||||
@ -72,8 +74,10 @@ func (tok Token) String() string {
|
|||||||
|
|
||||||
// IsLiteral returns true for tokens corresponding to identifiers
|
// IsLiteral returns true for tokens corresponding to identifiers
|
||||||
// and basic type literals; it returns false otherwise.
|
// and basic type literals; it returns false otherwise.
|
||||||
|
//
|
||||||
func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end }
|
func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end }
|
||||||
|
|
||||||
// IsOperator returns true for tokens corresponding to operators and
|
// IsOperator returns true for tokens corresponding to operators and
|
||||||
// delimiters; it returns false otherwise.
|
// delimiters; it returns false otherwise.
|
||||||
|
//
|
||||||
func (tok Token) IsOperator() bool { return operator_beg < tok && tok < operator_end }
|
func (tok Token) IsOperator() bool { return operator_beg < tok && tok < operator_end }
|
||||||
|
2
vendor/github.com/go-git/go-billy/v5/memfs/memory.go
generated
vendored
2
vendor/github.com/go-git/go-billy/v5/memfs/memory.go
generated
vendored
@ -25,7 +25,7 @@ type Memory struct {
|
|||||||
tempCount int
|
tempCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new Memory filesystem.
|
//New returns a new Memory filesystem.
|
||||||
func New() billy.Filesystem {
|
func New() billy.Filesystem {
|
||||||
fs := &Memory{s: newStorage()}
|
fs := &Memory{s: newStorage()}
|
||||||
return chroot.New(fs, string(separator))
|
return chroot.New(fs, string(separator))
|
||||||
|
8
vendor/github.com/go-git/go-billy/v5/util/walk.go
generated
vendored
8
vendor/github.com/go-git/go-billy/v5/util/walk.go
generated
vendored
@ -46,7 +46,7 @@ func walk(fs billy.Filesystem, path string, info os.FileInfo, walkFn filepath.Wa
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk walks the file tree rooted at root, calling fn for each file or
|
// Walk walks the file tree rooted at root, calling fn for each file or
|
||||||
// directory in the tree, including root. All errors that arise visiting files
|
// directory in the tree, including root. All errors that arise visiting files
|
||||||
// and directories are filtered by fn: see the WalkFunc documentation for
|
// and directories are filtered by fn: see the WalkFunc documentation for
|
||||||
// details.
|
// details.
|
||||||
@ -54,7 +54,7 @@ func walk(fs billy.Filesystem, path string, info os.FileInfo, walkFn filepath.Wa
|
|||||||
// The files are walked in lexical order, which makes the output deterministic
|
// The files are walked in lexical order, which makes the output deterministic
|
||||||
// but requires Walk to read an entire directory into memory before proceeding
|
// but requires Walk to read an entire directory into memory before proceeding
|
||||||
// to walk that directory. Walk does not follow symbolic links.
|
// to walk that directory. Walk does not follow symbolic links.
|
||||||
//
|
//
|
||||||
// Function adapted from https://github.com/golang/go/blob/3b770f2ccb1fa6fecc22ea822a19447b10b70c5c/src/path/filepath/path.go#L500
|
// Function adapted from https://github.com/golang/go/blob/3b770f2ccb1fa6fecc22ea822a19447b10b70c5c/src/path/filepath/path.go#L500
|
||||||
func Walk(fs billy.Filesystem, root string, walkFn filepath.WalkFunc) error {
|
func Walk(fs billy.Filesystem, root string, walkFn filepath.WalkFunc) error {
|
||||||
info, err := fs.Lstat(root)
|
info, err := fs.Lstat(root)
|
||||||
@ -63,10 +63,10 @@ func Walk(fs billy.Filesystem, root string, walkFn filepath.WalkFunc) error {
|
|||||||
} else {
|
} else {
|
||||||
err = walk(fs, root, info, walkFn)
|
err = walk(fs, root, info, walkFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == filepath.SkipDir {
|
if err == filepath.SkipDir {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user