-
Notifications
You must be signed in to change notification settings - Fork 8
Con 1896 jobs progress #95
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
base: master
Are you sure you want to change the base?
Changes from 9 commits
1400fbc
33a8474
a01e411
9385101
041b889
217a008
a5b6a01
e7d6c3c
df90e7c
8d3c4e3
bf5a566
2b96749
6aa5283
44ec26b
313a0bf
cb48c06
73b064f
6eb57d0
4736a1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package resolve | ||
|
|
||
| import ( | ||
| "github.com/Smartling/smartling-cli/output" | ||
| clierror "github.com/Smartling/smartling-cli/services/helpers/cli_error" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| // OutputParams resolve OutputParams for subcommands | ||
| func OutputParams(cmd *cobra.Command, fileConfigMTFileFormat *string) (output.Params, error) { | ||
| const outputTemplateFlag = "format" | ||
| format, err := cmd.Parent().PersistentFlags().GetString("output") | ||
| if err != nil { | ||
| return output.Params{}, clierror.UIError{ | ||
| Operation: "get output", | ||
| Err: err, | ||
| Description: "unable to get output param", | ||
| } | ||
| } | ||
| template := FallbackString(cmd.Flags().Lookup(outputTemplateFlag), StringParam{ | ||
| FlagName: outputTemplateFlag, | ||
| Config: fileConfigMTFileFormat, | ||
| }) | ||
|
|
||
| mode, err := cmd.Parent().PersistentFlags().GetString("output-mode") | ||
| if err != nil { | ||
| return output.Params{}, clierror.UIError{ | ||
| Operation: "get output mode", | ||
| Err: err, | ||
| Description: "unable to get output mode param", | ||
| } | ||
| } | ||
| return output.Params{ | ||
| Mode: mode, | ||
| Format: format, | ||
| Template: template, | ||
| }, nil | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| package jobs | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "slices" | ||
| "strings" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const ( | ||
| outputFormatFlag = "output" | ||
| ) | ||
|
|
||
| var ( | ||
| outputFormat string | ||
| allowedOutputs = []string{ | ||
| "json", | ||
| "simple", | ||
| } | ||
| joinedAllowedOutputs = strings.Join(allowedOutputs, ", ") | ||
| ) | ||
|
|
||
| // NewJobsCmd returns new jobs command | ||
| func NewJobsCmd() *cobra.Command { | ||
| jobsCmd := &cobra.Command{ | ||
| Use: "jobs", | ||
| Short: "Manage translation jobs and monitor their progress.", | ||
| Long: `Translation jobs are the fundamental unit of work in Smartling TMS that organize | ||
| content for translation and track it through the translation workflow. | ||
|
|
||
| The jobs command group provides tools to interact with translation jobs, including | ||
| monitoring translation progress, viewing job details, and managing job workflows. | ||
|
|
||
| Each job contains one or more files targeted for translation into specific locales, | ||
| with defined due dates and workflow steps. Jobs help coordinate translation work between | ||
| content owners, project managers, and translators. | ||
|
|
||
| Available options: | ||
| --output string Output format: ` + joinedAllowedOutputs + ` (default "simple") | ||
| - simple: Human-readable format optimized for terminal display | ||
| - json: Raw API response for programmatic processing and automation`, | ||
| Example: ` | ||
| # View job progress in human-readable format | ||
|
|
||
| smartling-cli jobs progress "Website Q1 2026" | ||
|
|
||
| # Get detailed progress data for automation | ||
|
|
||
| smartling-cli jobs progress aabbccdd --output json | ||
|
|
||
| `, | ||
| PreRunE: func(cmd *cobra.Command, args []string) error { | ||
| if !slices.Contains(allowedOutputs, outputFormat) { | ||
| return fmt.Errorf("invalid output: %s (allowed: %s)", outputFormat, joinedAllowedOutputs) | ||
| } | ||
| return nil | ||
| }, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| if len(args) == 0 && cmd.Flags().NFlag() == 0 { | ||
| return cmd.Help() | ||
| } | ||
| return nil | ||
| }, | ||
| } | ||
|
|
||
| jobsCmd.PersistentFlags().StringVar(&outputFormat, outputFormatFlag, "simple", "Output format: "+joinedAllowedOutputs) | ||
|
|
||
| return jobsCmd | ||
| } |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,136 @@ | ||||
| package progress | ||||
|
|
||||
| import ( | ||||
| "errors" | ||||
| "fmt" | ||||
|
|
||||
| rootcmd "github.com/Smartling/smartling-cli/cmd" | ||||
| "github.com/Smartling/smartling-cli/cmd/helpers/resolve" | ||||
| jobscmd "github.com/Smartling/smartling-cli/cmd/jobs" | ||||
| "github.com/Smartling/smartling-cli/output" | ||||
| clierror "github.com/Smartling/smartling-cli/services/helpers/cli_error" | ||||
| "github.com/Smartling/smartling-cli/services/helpers/help" | ||||
| srv "github.com/Smartling/smartling-cli/services/jobs" | ||||
|
|
||||
| "github.com/spf13/cobra" | ||||
| ) | ||||
|
|
||||
| // NewProgressCmd returns new progress command | ||||
| func NewProgressCmd(initializer jobscmd.SrvInitializer) *cobra.Command { | ||||
| progressCmd := &cobra.Command{ | ||||
| Use: "progress <translationJobUid|translationJobName>", | ||||
| Short: "Track translation progress for a specific job.", | ||||
| Long: `smartling-cli jobs progress <translationJobUid|translationJobName> [--output json] | ||||
|
|
||||
| Retrieves real-time translation progress metrics for a specific translation job. | ||||
| This command is essential for monitoring active translations, estimating completion times, | ||||
| and tracking workflow progress across multiple locales. | ||||
|
|
||||
| Progress information includes total word counts, completion percentages, and detailed | ||||
| per-locale breakdowns showing how content moves through each translation workflow step | ||||
| (awaiting authorization, in translation, completed, etc.). | ||||
|
|
||||
| The command accepts either: | ||||
| • Translation Job UID: 12-character alphanumeric identifier (e.g., aabbccdd1122) | ||||
| • Translation Job Name: Human-readable name assigned when creating the job | ||||
|
|
||||
| If multiple jobs share the same name, the most recent active job (not Canceled or Closed) | ||||
| will be selected. | ||||
|
|
||||
| Output Formats: | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @az-smartling I have updated the documentation for two new commands. Please review the new texts, but I want to draw your attention to these
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will be good to standardize output related variable for all commands. And move them to root command.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My original comment was about two predefined output styles\templates:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For some commands we have
We should discuss this. |
||||
|
|
||||
| --output simple (default) | ||||
| Displays key progress metrics in human-readable format: | ||||
| - Total word count across all locales | ||||
| - Overall completion percentage | ||||
| Best for: Quick status checks, manual monitoring, terminal viewing | ||||
|
|
||||
| --output json | ||||
| Returns the complete API response as JSON, including: | ||||
| - Per-locale progress breakdowns | ||||
| - Workflow step details (authorized, awaiting, completed, etc.) | ||||
| - String and word counts at each workflow stage | ||||
| - Target locale descriptions | ||||
| Best for: Automation scripts, CI/CD pipelines, custom reporting tools | ||||
|
|
||||
| Use Cases: | ||||
| • Monitor active translation projects to estimate delivery times | ||||
| • Track progress before authorizing next workflow steps | ||||
| • Build automated alerts when translations reach completion thresholds | ||||
| • Generate custom progress reports for stakeholders | ||||
| • Integrate with CI/CD pipelines to gate deployments on translation completion | ||||
|
|
||||
| Project Configuration: | ||||
| Project ID must be configured in smartling.yml or specified via --project flag. | ||||
| Account ID can be configured in smartling.yml or specified via --account flag. | ||||
|
|
||||
| Authentication is required via user_id and secret in smartling.yml or environment variables. | ||||
|
|
||||
| Available options:` + help.AuthenticationOptions, | ||||
| Example: ` | ||||
| # Check progress using job name | ||||
|
|
||||
| smartling-cli jobs progress "Website Q1 2026" | ||||
|
|
||||
| # Check progress using job UID | ||||
|
|
||||
| smartling-cli jobs progress aabbccdd1122 | ||||
|
|
||||
| # Get detailed JSON output for automation | ||||
|
|
||||
| smartling-cli jobs progress "Mobile App Release" --output json | ||||
|
|
||||
| # Use with specific project | ||||
|
|
||||
| smartling-cli jobs progress aabbccdd1122 --project 9876543210 | ||||
|
|
||||
| # Parse JSON output in scripts (example: check if job is 100% complete) | ||||
|
|
||||
| PROGRESS=$(smartling-cli jobs progress my-job --output json | jq '.percentComplete') | ||||
| if [ "$PROGRESS" -eq 100 ]; then | ||||
| echo "Translation complete!" | ||||
| fi | ||||
|
|
||||
| # Monitor progress for CI/CD gate | ||||
|
|
||||
| smartling-cli jobs progress "Release v2.0" --output json | \ | ||||
| jq -e '.percentComplete >= 95' && echo "Ready for deployment" | ||||
|
|
||||
| `, | ||||
| RunE: func(cmd *cobra.Command, args []string) error { | ||||
| ctx := cmd.Context() | ||||
| if len(args) != 1 { | ||||
| return clierror.UIError{ | ||||
| Operation: "check args", | ||||
| Err: errors.New("wrong argument quantity"), | ||||
| Description: fmt.Sprintf("expected one argument, got: %d", len(args)), | ||||
| } | ||||
| } | ||||
| idOrName := args[0] | ||||
|
|
||||
| cnf, err := rootcmd.Config() | ||||
| if err != nil { | ||||
| return err | ||||
| } | ||||
|
|
||||
| accountUID, err := resolve.FallbackAccount(cmd.Root().PersistentFlags().Lookup("account"), cnf.AccountID) | ||||
| if err != nil { | ||||
| return err | ||||
| } | ||||
|
|
||||
| params := srv.ProgressParams{ | ||||
| AccountUID: accountUID, | ||||
| ProjectUID: cnf.ProjectID, | ||||
| JobIDOrName: idOrName, | ||||
| } | ||||
| format, err := cmd.Parent().PersistentFlags().GetString("output") | ||||
| if err != nil { | ||||
| return err | ||||
| } | ||||
| outputParams := output.Params{Format: format} | ||||
| return run(ctx, initializer, params, outputParams) | ||||
| }, | ||||
| } | ||||
|
|
||||
| return progressCmd | ||||
| } | ||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package progress | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| jobscmd "github.com/Smartling/smartling-cli/cmd/jobs" | ||
| "github.com/Smartling/smartling-cli/output" | ||
| "github.com/Smartling/smartling-cli/output/jobs" | ||
| 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" | ||
| ) | ||
|
|
||
| func run(ctx context.Context, | ||
| initializer jobscmd.SrvInitializer, | ||
| params srv.ProgressParams, | ||
| outputParams output.Params, | ||
| ) error { | ||
| rlog.Debugf("running progress with params: %v", params) | ||
| jobSrv, err := initializer.InitJobSrv() | ||
| if err != nil { | ||
| return clierror.UIError{ | ||
| Operation: "init", | ||
| Err: err, | ||
| Description: "unable to initialize Jobs service", | ||
| } | ||
| } | ||
|
|
||
| progressOutput, err := jobSrv.RunProgress(ctx, params) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if progressOutput.TranslationJobUID == "" { | ||
| rlog.Infof("no jobs found for given translationJobUid or translationJobName: %s", params.JobIDOrName) | ||
| return nil | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the exit code that will be returned in this case? I believe it should be non-zero.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to return error |
||
| } | ||
|
|
||
| outputFormat := jobs.GetOutputFormat(outputParams.Format) | ||
| outputFormat.FormatAndRender(progressOutput) | ||
| return nil | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.