-
Notifications
You must be signed in to change notification settings - Fork 8
RPS-10166 Job strings #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| package add | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "os" | ||
|
|
||
| stringscmd "github.com/Smartling/smartling-cli/cmd/jobs/strings" | ||
| "github.com/Smartling/smartling-cli/output" | ||
| "github.com/Smartling/smartling-cli/services/helpers/rlog" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const ( | ||
| hashcodeFlag = "hashcode" | ||
| targetLocaleFlag = "target-locale" | ||
| moveEnabledFlag = "move-enabled" | ||
| ) | ||
|
|
||
| // NewJobStringsAddCmd returns new command to job string add | ||
| func NewJobStringsAddCmd(initializer stringscmd.SrvInitializer) *cobra.Command { | ||
| var ( | ||
| hashcodes []string | ||
| targetLocales []string | ||
| moveEnabled bool | ||
| ) | ||
| addCmd := &cobra.Command{ | ||
| Use: "add <translationJobUid|translationJobName>", | ||
| Short: "Add strings to a translation job.", | ||
| Long: `Assign strings (by hashcode) to an existing translation job, identified by UID or name.`, | ||
| Args: cobra.ExactArgs(1), | ||
| Example: ` | ||
| # Add two strings to a job | ||
|
|
||
| smartling-cli jobs strings add aabbccdd1122 --hashcode h1 --hashcode h2 | ||
|
|
||
| # Add a string for specific locales, moving it if it already belongs to another job | ||
|
|
||
| smartling-cli jobs strings add "Website Q1 2026" --hashcode h1 --target-locale fr-FR --move-enabled | ||
| `, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| ctx := cmd.Context() | ||
|
|
||
| params, err := resolveParams(args[0], hashcodes, targetLocales, moveEnabled) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to resolve add params: %w", err) | ||
| } | ||
| format, err := cmd.Flags().GetString("output") | ||
| if err != nil { | ||
| return err | ||
| } | ||
| return run(ctx, initializer, params, output.Params{Format: format}) | ||
| }, | ||
| } | ||
|
|
||
| addCmd.Flags().StringArrayVar(&hashcodes, hashcodeFlag, nil, "String hashcode to add (repeatable, required).") | ||
| addCmd.Flags().StringArrayVar(&targetLocales, targetLocaleFlag, nil, "Target locale to add the strings to (repeatable; default all job locales).") | ||
| addCmd.Flags().BoolVar(&moveEnabled, moveEnabledFlag, false, "Move the string into this job if it already belongs to another job for a locale.") | ||
| if err := addCmd.MarkFlagRequired(hashcodeFlag); err != nil { | ||
| rlog.Errorf("failed to mark --%s required: %s", hashcodeFlag, err) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| return addCmd | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package add | ||
|
|
||
| import ( | ||
| rootcmd "github.com/Smartling/smartling-cli/cmd" | ||
| clierror "github.com/Smartling/smartling-cli/services/helpers/cli_error" | ||
| "github.com/Smartling/smartling-cli/services/helpers/rlog" | ||
| srv "github.com/Smartling/smartling-cli/services/jobs/strings" | ||
| ) | ||
|
|
||
| func resolveParams(jobUIDOrName string, hashcodes, targetLocales []string, moveEnabled bool) (srv.AddParams, error) { | ||
| rlog.Debugf("resolving add params") | ||
|
|
||
| cnf, err := rootcmd.Config() | ||
| if err != nil { | ||
| return srv.AddParams{}, clierror.UIError{ | ||
| Operation: "config", | ||
| Err: err, | ||
| Description: "failed to read config", | ||
| } | ||
| } | ||
|
|
||
| return srv.AddParams{ | ||
| ProjectID: cnf.ProjectID, | ||
| JobUIDOrName: jobUIDOrName, | ||
| Hashcodes: hashcodes, | ||
| TargetLocaleIDs: targetLocales, | ||
| MoveEnabled: moveEnabled, | ||
| }, nil | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| package add | ||
|
|
||
| import ( | ||
| "os" | ||
| "path/filepath" | ||
| "testing" | ||
|
|
||
| rootcmd "github.com/Smartling/smartling-cli/cmd" | ||
| ) | ||
|
|
||
| func TestMain(m *testing.M) { | ||
| rootcmd.ConfigureLogger() | ||
| os.Exit(m.Run()) | ||
| } | ||
|
|
||
| func writeConfig(t *testing.T, content string) string { | ||
| t.Helper() | ||
| path := filepath.Join(t.TempDir(), "smartling.yml") | ||
| if err := os.WriteFile(path, []byte(content), 0o600); err != nil { | ||
| t.Fatalf("write config: %v", err) | ||
| } | ||
| return path | ||
| } | ||
|
|
||
| func Test_resolveParams(t *testing.T) { | ||
| // Config() always requires these. | ||
| t.Setenv("SMARTLING_USER_ID", "test-user") | ||
| t.Setenv("SMARTLING_SECRET", "test-secret") | ||
|
|
||
| root := rootcmd.NewRootCmd() | ||
| cfgPath := writeConfig(t, "project_id: config-project-id\n") | ||
| if err := root.PersistentFlags().Set("config", cfgPath); err != nil { | ||
| t.Fatalf("set config flag: %v", err) | ||
| } | ||
| t.Cleanup(func() { _ = root.PersistentFlags().Set("config", "") }) | ||
|
|
||
| params, err := resolveParams("aabbccdd1122", []string{"h1", "h2"}, []string{"fr-FR"}, true) | ||
| if err != nil { | ||
| t.Fatalf("resolveParams() error = %v", err) | ||
| } | ||
| if params.ProjectID != "config-project-id" { | ||
| t.Errorf("ProjectID = %q, want config-project-id", params.ProjectID) | ||
| } | ||
| if params.JobUIDOrName != "aabbccdd1122" { | ||
| t.Errorf("JobUIDOrName = %q, want aabbccdd1122", params.JobUIDOrName) | ||
| } | ||
| if len(params.Hashcodes) != 2 || params.Hashcodes[0] != "h1" { | ||
| t.Errorf("Hashcodes = %v, want [h1 h2]", params.Hashcodes) | ||
| } | ||
| if len(params.TargetLocaleIDs) != 1 || params.TargetLocaleIDs[0] != "fr-FR" { | ||
| t.Errorf("TargetLocaleIDs = %v, want [fr-FR]", params.TargetLocaleIDs) | ||
| } | ||
| if !params.MoveEnabled { | ||
| t.Error("MoveEnabled = false, want true") | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package add | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "fmt" | ||
|
|
||
| stringscmd "github.com/Smartling/smartling-cli/cmd/jobs/strings" | ||
| "github.com/Smartling/smartling-cli/output" | ||
| "github.com/Smartling/smartling-cli/output/static" | ||
| clierror "github.com/Smartling/smartling-cli/services/helpers/cli_error" | ||
| "github.com/Smartling/smartling-cli/services/helpers/rlog" | ||
| srv "github.com/Smartling/smartling-cli/services/jobs/strings" | ||
|
|
||
| jobapi "github.com/Smartling/api-sdk-go/api/job" | ||
| ) | ||
|
|
||
| func run(ctx context.Context, | ||
| initializer stringscmd.SrvInitializer, | ||
| params srv.AddParams, | ||
| outputParams output.Params, | ||
| ) error { | ||
| rlog.Debugf("running jobs strings add with params: %v", params) | ||
| stringsSrv, err := initializer.InitJobStringsSrv(ctx) | ||
| if err != nil { | ||
| return clierror.UIError{ | ||
| Operation: "init", | ||
| Err: err, | ||
| Description: "unable to initialize Job Strings service", | ||
| } | ||
| } | ||
|
|
||
| addOutput, err := stringsSrv.RunAdd(ctx, params) | ||
| if err != nil { | ||
| if errors.Is(err, jobapi.ErrNotFound) { | ||
| return clierror.UIError{ | ||
| Operation: "find job", | ||
| Err: err, | ||
| Description: fmt.Sprintf("no job found for %q", params.JobUIDOrName), | ||
| } | ||
| } | ||
| return err | ||
| } | ||
|
|
||
| static.GetOutputFormat[srv.MutateOutput](outputParams.Format).FormatAndRender(addOutput) | ||
| return nil | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| package jobstrings | ||
|
|
||
| import ( | ||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| // NewJobStringsCmd returns new job strings command | ||
| func NewJobStringsCmd() *cobra.Command { | ||
| jobStringsCmd := &cobra.Command{ | ||
| Use: "strings", | ||
| Short: "Manage strings on a translation job.", | ||
| Long: `Add, remove, or list the strings on an existing translation job. | ||
|
|
||
| Strings are identified by hashcode. Use these commands to assign strings to a | ||
| job, detach them, or inspect which strings a job currently contains.`, | ||
| Example: ` | ||
| # Add strings to a job | ||
|
|
||
| smartling-cli jobs strings add <translationJobUid|translationJobName> --hashcode <hashcode> | ||
|
|
||
| # Remove strings from a job | ||
|
|
||
| smartling-cli jobs strings remove <translationJobUid|translationJobName> --hashcode <hashcode> | ||
|
|
||
| # List a job's strings | ||
|
|
||
| smartling-cli jobs strings list <translationJobUid|translationJobName> | ||
|
|
||
| `, | ||
| } | ||
|
|
||
| return jobStringsCmd | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package list | ||
|
|
||
| import ( | ||
| "fmt" | ||
|
|
||
| stringscmd "github.com/Smartling/smartling-cli/cmd/jobs/strings" | ||
| "github.com/Smartling/smartling-cli/output" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const ( | ||
| targetLocaleFlag = "target-locale" | ||
| limitFlag = "limit" | ||
| offsetFlag = "offset" | ||
| ) | ||
|
|
||
| // NewJobStringsListCmd returns new command to job string list | ||
| func NewJobStringsListCmd(initializer stringscmd.SrvInitializer) *cobra.Command { | ||
| var ( | ||
| targetLocale string | ||
| limit uint32 | ||
| offset uint32 | ||
| ) | ||
| listCmd := &cobra.Command{ | ||
| Use: "list <translationJobUid|translationJobName>", | ||
| Short: "List the strings on a translation job.", | ||
| Long: `List the strings (by hashcode and target locale) assigned to a translation job, identified by UID or name.`, | ||
| Args: cobra.ExactArgs(1), | ||
| Example: ` | ||
| # List a job's strings | ||
|
|
||
| smartling-cli jobs strings list aabbccdd1122 | ||
|
|
||
| # List strings for one locale as a table | ||
|
|
||
| smartling-cli jobs strings list "Website Q1 2026" --target-locale fr-FR --output table | ||
| `, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| ctx := cmd.Context() | ||
|
|
||
| params, err := resolveParams(args[0], targetLocale, limit, offset) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to resolve list params: %w", err) | ||
| } | ||
| format, err := cmd.Flags().GetString("output") | ||
| if err != nil { | ||
| return err | ||
| } | ||
| return run(ctx, initializer, params, output.Params{Format: format}) | ||
| }, | ||
| } | ||
|
|
||
| listCmd.Flags().StringVar(&targetLocale, targetLocaleFlag, "", "Filter strings by target locale.") | ||
| listCmd.Flags().Uint32Var(&limit, limitFlag, 0, "Maximum number of strings to return.") | ||
| listCmd.Flags().Uint32Var(&offset, offsetFlag, 0, "Number of strings to skip.") | ||
|
|
||
| return listCmd | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package list | ||
|
|
||
| import ( | ||
| rootcmd "github.com/Smartling/smartling-cli/cmd" | ||
| clierror "github.com/Smartling/smartling-cli/services/helpers/cli_error" | ||
| "github.com/Smartling/smartling-cli/services/helpers/rlog" | ||
| srv "github.com/Smartling/smartling-cli/services/jobs/strings" | ||
| ) | ||
|
|
||
| func resolveParams(jobUIDOrName, targetLocale string, limit, offset uint32) (srv.ListParams, error) { | ||
| rlog.Debugf("resolving list params") | ||
|
|
||
| cnf, err := rootcmd.Config() | ||
| if err != nil { | ||
| return srv.ListParams{}, clierror.UIError{ | ||
| Operation: "config", | ||
| Err: err, | ||
| Description: "failed to read config", | ||
| } | ||
| } | ||
|
|
||
| return srv.ListParams{ | ||
| ProjectID: cnf.ProjectID, | ||
| JobUIDOrName: jobUIDOrName, | ||
| TargetLocaleID: targetLocale, | ||
| Limit: limit, | ||
| Offset: offset, | ||
| }, nil | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| package list | ||
|
|
||
| import ( | ||
| "os" | ||
| "path/filepath" | ||
| "testing" | ||
|
|
||
| rootcmd "github.com/Smartling/smartling-cli/cmd" | ||
| ) | ||
|
|
||
| func TestMain(m *testing.M) { | ||
| rootcmd.ConfigureLogger() | ||
| os.Exit(m.Run()) | ||
| } | ||
|
|
||
| func writeConfig(t *testing.T, content string) string { | ||
| t.Helper() | ||
| path := filepath.Join(t.TempDir(), "smartling.yml") | ||
| if err := os.WriteFile(path, []byte(content), 0o600); err != nil { | ||
| t.Fatalf("write config: %v", err) | ||
| } | ||
| return path | ||
| } | ||
|
|
||
| func Test_resolveParams(t *testing.T) { | ||
| // Config() always requires these. | ||
| t.Setenv("SMARTLING_USER_ID", "test-user") | ||
| t.Setenv("SMARTLING_SECRET", "test-secret") | ||
|
|
||
| root := rootcmd.NewRootCmd() | ||
| cfgPath := writeConfig(t, "project_id: config-project-id\n") | ||
| if err := root.PersistentFlags().Set("config", cfgPath); err != nil { | ||
| t.Fatalf("set config flag: %v", err) | ||
| } | ||
| t.Cleanup(func() { _ = root.PersistentFlags().Set("config", "") }) | ||
|
|
||
| params, err := resolveParams("aabbccdd1122", "fr-FR", 10, 20) | ||
| if err != nil { | ||
| t.Fatalf("resolveParams() error = %v", err) | ||
| } | ||
| if params.ProjectID != "config-project-id" { | ||
| t.Errorf("ProjectID = %q, want config-project-id", params.ProjectID) | ||
| } | ||
| if params.JobUIDOrName != "aabbccdd1122" { | ||
| t.Errorf("JobUIDOrName = %q, want aabbccdd1122", params.JobUIDOrName) | ||
| } | ||
| if params.TargetLocaleID != "fr-FR" { | ||
| t.Errorf("TargetLocaleID = %q, want fr-FR", params.TargetLocaleID) | ||
| } | ||
| if params.Limit != 10 || params.Offset != 20 { | ||
| t.Errorf("Limit/Offset = %d/%d, want 10/20", params.Limit, params.Offset) | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.