Skip to content

Commit

Permalink
Merge pull request #130 from transifex/devel
Browse files Browse the repository at this point in the history
version 1.5.0
  • Loading branch information
igavriil authored Nov 17, 2022
2 parents b87dea7 + c4134fc commit 3232fff
Show file tree
Hide file tree
Showing 12 changed files with 826 additions and 24 deletions.
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@
## Installation

### Installing with a script (Linux/Mac)
You can install the Transifex CLI by executing:
You can install the latest Transifex CLI by executing:

```
curl -o- https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash
```

Or you can isntall a specific version if you need by executing:

```
curl -o- https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash -s -- yourVersion
```


This script will:
* Try to find the correct version for your system.
* Download & extract the CLI to the current folder.
Expand Down Expand Up @@ -540,6 +547,17 @@ fall back to taking the filesystem timestamp into account.
`https://www.transifex.com/myorganization/myproject/new_feature--myresource`
resource.
> Note: Starting from version 1.5.0 resources created using the `--branch` flag,
will have an enhanced functionality in transifex and will be able to automatically
be merged into their bases. Resources created using the `--branch` prior to this
version, need to be pushed again in order for the new functionality to be available..
```sh
→ tx push --branch 'new_feature' --base '' myproject.myresource
```
- `--base`: Define the base branch when pushing a branch.
- `--skip`: Normally, if an upload fails, the client will abort. This may not
be desirable if most uploads are expected to succeed. For example, the reason
of the failed upload may be a syntax error in _one_ of the language files. If
Expand Down Expand Up @@ -774,7 +792,16 @@ tx delete project_slug.\*
If you supply an empty string as the branch (`--branch ''`), then the client
will attempt to figure out the currently active branch in the local git repository.
### Merging Resource
The tx merge command lets you merge a branch resource with its base resource (applies only to resources created with the `--branch` flag)
To merge a resource to its base resource, use the following command:
```
tx merge --branch branch_name project_slug.resource_slug
```
**Other flags:**
- `--conflict-resolution`: Set the conflict resolution strategy. Acceptable options are `USE_HEAD` (changes in the HEAD resource will be used) and `USE_BASE` (changes in the BASE resource will be used)
- `--force`: In case you want to proceed with the merge even if the source strings are diverged, use the `-f/--force` flag.
### Getting the local status of the project
The status command displays the existing configuration in a human readable format. It lists all resources that have been initialized under the local repo/directory and all their associated translation files:
Expand Down
104 changes: 104 additions & 0 deletions cmd/tx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,103 @@ func Main() {
return nil
},
},
{
Name: "merge",
Usage: "tx merge [options] [resource_id]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "branch",
Usage: "Merge specific branch (omit " +
"if it can be determined)",
Value: "",
},
&cli.StringFlag{
Name: "conflict-resolution",
Usage: "Conflict resolution to use for unresolved conflicts",
Value: "USE_BASE",
},
&cli.BoolFlag{
Name: "force",
Usage: "Force merge even if sources are diverged",
Aliases: []string{"f"},
Value: false,
},
&cli.BoolFlag{
Name: "skip",
Usage: "Whether to skip on errors",
},
&cli.BoolFlag{
Name: "silent",
Usage: "Whether to reduce verbosity of the output",
},
},
Action: func(c *cli.Context) error {
if c.Args().Len() != 1 {
return cli.Exit(errorColor("Please provide one resource"), 1)
}

resourceId := c.Args().First()
cfg, err := config.LoadFromPaths(
c.String("root-config"),
c.String("config"),
)
if err != nil {
return cli.Exit(
errorColor(
"Error loading configuration: %s",
err,
),
1,
)
}
hostname, token, err := txlib.GetHostAndToken(
&cfg, c.String("hostname"), c.String("token"),
)
if err != nil {
return cli.Exit(
errorColor(
"Error getting API token: %s",
err,
),
1,
)
}

client, err := txlib.GetClient(c.String("cacert"))
if err != nil {
return cli.Exit(
errorColor(
"Error getting HTTP client configuration: %s",
err,
),
1,
)
}

api := jsonapi.Connection{
Host: hostname,
Token: token,
Client: client,
Headers: map[string]string{
"Integration": "txclient",
},
}

args := txlib.MergeCommandArguments{
ResourceId: resourceId,
Branch: c.String("branch"),
ConflictResolution: c.String("conflict-resolution"),
Force: c.Bool("force"),
Skip: c.Bool("skip"),
Silent: c.Bool("silent"),
}
err = txlib.MergeCommand(&cfg, api, args)
if err != nil {
return cli.Exit(err, 1)
}
return nil
},
},
{
Name: "push",
Usage: "tx push [options] [resource_id...]",
Expand Down Expand Up @@ -146,6 +243,12 @@ func Main() {
"determined)",
Value: "-1",
},
&cli.StringFlag{
Name: "base",
Usage: "Push current branch with a specific base branch. " +
"If omitted the main resource will be used as base",
Value: "-1",
},
&cli.IntFlag{
Name: "workers",
Usage: "How many parallel workers to use",
Expand Down Expand Up @@ -227,6 +330,7 @@ func Main() {
ResourceIds: resourceIds,
UseGitTimestamps: c.Bool("use-git-timestamps"),
Branch: c.String("branch"),
Base: c.String("base"),
All: c.Bool("all"),
Workers: c.Int("workers"),
Silent: c.Bool("silent"),
Expand Down
12 changes: 10 additions & 2 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,16 @@
exit 1
fi

# Try to download the latest version from github releases
URL="https://github.com/transifex/cli/releases/latest/download/tx-$OS-$ARCH.tar.gz"
DEFAULT_TX_VERSION=latest
TX_VERSION="${1:-$DEFAULT_TX_VERSION}"
# Try to download the TX version from github releases
# https://github.com/transifex/cli/releases/download/v1.4.0/tx-darwin-arm64.tar.gz

if [ $TX_VERSION == "latest" ]; then
URL="https://github.com/transifex/cli/releases/latest/download/tx-$OS-$ARCH.tar.gz"
else
URL="https://github.com/transifex/cli/releases/download/$TX_VERSION/tx-$OS-$ARCH.tar.gz"
fi

echo -e "** Installing CLI from $URL\n"
if tar --version | grep -q 'gnu'
Expand Down
3 changes: 2 additions & 1 deletion internal/txlib/config/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@ func nameToSlugsForMigrate(in string) (string, string, string, error) {

/*
Name Return the name of a resource as it appears in the configuration file. The
format is the same as the ID of the resource in APIv3 */
format is the same as the ID of the resource in APIv3
*/
func (localCfg *Resource) Name() string {
var result string
if localCfg.OrganizationSlug != "" {
Expand Down
130 changes: 130 additions & 0 deletions internal/txlib/merge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package txlib

import (
"errors"
"fmt"
"strings"
"time"

"github.com/transifex/cli/internal/txlib/config"
"github.com/transifex/cli/pkg/jsonapi"
"github.com/transifex/cli/pkg/txapi"
"github.com/transifex/cli/pkg/worker_pool"
)

type MergeCommandArguments struct {
ResourceId string
Branch string
ConflictResolution string
Force bool
Skip bool
Silent bool
}

func MergeCommand(
cfg *config.Config,
api jsonapi.Connection,
args MergeCommandArguments,
) error {
args.Branch = figureOutBranch(args.Branch)

cfgResources, err := figureOutResources([]string{args.ResourceId}, cfg)
if err != nil {
return err
}

applyBranchToResources(cfgResources, args.Branch)

cfgResource := cfgResources[0]

err = mergeResource(&api, cfgResource, args)

return err
}

func mergeResource(
api *jsonapi.Connection, cfgResource *config.Resource, args MergeCommandArguments,
) error {
isValidPolicy := isValidResolutionPolicy(args.ConflictResolution)
if !isValidPolicy {
return fmt.Errorf("invalid resolution policy %s", args.ConflictResolution)
}

resourceId := fmt.Sprintf(
"o:%s:p:%s:r:%s",
cfgResource.OrganizationSlug,
cfgResource.ProjectSlug,
cfgResource.ResourceSlug,
)

// Get Resource from Server
resource, err := txapi.GetResourceById(api, resourceId)
if err != nil {
return fmt.Errorf("error getting resource '%s - %s - %s'",
cfgResource.OrganizationSlug,
cfgResource.ProjectSlug,
cfgResource.ResourceSlug)
}

if resource == nil {
return fmt.Errorf("resource not found '%s - %s - %s'",
cfgResource.OrganizationSlug,
cfgResource.ProjectSlug,
cfgResource.ResourceSlug)
}

var merge *jsonapi.Resource
merge, err = txapi.CreateAsyncResourceMerge(api, resource, args.ConflictResolution, args.Force)
if err != nil {
return err
}

pool := worker_pool.New(1, 1, args.Silent)
pool.Add(&MergeResourcePollTask{merge, args})
pool.Start()
<-pool.Wait()
if pool.IsAborted {
return errors.New("Aborted")
}

return nil
}

type MergeResourcePollTask struct {
merge *jsonapi.Resource
args MergeCommandArguments
}

func (task *MergeResourcePollTask) Run(send func(string), abort func()) {
merge := task.merge
args := task.args

parts := strings.Split(merge.Relationships["base"].DataSingular.Id, ":")
sendMessage := func(body string, force bool) {
if args.Silent && !force {
return
}
send(fmt.Sprintf(
"%s.%s - %s", parts[3], parts[5], body,
))
}

err := handleThrottling(
func() error {
return txapi.PollResourceMerge(
merge,
time.Second,
)
},
"Polling merge task status",
func(msg string) { sendMessage(msg, false) },
)
if err != nil {
sendMessage(err.Error(), true)
if !args.Skip {
abort()
}
return
}
sendMessage("Done", false)
}
Loading

0 comments on commit 3232fff

Please sign in to comment.