mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-04 23:56:30 +00:00
Merge branch 'origin/main' into 'next-release/main'
This commit is contained in:
commit
0162442ebc
53 changed files with 270 additions and 225 deletions
|
@ -29,7 +29,7 @@ import (
|
|||
var Command = &cli.Command{
|
||||
Name: "log-level",
|
||||
ArgsUsage: "[level]",
|
||||
Usage: "get the logging level of the server, or set it with [level]",
|
||||
Usage: "retrieve log level from server, or set it with [level]",
|
||||
Action: logLevel,
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,6 @@ func logLevel(ctx context.Context, c *cli.Command) error {
|
|||
}
|
||||
}
|
||||
|
||||
log.Info().Msgf("logging level: %s", ll.Level)
|
||||
log.Info().Msgf("log level: %s", ll.Level)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ var Command = &cli.Command{
|
|||
registryCreateCmd,
|
||||
registryDeleteCmd,
|
||||
registryUpdateCmd,
|
||||
registryInfoCmd,
|
||||
registryShowCmd,
|
||||
registryListCmd,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
|
||||
var registryCreateCmd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a registry",
|
||||
Usage: "add a registry",
|
||||
Action: registryCreate,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
|
|
|
@ -25,10 +25,10 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var registryInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display registry info",
|
||||
Action: registryInfo,
|
||||
var registryShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show registry information",
|
||||
Action: registryShow,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "hostname",
|
||||
|
@ -39,7 +39,7 @@ var registryInfoCmd = &cli.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func registryInfo(ctx context.Context, c *cli.Command) error {
|
||||
func registryShow(ctx context.Context, c *cli.Command) error {
|
||||
var (
|
||||
hostname = c.String("hostname")
|
||||
format = c.String("format") + "\n"
|
|
@ -26,7 +26,7 @@ var Command = &cli.Command{
|
|||
secretCreateCmd,
|
||||
secretDeleteCmd,
|
||||
secretUpdateCmd,
|
||||
secretInfoCmd,
|
||||
secretShowCmd,
|
||||
secretListCmd,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
|
||||
var secretCreateCmd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a secret",
|
||||
Usage: "add a secret",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: secretCreate,
|
||||
Flags: []cli.Flag{
|
||||
|
|
|
@ -26,11 +26,11 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var secretInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display secret info",
|
||||
var secretShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show secret information",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: secretInfo,
|
||||
Action: secretShow,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
|
@ -40,7 +40,7 @@ var secretInfoCmd = &cli.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func secretInfo(ctx context.Context, c *cli.Command) error {
|
||||
func secretShow(ctx context.Context, c *cli.Command) error {
|
||||
var (
|
||||
secretName = c.String("name")
|
||||
format = c.String("format") + "\n"
|
|
@ -24,7 +24,7 @@ var Command = &cli.Command{
|
|||
Usage: "manage users",
|
||||
Commands: []*cli.Command{
|
||||
userListCmd,
|
||||
userInfoCmd,
|
||||
userShowCmd,
|
||||
userAddCmd,
|
||||
userRemoveCmd,
|
||||
},
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
|
||||
var userAddCmd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a user",
|
||||
Usage: "add a user",
|
||||
ArgsUsage: "<username>",
|
||||
Action: userAdd,
|
||||
}
|
||||
|
|
|
@ -26,15 +26,15 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var userInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "show user details",
|
||||
var userShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show user information",
|
||||
ArgsUsage: "<username>",
|
||||
Action: userInfo,
|
||||
Action: userShow,
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplUserInfo)},
|
||||
}
|
||||
|
||||
func userInfo(ctx context.Context, c *cli.Command) error {
|
||||
func userShow(ctx context.Context, c *cli.Command) error {
|
||||
client, err := internal.NewClient(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
|
@ -35,18 +35,18 @@ func Before(ctx context.Context, c *cli.Command) (context.Context, error) {
|
|||
waitForUpdateCheck, cancelWaitForUpdate = context.WithCancelCause(context.Background())
|
||||
defer cancelWaitForUpdate(errors.New("update check finished"))
|
||||
|
||||
log.Debug().Msg("Checking for updates ...")
|
||||
log.Debug().Msg("checking for updates ...")
|
||||
|
||||
newVersion, err := update.CheckForUpdate(waitForUpdateCheck, false) //nolint:contextcheck
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("Failed to check for updates")
|
||||
log.Error().Err(err).Msgf("failed to check for updates")
|
||||
return
|
||||
}
|
||||
|
||||
if newVersion != nil {
|
||||
log.Warn().Msgf("A new version of woodpecker-cli is available: %s. Update by running: %s update", newVersion.Version, c.Root().Name)
|
||||
log.Warn().Msgf("new version of woodpecker-cli is available: %s, update with: %s update", newVersion.Version, c.Root().Name)
|
||||
} else {
|
||||
log.Debug().Msgf("No update required")
|
||||
log.Debug().Msgf("no update required")
|
||||
}
|
||||
}(ctx)
|
||||
|
||||
|
@ -59,7 +59,7 @@ func After(_ context.Context, _ *cli.Command) error {
|
|||
case <-waitForUpdateCheck.Done():
|
||||
// When the actual command already finished, we still wait 500ms for the update check to finish
|
||||
case <-time.After(time.Millisecond * 500):
|
||||
log.Debug().Msg("Update check stopped due to timeout")
|
||||
log.Debug().Msg("update check stopped due to timeout")
|
||||
cancelWaitForUpdate(errors.New("update check timeout"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ func Load(ctx context.Context, c *cli.Command) error {
|
|||
}
|
||||
|
||||
if config.ServerURL == "" || config.Token == "" {
|
||||
log.Info().Msg("The woodpecker-cli is not yet set up. Please run `woodpecker-cli setup` or provide the required environment variables / flags.")
|
||||
log.Info().Msg("woodpecker-cli is not set up, run `woodpecker-cli setup` or provide required environment variables/flags")
|
||||
return errors.New("woodpecker-cli is not configured")
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ func Load(ctx context.Context, c *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Debug().Any("config", config).Msg("Loaded config")
|
||||
log.Debug().Any("config", config).Msg("loaded config")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -93,16 +93,16 @@ func Get(_ context.Context, c *cli.Command, _configPath string) (*Config, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log.Debug().Str("configPath", configPath).Msg("Checking for config file")
|
||||
log.Debug().Str("configPath", configPath).Msg("checking for config file")
|
||||
|
||||
content, err := os.ReadFile(configPath)
|
||||
switch {
|
||||
case err != nil && !os.IsNotExist(err):
|
||||
log.Debug().Err(err).Msg("Failed to read the config file")
|
||||
log.Debug().Err(err).Msg("failed to read the config file")
|
||||
return nil, err
|
||||
|
||||
case err != nil && os.IsNotExist(err):
|
||||
log.Debug().Msg("The config file does not exist")
|
||||
log.Debug().Msg("config file does not exist")
|
||||
|
||||
default:
|
||||
configFromFile := &Config{}
|
||||
|
@ -111,7 +111,7 @@ func Get(_ context.Context, c *cli.Command, _configPath string) (*Config, error)
|
|||
return nil, err
|
||||
}
|
||||
conf.MergeIfNotSet(configFromFile)
|
||||
log.Debug().Msg("Loaded config from file")
|
||||
log.Debug().Msg("loaded config from file")
|
||||
}
|
||||
|
||||
// if server or token are explicitly set, use them
|
||||
|
@ -123,11 +123,11 @@ func Get(_ context.Context, c *cli.Command, _configPath string) (*Config, error)
|
|||
service := c.Root().Name
|
||||
secret, err := keyring.Get(service, conf.ServerURL)
|
||||
if errors.Is(err, keyring.ErrUnsupportedPlatform) {
|
||||
log.Warn().Msg("Keyring is not supported on this platform")
|
||||
log.Warn().Msg("keyring is not supported on this platform")
|
||||
return conf, nil
|
||||
}
|
||||
if errors.Is(err, keyring.ErrNotFound) {
|
||||
log.Warn().Msg("Token not found in keyring")
|
||||
log.Warn().Msg("token not found in keyring")
|
||||
return conf, nil
|
||||
}
|
||||
conf.Token = secret
|
||||
|
|
|
@ -40,12 +40,12 @@ var Command = &cli.Command{
|
|||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_PRIVILEGED"),
|
||||
Name: "plugins-privileged",
|
||||
Usage: "Allow plugins to run in privileged mode, if environment variable is defined but empty there will be none",
|
||||
Usage: "allow plugins to run in privileged mode, if set empty, there is no",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_TRUSTED_CLONE"),
|
||||
Name: "plugins-trusted-clone",
|
||||
Usage: "Plugins which are trusted to handle Git credentials in clone steps",
|
||||
Usage: "plugins that are trusted to handle Git credentials in cloning steps",
|
||||
Value: constant.TrustedClonePlugins,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
|
|
|
@ -30,7 +30,7 @@ var Command = &cli.Command{
|
|||
registryCreateCmd,
|
||||
registryDeleteCmd,
|
||||
registryUpdateCmd,
|
||||
registryInfoCmd,
|
||||
registryShowCmd,
|
||||
registryListCmd,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
|
||||
var registryCreateCmd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a registry",
|
||||
Usage: "add a registry",
|
||||
ArgsUsage: "[org-id|org-full-name]",
|
||||
Action: registryCreate,
|
||||
Flags: []cli.Flag{
|
||||
|
|
|
@ -25,11 +25,11 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var registryInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display registry info",
|
||||
var registryShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show registry information",
|
||||
ArgsUsage: "[org-id|org-full-name]",
|
||||
Action: registryInfo,
|
||||
Action: registryShow,
|
||||
Flags: []cli.Flag{
|
||||
common.OrgFlag,
|
||||
&cli.StringFlag{
|
||||
|
@ -41,7 +41,7 @@ var registryInfoCmd = &cli.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func registryInfo(ctx context.Context, c *cli.Command) error {
|
||||
func registryShow(ctx context.Context, c *cli.Command) error {
|
||||
var (
|
||||
hostname = c.String("hostname")
|
||||
format = c.String("format") + "\n"
|
|
@ -30,7 +30,7 @@ var Command = &cli.Command{
|
|||
secretCreateCmd,
|
||||
secretDeleteCmd,
|
||||
secretUpdateCmd,
|
||||
secretInfoCmd,
|
||||
secretShowCmd,
|
||||
secretListCmd,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
|
||||
var secretCreateCmd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a secret",
|
||||
Usage: "add a secret",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: secretCreate,
|
||||
Flags: []cli.Flag{
|
||||
|
|
|
@ -43,11 +43,11 @@ var secretUpdateCmd = &cli.Command{
|
|||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "event",
|
||||
Usage: "secret limited to these events",
|
||||
Usage: "limit secret to these event",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "image",
|
||||
Usage: "secret limited to these images",
|
||||
Usage: "limit secret to these image",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var secretInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display secret info",
|
||||
var secretShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show secret information",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: secretInfo,
|
||||
Action: secretShow,
|
||||
Flags: []cli.Flag{
|
||||
common.OrgFlag,
|
||||
&cli.StringFlag{
|
||||
|
@ -41,7 +41,7 @@ var secretInfoCmd = &cli.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func secretInfo(ctx context.Context, c *cli.Command) error {
|
||||
func secretShow(ctx context.Context, c *cli.Command) error {
|
||||
var (
|
||||
secretName = c.String("name")
|
||||
format = c.String("format") + "\n"
|
|
@ -53,7 +53,7 @@ var Command = &cli.Command{
|
|||
&cli.StringSliceFlag{
|
||||
Name: "param",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "custom parameters to be injected into the step environment. Format: KEY=value",
|
||||
Usage: "custom parameters to inject into the step environment. Format: KEY=value",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
|
||||
var pipelineLastCmd = &cli.Command{
|
||||
Name: "last",
|
||||
Usage: "show latest pipeline details",
|
||||
Usage: "show latest pipeline information",
|
||||
ArgsUsage: "<repo-id|repo-full-name>",
|
||||
Action: pipelineLast,
|
||||
Flags: append(common.OutputFlags("table"), []cli.Flag{
|
||||
|
|
|
@ -52,7 +52,7 @@ func buildPipelineListCmd() *cli.Command {
|
|||
},
|
||||
&cli.TimestampFlag{
|
||||
Name: "before",
|
||||
Usage: "only return pipelines before this RFC3339 date",
|
||||
Usage: "only return pipelines before this date (RFC3339)",
|
||||
Config: cli.TimestampConfig{
|
||||
Layouts: []string{
|
||||
time.RFC3339,
|
||||
|
@ -61,7 +61,7 @@ func buildPipelineListCmd() *cli.Command {
|
|||
},
|
||||
&cli.TimestampFlag{
|
||||
Name: "after",
|
||||
Usage: "only return pipelines after this RFC3339 date",
|
||||
Usage: "only return pipelines after this date (RFC3339)",
|
||||
Config: cli.TimestampConfig{
|
||||
Layouts: []string{
|
||||
time.RFC3339,
|
||||
|
|
|
@ -35,7 +35,7 @@ var Command = &cli.Command{
|
|||
Commands: []*cli.Command{
|
||||
buildPipelineListCmd(),
|
||||
pipelineLastCmd,
|
||||
pipelineInfoCmd,
|
||||
pipelineShowCmd,
|
||||
pipelineStopCmd,
|
||||
pipelineStartCmd,
|
||||
pipelineApproveCmd,
|
||||
|
|
|
@ -25,15 +25,15 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
||||
)
|
||||
|
||||
var pipelineInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "show pipeline details",
|
||||
var pipelineShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show pipeline information",
|
||||
ArgsUsage: "<repo-id|repo-full-name> [pipeline]",
|
||||
Action: pipelineInfo,
|
||||
Action: pipelineShow,
|
||||
Flags: common.OutputFlags("table"),
|
||||
}
|
||||
|
||||
func pipelineInfo(ctx context.Context, c *cli.Command) error {
|
||||
func pipelineShow(ctx context.Context, c *cli.Command) error {
|
||||
repoIDOrFullName := c.Args().First()
|
||||
client, err := internal.NewClient(ctx, c)
|
||||
if err != nil {
|
|
@ -35,7 +35,7 @@ var pipelineStartCmd = &cli.Command{
|
|||
&cli.StringSliceFlag{
|
||||
Name: "param",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "custom parameters to be injected into the step environment. Format: KEY=value",
|
||||
Usage: "custom parameters to inject into the step environment. Format: KEY=value",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ var Command = &cli.Command{
|
|||
cronCreateCmd,
|
||||
cronDeleteCmd,
|
||||
cronUpdateCmd,
|
||||
cronInfoCmd,
|
||||
cronShowCmd,
|
||||
cronListCmd,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var cronInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display info about a cron job",
|
||||
var cronShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show cron job information",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: cronInfo,
|
||||
Action: cronShow,
|
||||
Flags: []cli.Flag{
|
||||
common.RepoFlag,
|
||||
&cli.StringFlag{
|
||||
|
@ -41,7 +41,7 @@ var cronInfoCmd = &cli.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func cronInfo(ctx context.Context, c *cli.Command) error {
|
||||
func cronShow(ctx context.Context, c *cli.Command) error {
|
||||
var (
|
||||
cronID = c.Int("id")
|
||||
repoIDOrFullName = c.String("repository")
|
|
@ -29,7 +29,7 @@ var Command = &cli.Command{
|
|||
registryCreateCmd,
|
||||
registryDeleteCmd,
|
||||
registryUpdateCmd,
|
||||
registryInfoCmd,
|
||||
registryShowCmd,
|
||||
registryListCmd,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
|
||||
var registryCreateCmd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a registry",
|
||||
Usage: "add a registry",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: registryCreate,
|
||||
Flags: []cli.Flag{
|
||||
|
|
|
@ -25,11 +25,11 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var registryInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display registry info",
|
||||
var registryShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show registry information",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: registryInfo,
|
||||
Action: registryShow,
|
||||
Flags: []cli.Flag{
|
||||
common.RepoFlag,
|
||||
&cli.StringFlag{
|
||||
|
@ -41,7 +41,7 @@ var registryInfoCmd = &cli.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func registryInfo(ctx context.Context, c *cli.Command) error {
|
||||
func registryShow(ctx context.Context, c *cli.Command) error {
|
||||
var (
|
||||
hostname = c.String("hostname")
|
||||
format = c.String("format") + "\n"
|
|
@ -28,7 +28,7 @@ var Command = &cli.Command{
|
|||
Usage: "manage repositories",
|
||||
Commands: []*cli.Command{
|
||||
repoListCmd,
|
||||
repoInfoCmd,
|
||||
repoShowCmd,
|
||||
repoAddCmd,
|
||||
repoUpdateCmd,
|
||||
repoRemoveCmd,
|
||||
|
|
|
@ -25,15 +25,15 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var repoInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "show repository details",
|
||||
var repoShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show repository information",
|
||||
ArgsUsage: "<repo-id|repo-full-name>",
|
||||
Action: repoInfo,
|
||||
Action: repoShow,
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplRepoInfo)},
|
||||
}
|
||||
|
||||
func repoInfo(ctx context.Context, c *cli.Command) error {
|
||||
func repoShow(ctx context.Context, c *cli.Command) error {
|
||||
repoIDOrFullName := c.Args().First()
|
||||
client, err := internal.NewClient(ctx, c)
|
||||
if err != nil {
|
|
@ -53,7 +53,7 @@ var repoUpdateCmd = &cli.Command{
|
|||
},
|
||||
&cli.StringFlag{
|
||||
Name: "config",
|
||||
Usage: "repository configuration path (e.g. .woodpecker.yml)",
|
||||
Usage: "repository configuration path. Example: .woodpecker.yml",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "pipeline-counter",
|
||||
|
@ -61,7 +61,7 @@ var repoUpdateCmd = &cli.Command{
|
|||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "unsafe",
|
||||
Usage: "validate updating the pipeline-counter is unsafe",
|
||||
Usage: "allow unsafe operations",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ var Command = &cli.Command{
|
|||
secretCreateCmd,
|
||||
secretDeleteCmd,
|
||||
secretUpdateCmd,
|
||||
secretInfoCmd,
|
||||
secretShowCmd,
|
||||
secretListCmd,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
|
||||
var secretCreateCmd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a secret",
|
||||
Usage: "add a secret",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: secretCreate,
|
||||
Flags: []cli.Flag{
|
||||
|
@ -43,11 +43,11 @@ var secretCreateCmd = &cli.Command{
|
|||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "event",
|
||||
Usage: "secret limited to these events",
|
||||
Usage: "limit secret to these events",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "image",
|
||||
Usage: "secret limited to these images",
|
||||
Usage: "limit secret to these images",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -43,11 +43,11 @@ var secretUpdateCmd = &cli.Command{
|
|||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "event",
|
||||
Usage: "secret limited to these events",
|
||||
Usage: "limit secret to these events",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "image",
|
||||
Usage: "secret limited to these images",
|
||||
Usage: "limit secret to these images",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
)
|
||||
|
||||
var secretInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display secret info",
|
||||
var secretShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show secret information",
|
||||
ArgsUsage: "[repo-id|repo-full-name]",
|
||||
Action: secretInfo,
|
||||
Action: secretShow,
|
||||
Flags: []cli.Flag{
|
||||
common.RepoFlag,
|
||||
&cli.StringFlag{
|
||||
|
@ -41,7 +41,7 @@ var secretInfoCmd = &cli.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func secretInfo(ctx context.Context, c *cli.Command) error {
|
||||
func secretShow(ctx context.Context, c *cli.Command) error {
|
||||
var (
|
||||
secretName = c.String("name")
|
||||
format = c.String("format") + "\n"
|
|
@ -20,11 +20,11 @@ var Command = &cli.Command{
|
|||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "server",
|
||||
Usage: "The URL of the woodpecker server",
|
||||
Usage: "URL of the woodpecker server",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "token",
|
||||
Usage: "The token to authenticate with the woodpecker server",
|
||||
Usage: "token to authenticate with the woodpecker server",
|
||||
},
|
||||
},
|
||||
Action: setup,
|
||||
|
@ -41,7 +41,7 @@ func setup(ctx context.Context, c *cli.Command) error {
|
|||
}
|
||||
|
||||
if !setupAgain {
|
||||
log.Info().Msg("Configuration skipped")
|
||||
log.Info().Msg("configuration skipped")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func setup(ctx context.Context, c *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Info().Msg("The woodpecker-cli has been successfully setup")
|
||||
log.Info().Msg("woodpecker-cli has been successfully setup")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ func receiveTokenFromUI(c context.Context, serverURL string) (string, error) {
|
|||
srv.Handler = setupRouter(tokenReceived)
|
||||
|
||||
go func() {
|
||||
log.Debug().Msgf("Listening for token response on :%d", port)
|
||||
log.Debug().Msgf("listening for token response on :%d", port)
|
||||
_ = srv.ListenAndServe()
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
log.Debug().Msg("Shutting down server")
|
||||
log.Debug().Msg("shutting down server")
|
||||
_ = srv.Shutdown(c)
|
||||
}()
|
||||
|
||||
|
@ -90,7 +90,7 @@ func setupRouter(tokenReceived chan string) *gin.Engine {
|
|||
|
||||
err := c.BindJSON(&data)
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Msg("Failed to bind JSON")
|
||||
log.Debug().Err(err).Msg("failed to bind JSON")
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "invalid request",
|
||||
})
|
||||
|
@ -110,7 +110,7 @@ func setupRouter(tokenReceived chan string) *gin.Engine {
|
|||
func openBrowser(url string) error {
|
||||
var err error
|
||||
|
||||
log.Debug().Msgf("Opening browser with URL: %s", url)
|
||||
log.Debug().Msgf("opening browser with URL: %s", url)
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
|
|
|
@ -24,7 +24,7 @@ var Command = &cli.Command{
|
|||
}
|
||||
|
||||
func update(ctx context.Context, c *cli.Command) error {
|
||||
log.Info().Msg("Checking for updates ...")
|
||||
log.Info().Msg("checking for updates ...")
|
||||
|
||||
newVersion, err := CheckForUpdate(ctx, c.Bool("force"))
|
||||
if err != nil {
|
||||
|
@ -32,11 +32,11 @@ func update(ctx context.Context, c *cli.Command) error {
|
|||
}
|
||||
|
||||
if newVersion == nil {
|
||||
fmt.Println("You are using the latest version of woodpecker-cli")
|
||||
fmt.Println("you are using the latest version of woodpecker-cli")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info().Msgf("New version %s is available! Updating ...", newVersion.Version)
|
||||
log.Info().Msgf("new version %s is available! Updating ...", newVersion.Version)
|
||||
|
||||
var tarFilePath string
|
||||
tarFilePath, err = downloadNewVersion(ctx, newVersion.AssetURL)
|
||||
|
@ -44,14 +44,14 @@ func update(ctx context.Context, c *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Debug().Msgf("New version %s has been downloaded successfully! Installing ...", newVersion.Version)
|
||||
log.Debug().Msgf("new version %s has been downloaded successfully! Installing ...", newVersion.Version)
|
||||
|
||||
binFile, err := extractNewVersion(tarFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug().Msgf("New version %s has been extracted to %s", newVersion.Version, binFile)
|
||||
log.Debug().Msgf("new version %s has been extracted to %s", newVersion.Version, binFile)
|
||||
|
||||
executablePathOrSymlink, err := os.Executable()
|
||||
if err != nil {
|
||||
|
|
|
@ -22,10 +22,10 @@ func CheckForUpdate(ctx context.Context, force bool) (*NewVersion, error) {
|
|||
}
|
||||
|
||||
func checkForUpdate(ctx context.Context, versionURL string, force bool) (*NewVersion, error) {
|
||||
log.Debug().Msgf("Current version: %s", version.String())
|
||||
log.Debug().Msgf("current version: %s", version.String())
|
||||
|
||||
if (version.String() == "dev" || strings.HasPrefix(version.String(), "next-")) && !force {
|
||||
log.Debug().Msgf("Skipping update check for development & next versions")
|
||||
log.Debug().Msgf("skipping update check for development/next versions")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -61,11 +61,11 @@ func checkForUpdate(ctx context.Context, versionURL string, force bool) (*NewVer
|
|||
|
||||
// using the latest release
|
||||
if installedVersion == upstreamVersion && !force {
|
||||
log.Debug().Msgf("No new version available")
|
||||
log.Debug().Msgf("no new version available")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
log.Debug().Msgf("New version available: %s", upstreamVersion)
|
||||
log.Debug().Msgf("new version available: %s", upstreamVersion)
|
||||
|
||||
assetURL := fmt.Sprintf(githubBinaryURL, upstreamVersion, runtime.GOOS, runtime.GOARCH)
|
||||
return &NewVersion{
|
||||
|
@ -75,7 +75,7 @@ func checkForUpdate(ctx context.Context, versionURL string, force bool) (*NewVer
|
|||
}
|
||||
|
||||
func downloadNewVersion(ctx context.Context, downloadURL string) (string, error) {
|
||||
log.Debug().Msgf("Downloading new version from %s ...", downloadURL)
|
||||
log.Debug().Msgf("downloading new version from %s ...", downloadURL)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, downloadURL, nil)
|
||||
if err != nil {
|
||||
|
@ -102,13 +102,13 @@ func downloadNewVersion(ctx context.Context, downloadURL string) (string, error)
|
|||
return "", err
|
||||
}
|
||||
|
||||
log.Debug().Msgf("New version downloaded to %s", file.Name())
|
||||
log.Debug().Msgf("new version downloaded to %s", file.Name())
|
||||
|
||||
return file.Name(), nil
|
||||
}
|
||||
|
||||
func extractNewVersion(tarFilePath string) (string, error) {
|
||||
log.Debug().Msgf("Extracting new version from %s ...", tarFilePath)
|
||||
log.Debug().Msgf("extracting new version from %s ...", tarFilePath)
|
||||
|
||||
tarFile, err := os.Open(tarFilePath)
|
||||
if err != nil {
|
||||
|
@ -132,7 +132,7 @@ func extractNewVersion(tarFilePath string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
log.Debug().Msgf("New version extracted to %s", tmpDir)
|
||||
log.Debug().Msgf("new version extracted to %s", tmpDir)
|
||||
|
||||
return path.Join(tmpDir, "woodpecker-cli"), nil
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ This will be the next version of Woodpecker.
|
|||
- `woodpecker-cli cron` is now `woodpecker-cli repo cron`
|
||||
- `woodpecker-cli secret [add|rm|...] --repository` is now `woodpecker-cli repo secret [add|rm|...]`
|
||||
- `woodpecker-cli pipeline logs` is now `woodpecker-cli pipeline log show`
|
||||
- `woodpecker-cli [registry|secret|...] info` is now `woodpecker-cli [registry|secret|...] show`
|
||||
|
||||
## Admin migrations
|
||||
|
||||
|
|
1
web/.gitignore
vendored
1
web/.gitignore
vendored
|
@ -3,4 +3,3 @@ node_modules
|
|||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
src/assets/dayjsLocales
|
||||
|
|
|
@ -4,5 +4,4 @@ coverage/
|
|||
LICENSE
|
||||
components.d.ts
|
||||
src/assets/locales/*.json
|
||||
src/assets/dayjsLocales/
|
||||
!src/assets/locales/en.json
|
||||
|
|
|
@ -106,7 +106,6 @@ export default antfu(
|
|||
'tsconfig.json',
|
||||
'src/assets/locales/**/*',
|
||||
'!src/assets/locales/en.json',
|
||||
'src/assets/dayjsLocales/',
|
||||
'components.d.ts',
|
||||
],
|
||||
},
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
"@mdi/js": "^7.4.47",
|
||||
"@vueuse/core": "^12.0.0",
|
||||
"ansi_up": "^6.0.2",
|
||||
"dayjs": "^1.11.12",
|
||||
"dompurify": "^3.2.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"js-base64": "^3.7.7",
|
||||
|
@ -57,7 +56,6 @@
|
|||
"eslint-plugin-vue-scoped-css": "^2.8.1",
|
||||
"jsdom": "^25.0.0",
|
||||
"prettier": "^3.3.3",
|
||||
"replace-in-file": "^8.1.0",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"typescript": "5.6.3",
|
||||
"vite": "^5.4.1",
|
||||
|
|
|
@ -26,9 +26,6 @@ importers:
|
|||
ansi_up:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
dayjs:
|
||||
specifier: ^1.11.12
|
||||
version: 1.11.13
|
||||
dompurify:
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.1
|
||||
|
@ -123,9 +120,6 @@ importers:
|
|||
prettier:
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3
|
||||
replace-in-file:
|
||||
specifier: ^8.1.0
|
||||
version: 8.2.0
|
||||
tinycolor2:
|
||||
specifier: ^1.6.0
|
||||
version: 1.6.0
|
||||
|
@ -1107,10 +1101,6 @@ packages:
|
|||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
chalk@5.3.0:
|
||||
resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
|
||||
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
|
||||
|
||||
char-regex@1.0.2:
|
||||
resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -1214,9 +1204,6 @@ packages:
|
|||
resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
dayjs@1.11.13:
|
||||
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
|
||||
|
||||
de-indent@1.0.2:
|
||||
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
|
||||
|
||||
|
@ -2295,11 +2282,6 @@ packages:
|
|||
resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==}
|
||||
hasBin: true
|
||||
|
||||
replace-in-file@8.2.0:
|
||||
resolution: {integrity: sha512-hMsQtdYHwWviQT5ZbNsgfu0WuCiNlcUSnnD+aHAL081kbU9dPkPocDaHlDvAHKydTWWpx1apfcEcmvIyQk3CpQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -3798,8 +3780,6 @@ snapshots:
|
|||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
|
||||
chalk@5.3.0: {}
|
||||
|
||||
char-regex@1.0.2: {}
|
||||
|
||||
character-entities@2.0.2: {}
|
||||
|
@ -3898,8 +3878,6 @@ snapshots:
|
|||
whatwg-mimetype: 4.0.0
|
||||
whatwg-url: 14.0.0
|
||||
|
||||
dayjs@1.11.13: {}
|
||||
|
||||
de-indent@1.0.2: {}
|
||||
|
||||
debug@3.2.7:
|
||||
|
@ -5205,12 +5183,6 @@ snapshots:
|
|||
dependencies:
|
||||
jsesc: 0.5.0
|
||||
|
||||
replace-in-file@8.2.0:
|
||||
dependencies:
|
||||
chalk: 5.3.0
|
||||
glob: 10.4.5
|
||||
yargs: 17.7.2
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
"delete_agent": "Odstranit agent",
|
||||
"delete_confirm": "Opravdu chcete tohoto agenta odstranit? Už se nebude moci připojit k serveru.",
|
||||
"deleted": "Agent smazán",
|
||||
"desc": "Agenti registrovaní pro tento server",
|
||||
"desc": "Agenti registrovaní na tomto serveru.",
|
||||
"edit_agent": "Upravit agent",
|
||||
"id": "ID",
|
||||
"last_contact": "Poslední kontakt",
|
||||
|
@ -41,12 +41,12 @@
|
|||
"token": "Tokeny",
|
||||
"version": "Verze"
|
||||
},
|
||||
"not_allowed": "Nemáte povolen přístup k nastavení serveru",
|
||||
"not_allowed": "K nastavení serveru nemáte přístup.",
|
||||
"orgs": {
|
||||
"delete_confirm": "Opravdu chcete tuto organizaci smazat? Tím se odstraní také všechna úložiště vlastněná touto organizací.",
|
||||
"delete_org": "Odstranit organizaci",
|
||||
"deleted": "Organizace vymazána",
|
||||
"desc": "Organizace vlastnící úložiště na tomto serveru",
|
||||
"desc": "Organizace vlastnící repozitáře na tomto serveru.",
|
||||
"none": "Zatím neexistují žádné organizace.",
|
||||
"org_settings": "Organizační nastavení",
|
||||
"orgs": "Organizace",
|
||||
|
@ -74,7 +74,7 @@
|
|||
"waiting_for": "čekání na"
|
||||
},
|
||||
"repos": {
|
||||
"desc": "Úložiště, která jsou nebo byla na tomto serveru povolena",
|
||||
"desc": "Repozitáře, které jsou nebo byly na tomto serveru povoleny.",
|
||||
"disabled": "Bezbariérový",
|
||||
"none": "Zatím neexistují žádná úložiště.",
|
||||
"repos": "Repozitáře",
|
||||
|
@ -198,7 +198,7 @@
|
|||
"success": "Repozitář povoleno"
|
||||
},
|
||||
"manual_pipeline": {
|
||||
"select_branch": "Vyberte pobočku",
|
||||
"select_branch": "Vyberte větev",
|
||||
"title": "Spuštění ručního spuštění potrubí",
|
||||
"trigger": "Spustit potrubí",
|
||||
"variables": {
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
"not_found": "Server could not find requested object"
|
||||
},
|
||||
"time": {
|
||||
"template": "MMM D, YYYY, HH:mm z",
|
||||
"not_started": "not started yet"
|
||||
"not_started": "not started yet",
|
||||
"just_now": "just now"
|
||||
},
|
||||
"repo": {
|
||||
"manual_pipeline": {
|
||||
|
|
|
@ -1 +1,67 @@
|
|||
{}
|
||||
{
|
||||
"back": "Vissza",
|
||||
"logout": "Kijelentkezés",
|
||||
"search": "Keresés…",
|
||||
"username": "Felhasználónév",
|
||||
"unknown_error": "Ismeretlen hiba történt",
|
||||
"password": "Jelszó",
|
||||
"repo": {
|
||||
"visibility": {
|
||||
"public": {
|
||||
"public": "Nyilvános"
|
||||
},
|
||||
"private": {
|
||||
"private": "Privát",
|
||||
"desc": "Csak te és a többi tulajdonos láthatjátok ezt a projektet a tárolóban."
|
||||
},
|
||||
"internal": {
|
||||
"internal": "Belső"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"general": {
|
||||
"timeout": {
|
||||
"minutes": "percek"
|
||||
},
|
||||
"save": "Beállítások mentése",
|
||||
"project": "Projekt beállítások",
|
||||
"success": "Projekt beállítások frissítve"
|
||||
},
|
||||
"actions": {
|
||||
"disable": {
|
||||
"disable": "Tároló inaktiválása"
|
||||
},
|
||||
"delete": {
|
||||
"delete": "Tároló törlése"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pipeline": {
|
||||
"loading": "Betöltés…"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"settings": {
|
||||
"users": {
|
||||
"show": "Mutasd a felhasználokat",
|
||||
"cancel": "Mégse",
|
||||
"save": "Felhasználó mentése",
|
||||
"add": "Felhasználó hozzáadása",
|
||||
"deleted": "Felhasználó törölve",
|
||||
"created": "Felhasználó létrehozva",
|
||||
"saved": "Felhasználó mentve",
|
||||
"delete_user": "Felhasználó törlése",
|
||||
"edit_user": "Felhasználó szerkesztése"
|
||||
},
|
||||
"orgs": {
|
||||
"orgs": "Szervezetek",
|
||||
"delete_org": "Szervezet törlése"
|
||||
}
|
||||
}
|
||||
},
|
||||
"cancel": "Mégse",
|
||||
"login": "Bejelentkezés",
|
||||
"internal_error": "Valamilyen belső hiba történt",
|
||||
"info": "Információ",
|
||||
"registration_closed": "A regisztráció zárva"
|
||||
}
|
||||
|
|
|
@ -1,44 +1,94 @@
|
|||
import dayjs from 'dayjs';
|
||||
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import timezone from 'dayjs/plugin/timezone';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
dayjs.extend(timezone);
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(advancedFormat);
|
||||
dayjs.extend(relativeTime);
|
||||
dayjs.extend(duration);
|
||||
let currentLocale = 'en';
|
||||
|
||||
function toLocaleString(date: Date) {
|
||||
return dayjs(date).format(useI18n().t('time.template'));
|
||||
function splitDuration(durationMs: number) {
|
||||
const totalSeconds = durationMs / 1000;
|
||||
const totalMinutes = totalSeconds / 60;
|
||||
const totalHours = totalMinutes / 60;
|
||||
|
||||
const seconds = Math.floor(totalSeconds) % 60;
|
||||
const minutes = Math.floor(totalMinutes) % 60;
|
||||
const hours = Math.floor(totalHours) % 24;
|
||||
|
||||
return {
|
||||
seconds,
|
||||
minutes,
|
||||
hours,
|
||||
totalHours,
|
||||
totalMinutes,
|
||||
totalSeconds,
|
||||
};
|
||||
}
|
||||
|
||||
function timeAgo(date: Date | string | number) {
|
||||
return dayjs().to(dayjs(date));
|
||||
function toLocaleString(date: Date) {
|
||||
return date.toLocaleString(currentLocale, {
|
||||
dateStyle: 'short',
|
||||
timeStyle: 'short',
|
||||
});
|
||||
}
|
||||
|
||||
function timeAgo(date: number) {
|
||||
const seconds = Math.floor((new Date().getTime() - date) / 1000);
|
||||
|
||||
const formatter = new Intl.RelativeTimeFormat(currentLocale);
|
||||
|
||||
let interval = seconds / 31536000;
|
||||
if (interval > 1) {
|
||||
return formatter.format(-Math.round(interval), 'year');
|
||||
}
|
||||
interval = seconds / 2592000;
|
||||
if (interval > 1) {
|
||||
return formatter.format(-Math.round(interval), 'month');
|
||||
}
|
||||
interval = seconds / 86400;
|
||||
if (interval > 1) {
|
||||
return formatter.format(-Math.round(interval), 'day');
|
||||
}
|
||||
interval = seconds / 3600;
|
||||
if (interval > 1) {
|
||||
return formatter.format(-Math.round(interval), 'hour');
|
||||
}
|
||||
interval = seconds / 60;
|
||||
if (interval > 0.5) {
|
||||
return formatter.format(-Math.round(interval), 'minute');
|
||||
}
|
||||
return useI18n().t('time.just_now');
|
||||
}
|
||||
|
||||
function prettyDuration(durationMs: number) {
|
||||
return dayjs.duration(durationMs).humanize();
|
||||
const t = splitDuration(durationMs);
|
||||
|
||||
if (t.totalHours > 1) {
|
||||
return Intl.NumberFormat(currentLocale, { style: 'unit', unit: 'hour', unitDisplay: 'long' }).format(
|
||||
Math.round(t.totalHours),
|
||||
);
|
||||
}
|
||||
if (t.totalMinutes > 1) {
|
||||
return Intl.NumberFormat(currentLocale, { style: 'unit', unit: 'minute', unitDisplay: 'long' }).format(
|
||||
Math.round(t.totalMinutes),
|
||||
);
|
||||
}
|
||||
return Intl.NumberFormat(currentLocale, { style: 'unit', unit: 'second', unitDisplay: 'long' }).format(
|
||||
Math.round(t.totalSeconds),
|
||||
);
|
||||
}
|
||||
|
||||
function durationAsNumber(durationMs: number): string {
|
||||
const dur = dayjs.duration(durationMs);
|
||||
return dur.format(dur.hours() > 1 ? 'HH:mm:ss' : 'mm:ss');
|
||||
const { seconds, minutes, hours } = splitDuration(durationMs);
|
||||
|
||||
const minSecFormat = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||||
|
||||
if (hours > 0) {
|
||||
return `${hours.toString().padStart(2, '0')}:${minSecFormat}`;
|
||||
}
|
||||
|
||||
return minSecFormat;
|
||||
}
|
||||
|
||||
export function useDate() {
|
||||
const addedLocales = ['en'];
|
||||
|
||||
async function setDayjsLocale(locale: string) {
|
||||
if (!addedLocales.includes(locale)) {
|
||||
const l = (await import(`~/assets/dayjsLocales/${locale}.js`)) as { default: string };
|
||||
dayjs.locale(l.default);
|
||||
} else {
|
||||
dayjs.locale(locale);
|
||||
}
|
||||
currentLocale = locale;
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { copyFile, existsSync, mkdirSync, readdirSync } from 'node:fs';
|
||||
import { readdirSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import { replaceInFileSync } from 'replace-in-file';
|
||||
import type { Plugin } from 'vite';
|
||||
import prismjs from 'vite-plugin-prismjs';
|
||||
import WindiCSS from 'vite-plugin-windicss';
|
||||
|
@ -54,44 +53,6 @@ export default defineConfig({
|
|||
|
||||
const filenames = readdirSync('src/assets/locales/').map((filename) => filename.replace('.json', ''));
|
||||
|
||||
if (!existsSync('src/assets/dayjsLocales')) {
|
||||
mkdirSync('src/assets/dayjsLocales');
|
||||
}
|
||||
|
||||
filenames.forEach((name) => {
|
||||
// English is always directly loaded (compiled by Vite) and thus not copied
|
||||
if (name === 'en') {
|
||||
return;
|
||||
}
|
||||
let langName = name;
|
||||
|
||||
// copy dayjs language
|
||||
if (name === 'zh-Hans') {
|
||||
// zh-Hans is called zh in dayjs
|
||||
langName = 'zh';
|
||||
} else if (name === 'zh-Hant') {
|
||||
// zh-Hant is called zh-cn in dayjs
|
||||
langName = 'zh-cn';
|
||||
}
|
||||
|
||||
copyFile(
|
||||
`node_modules/dayjs/esm/locale/${langName}.js`,
|
||||
`src/assets/dayjsLocales/${name}.js`,
|
||||
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
||||
(err) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
replaceInFileSync({
|
||||
files: 'src/assets/dayjsLocales/*.js',
|
||||
// remove any dayjs import and any dayjs.locale call
|
||||
from: /(?:import dayjs.*'|dayjs\.locale.*);/g,
|
||||
to: '',
|
||||
});
|
||||
|
||||
return {
|
||||
name: 'vue-i18n-supported-locales',
|
||||
|
||||
|
|
Loading…
Reference in a new issue