diff --git a/src/main/java/com/crowdin/cli/client/ClientDistribution.java b/src/main/java/com/crowdin/cli/client/ClientDistribution.java new file mode 100644 index 000000000..6e25a2aaf --- /dev/null +++ b/src/main/java/com/crowdin/cli/client/ClientDistribution.java @@ -0,0 +1,18 @@ +package com.crowdin.cli.client; + +import com.crowdin.client.distributions.model.AddDistributionRequest; +import com.crowdin.client.distributions.model.Distribution; +import com.crowdin.client.distributions.model.DistributionRelease; + +import java.util.List; + +public interface ClientDistribution extends Client { + + List listDistribution(); + + Distribution addDistribution(AddDistributionRequest request); + + DistributionRelease release(String hash); + + DistributionRelease getDistributionRelease(String hash); +} diff --git a/src/main/java/com/crowdin/cli/client/Clients.java b/src/main/java/com/crowdin/cli/client/Clients.java index 1ec2f7513..00d32e253 100644 --- a/src/main/java/com/crowdin/cli/client/Clients.java +++ b/src/main/java/com/crowdin/cli/client/Clients.java @@ -39,6 +39,11 @@ public static ClientComment getClientComment(String apiToken, String baseUrl, St return new CrowdinClientComment(client, projectId); } + public static ClientDistribution getClientDistribution(String apiToken, String baseUrl, String projectId) { + com.crowdin.client.Client client = prepareClient(apiToken, baseUrl); + return new CrowdinClientDistribution(client, projectId); + } + public static ClientBundle getClientBundle(String apiToken, String baseUrl, String projectId) { com.crowdin.client.Client client = prepareClient(apiToken, baseUrl); return new CrowdinClientBundle(client, projectId); diff --git a/src/main/java/com/crowdin/cli/client/CrowdinClientDistribution.java b/src/main/java/com/crowdin/cli/client/CrowdinClientDistribution.java new file mode 100644 index 000000000..b9be24b39 --- /dev/null +++ b/src/main/java/com/crowdin/cli/client/CrowdinClientDistribution.java @@ -0,0 +1,46 @@ +package com.crowdin.cli.client; + +import com.crowdin.client.distributions.model.AddDistributionRequest; +import com.crowdin.client.distributions.model.Distribution; +import com.crowdin.client.distributions.model.DistributionRelease; + +import java.util.List; + +public class CrowdinClientDistribution extends CrowdinClientCore implements ClientDistribution { + + private final com.crowdin.client.Client client; + private final String projectId; + + public CrowdinClientDistribution(com.crowdin.client.Client client, String projectId) { + this.client = client; + this.projectId = projectId; + } + + @Override + public List listDistribution() { + return executeRequestFullList((limit, offset) -> this.client.getDistributionsApi() + .listDistributions(Long.valueOf(projectId), limit, offset)); + } + + @Override + public Distribution addDistribution(AddDistributionRequest distributionRequest) { + return executeRequest(() -> this.client.getDistributionsApi() + .addDistribution(Long.valueOf(projectId), distributionRequest) + .getData()); + } + + @Override + public DistributionRelease release(String hash) { + return executeRequest(() -> this.client.getDistributionsApi() + .createDistributionRelease(Long.valueOf(projectId), hash) + .getData()); + } + + @Override + public DistributionRelease getDistributionRelease(String hash) { + return executeRequest(() -> this.client.getDistributionsApi() + .getDistributionRelease(Long.valueOf(projectId), hash) + .getData()); + } + +} diff --git a/src/main/java/com/crowdin/cli/commands/Actions.java b/src/main/java/com/crowdin/cli/commands/Actions.java index ef7d867f3..f88599ea0 100644 --- a/src/main/java/com/crowdin/cli/commands/Actions.java +++ b/src/main/java/com/crowdin/cli/commands/Actions.java @@ -9,6 +9,7 @@ import com.crowdin.cli.properties.PropertiesWithTargets; import com.crowdin.cli.properties.PropertiesWithFiles; import com.crowdin.client.core.model.Priority; +import com.crowdin.client.distributions.model.ExportMode; import com.crowdin.client.glossaries.model.GlossariesFormat; import com.crowdin.client.stringcomments.model.IssueStatus; import com.crowdin.client.translationmemory.model.TranslationMemoryFormat; @@ -88,6 +89,12 @@ NewAction tmDownload( NewAction taskAdd(String title, Integer type, String language, List fileId, Long workflowStep, String description, boolean skipAssignedStrings, boolean skipUntranslatedStrings, List labels); + NewAction distributionList(boolean plainView); + + NewAction distributionAdd(boolean noProgress, boolean plainView, String name, ExportMode exportMode, List files, List bundleIds, String branch, ProjectClient projectClient); + + NewAction distributionRelease(boolean noProgress, boolean plainView, String hash); + NewAction commentList(boolean plainView, boolean isVerbose, String stringId, com.crowdin.client.stringcomments.model.Type type, com.crowdin.client.issues.model.Type issueType, IssueStatus status); NewAction resolve(Long id); diff --git a/src/main/java/com/crowdin/cli/commands/actions/CliActions.java b/src/main/java/com/crowdin/cli/commands/actions/CliActions.java index 2b9c388c6..c1bc933e5 100644 --- a/src/main/java/com/crowdin/cli/commands/actions/CliActions.java +++ b/src/main/java/com/crowdin/cli/commands/actions/CliActions.java @@ -11,6 +11,7 @@ import com.crowdin.cli.properties.PropertiesWithTargets; import com.crowdin.cli.properties.PropertiesWithFiles; import com.crowdin.client.core.model.Priority; +import com.crowdin.client.distributions.model.ExportMode; import com.crowdin.client.glossaries.model.GlossariesFormat; import com.crowdin.client.stringcomments.model.IssueStatus; import com.crowdin.client.translationmemory.model.TranslationMemoryFormat; @@ -172,6 +173,21 @@ public NewAction taskAdd(String title, Integer ty return new TaskAddAction(title, type, language, fileId, workflowStep, description, skipAssignedStrings, skipUntranslatedStrings, labels); } + @Override + public NewAction distributionList(boolean plainView) { + return new DistributionListAction(plainView); + } + + @Override + public NewAction distributionAdd(boolean noProgress, boolean plainView, String name, ExportMode exportMode, List files, List bundleIds, String branch, ProjectClient projectClient) { + return new DistributionAddAction(noProgress, plainView, name, exportMode, files, bundleIds, branch, projectClient); + } + + @Override + public NewAction distributionRelease(boolean noProgress, boolean plainView, String hash) { + return new DistributionReleaseAction(noProgress, plainView, hash); + } + @Override public NewAction commentList(boolean plainView, boolean isVerbose,String stringId, com.crowdin.client.stringcomments.model.Type type, com.crowdin.client.issues.model.Type issueType, diff --git a/src/main/java/com/crowdin/cli/commands/actions/DistributionAddAction.java b/src/main/java/com/crowdin/cli/commands/actions/DistributionAddAction.java new file mode 100644 index 000000000..a3f84615e --- /dev/null +++ b/src/main/java/com/crowdin/cli/commands/actions/DistributionAddAction.java @@ -0,0 +1,98 @@ +package com.crowdin.cli.commands.actions; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.client.CrowdinProjectFull; +import com.crowdin.cli.client.ProjectClient; +import com.crowdin.cli.commands.NewAction; +import com.crowdin.cli.commands.Outputter; +import com.crowdin.cli.commands.functionality.RequestBuilder; +import com.crowdin.cli.properties.ProjectProperties; +import com.crowdin.cli.utils.Utils; +import com.crowdin.cli.utils.console.ConsoleSpinner; +import com.crowdin.client.distributions.model.AddDistributionRequest; +import com.crowdin.client.distributions.model.Distribution; +import com.crowdin.client.distributions.model.ExportMode; +import com.crowdin.client.sourcefiles.model.Branch; +import com.crowdin.client.sourcefiles.model.FileInfo; +import lombok.AllArgsConstructor; + +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE; +import static com.crowdin.cli.utils.console.ExecutionStatus.OK; + +@AllArgsConstructor +class DistributionAddAction implements NewAction { + + private boolean noProgress; + private boolean plainView; + private String name; + private ExportMode exportMode; + private List files; + private List bundleIds; + private String branch; + + private ProjectClient projectClient; + + @Override + public void act(Outputter out, ProjectProperties pb, ClientDistribution client) { + CrowdinProjectFull project = ConsoleSpinner.execute( + out, + "message.spinner.fetching_project_info", "error.collect_project_info", + this.noProgress, + this.plainView, + () -> this.projectClient.downloadFullProject(this.branch) + ); + List fileIds = null; + if (files != null) { + Map projectBranches = project.getBranches().values().stream() + .collect(Collectors.toMap(Branch::getName, Branch::getId)); + List projectFiles = project.getFiles().stream() + .filter(file -> branch == null || file.getBranchId().equals(projectBranches.get(branch))) + .map(FileInfo::getPath) + .collect(Collectors.toList()); + List notExistingFiles = files.stream() + .map(file -> branch == null ? file : Paths.get(branch, file).toString()) + .map(Utils::sepAtStart) + .filter(file -> !projectFiles.contains(file)) + .collect(Collectors.toList()); + if (!notExistingFiles.isEmpty()) { + throw new RuntimeException(notExistingFiles.stream().map(Utils::noSepAtStart) + .map(file -> String.format(RESOURCE_BUNDLE.getString("error.file_not_found"), file)) + .collect(Collectors.joining("\n\u274C "))); + } + files = branch != null ? files.stream().map(file -> Paths.get(branch, file).toString()) + .collect(Collectors.toList()) : files; + files = files.stream().map(Utils::sepAtStart).collect(Collectors.toList()); + fileIds = project + .getFiles() + .stream() + .filter(file -> files.contains(file.getPath())) + .map(FileInfo::getId) + .collect(Collectors.toList()); + } + + Distribution distribution; + AddDistributionRequest addDistributionRequest = RequestBuilder.addDistribution(name, exportMode, fileIds, bundleIds); + Optional.ofNullable(name).ifPresent(addDistributionRequest::setName); + Optional.ofNullable(exportMode).ifPresent(addDistributionRequest::setExportMode); + Optional.ofNullable(fileIds).ifPresent(addDistributionRequest::setFileIds); + Optional.ofNullable(bundleIds).ifPresent(addDistributionRequest::setBundleIds); + + try { + distribution = client.addDistribution(addDistributionRequest); + } catch (Exception e) { + throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.distribution_is_not_added"), addDistributionRequest), e); + } + + if (!plainView) { + out.println(OK.withIcon(String.format(RESOURCE_BUNDLE.getString("message.distribution.added"), distribution.getName()))); + } else { + out.println(String.valueOf(distribution.getName())); + } + } +} diff --git a/src/main/java/com/crowdin/cli/commands/actions/DistributionListAction.java b/src/main/java/com/crowdin/cli/commands/actions/DistributionListAction.java new file mode 100644 index 000000000..4ee83105c --- /dev/null +++ b/src/main/java/com/crowdin/cli/commands/actions/DistributionListAction.java @@ -0,0 +1,44 @@ +package com.crowdin.cli.commands.actions; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.commands.NewAction; +import com.crowdin.cli.commands.Outputter; +import com.crowdin.cli.properties.ProjectProperties; +import com.crowdin.client.distributions.model.Distribution; + +import java.util.List; + +import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE; +import static com.crowdin.cli.utils.console.ExecutionStatus.OK; + +class DistributionListAction implements NewAction { + + private final boolean plainView; + + public DistributionListAction(boolean plainView) { + this.plainView = plainView; + } + + @Override + public void act(Outputter out, ProjectProperties pb, ClientDistribution client) { + List distributions = client.listDistribution(); + + for (Distribution distribution : distributions) { + if (!plainView) { + out.println(String.format(RESOURCE_BUNDLE.getString("message.distribution.list"), distribution.getHash(), + distribution.getName(), + distribution.getExportMode())); + } else { + out.println(distribution.getHash() + " " + distribution.getName()); + } + } + + if (distributions.isEmpty()) { + if (!plainView) { + out.println(OK.withIcon(RESOURCE_BUNDLE.getString("message.distribution.list_empty"))); + } else { + out.println(RESOURCE_BUNDLE.getString("message.distribution.list_empty")); + } + } + } +} diff --git a/src/main/java/com/crowdin/cli/commands/actions/DistributionReleaseAction.java b/src/main/java/com/crowdin/cli/commands/actions/DistributionReleaseAction.java new file mode 100644 index 000000000..989837961 --- /dev/null +++ b/src/main/java/com/crowdin/cli/commands/actions/DistributionReleaseAction.java @@ -0,0 +1,56 @@ +package com.crowdin.cli.commands.actions; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.commands.NewAction; +import com.crowdin.cli.commands.Outputter; +import com.crowdin.cli.properties.ProjectProperties; +import com.crowdin.cli.utils.console.ConsoleSpinner; +import com.crowdin.client.distributions.model.DistributionRelease; +import lombok.AllArgsConstructor; + +import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE; +import static com.crowdin.cli.utils.console.ExecutionStatus.OK; + +@AllArgsConstructor +class DistributionReleaseAction implements NewAction { + + private boolean noProgress; + private boolean plainView; + private String hash; + + @Override + public void act(Outputter out, ProjectProperties pb, ClientDistribution client) { + this.releaseDistribution(out, client); + out.println(OK.withIcon(String.format(RESOURCE_BUNDLE.getString("message.distribution.released"), hash))); + } + + private DistributionRelease releaseDistribution(Outputter out, ClientDistribution client) { + return ConsoleSpinner.execute( + out, + "message.spinner.releasing_distribution", + "error.distribution_is_not_released", + this.noProgress, + false, + () -> { + DistributionRelease release = client.release(hash); + + while (!"success".equalsIgnoreCase(release.getStatus())) { + ConsoleSpinner.update( + String.format(RESOURCE_BUNDLE.getString("message.spinner.releasing_distribution_percents"), + release.getProgress())); + Thread.sleep(1000); + + release = client.getDistributionRelease(hash); + + if ("failed".equalsIgnoreCase(release.getStatus())) { + throw new RuntimeException(RESOURCE_BUNDLE.getString("message.spinner.build_has_failed")); + } + } + + ConsoleSpinner.update(String.format(RESOURCE_BUNDLE.getString("message.spinner.releasing_distribution_percents"), 100)); + + return release; + } + ); + } +} diff --git a/src/main/java/com/crowdin/cli/commands/functionality/RequestBuilder.java b/src/main/java/com/crowdin/cli/commands/functionality/RequestBuilder.java index 2902a7dd4..2c7a19544 100644 --- a/src/main/java/com/crowdin/cli/commands/functionality/RequestBuilder.java +++ b/src/main/java/com/crowdin/cli/commands/functionality/RequestBuilder.java @@ -3,6 +3,8 @@ import com.crowdin.client.core.model.PatchOperation; import com.crowdin.client.core.model.PatchRequest; import com.crowdin.client.core.model.Priority; +import com.crowdin.client.distributions.model.AddDistributionRequest; +import com.crowdin.client.distributions.model.ExportMode; import com.crowdin.client.glossaries.model.AddGlossaryRequest; import com.crowdin.client.glossaries.model.ExportGlossaryRequest; import com.crowdin.client.glossaries.model.GlossariesFormat; @@ -57,6 +59,15 @@ public static AddStringCommentRequest addComment(String text, String type, Strin return request; } + public static AddDistributionRequest addDistribution(String name, ExportMode exportMode, List fileIds, List bundleIds) { + AddDistributionRequest request = new AddDistributionRequest(); + Optional.ofNullable(name).ifPresent(request::setName); + Optional.ofNullable(exportMode).ifPresent(request::setExportMode); + Optional.ofNullable(fileIds).ifPresent(request::setFileIds); + Optional.ofNullable(bundleIds).ifPresent(request::setBundleIds); + return request; + } + public static CrowdinTaskCreateFormRequest addCrowdinTask(String title, Integer type, String languageId, List fileId, String description, boolean skipAssignedStrings, boolean skipUntranslatedStrings, List labelIds) { CrowdinTaskCreateFormRequest request = new CrowdinTaskCreateFormRequest(); request.setTitle(title); diff --git a/src/main/java/com/crowdin/cli/commands/picocli/ActCommandDistribution.java b/src/main/java/com/crowdin/cli/commands/picocli/ActCommandDistribution.java new file mode 100644 index 000000000..0348392c5 --- /dev/null +++ b/src/main/java/com/crowdin/cli/commands/picocli/ActCommandDistribution.java @@ -0,0 +1,33 @@ +package com.crowdin.cli.commands.picocli; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.client.Clients; +import com.crowdin.cli.client.ProjectClient; +import com.crowdin.cli.commands.Outputter; +import com.crowdin.cli.properties.ProjectParams; +import com.crowdin.cli.properties.ProjectProperties; +import com.crowdin.cli.properties.PropertiesBuilders; +import picocli.CommandLine; + +public abstract class ActCommandDistribution extends GenericActCommand { + + @CommandLine.Mixin + private ConfigurationFilesProperties properties; + + @CommandLine.ArgGroup(exclusive = false, headingKey = "params.heading") + private ProjectParams params; + + @Override + protected ProjectProperties getProperties(PropertiesBuilders propertiesBuilders, Outputter out) { + return propertiesBuilders.buildProjectProperties(out, properties.getConfigFile(), properties.getIdentityFile(), params); + } + + @Override + protected ClientDistribution getClient(ProjectProperties properties) { + return Clients.getClientDistribution(properties.getApiToken(), properties.getBaseUrl(), properties.getProjectId()); + } + + protected ProjectClient getProjectClient(ProjectProperties properties) { + return Clients.getProjectClient(properties.getApiToken(), properties.getBaseUrl(), Long.parseLong(properties.getProjectId())); + } +} diff --git a/src/main/java/com/crowdin/cli/commands/picocli/CommandNames.java b/src/main/java/com/crowdin/cli/commands/picocli/CommandNames.java index 8d2184a9a..27cbf373c 100644 --- a/src/main/java/com/crowdin/cli/commands/picocli/CommandNames.java +++ b/src/main/java/com/crowdin/cli/commands/picocli/CommandNames.java @@ -64,4 +64,9 @@ public final class CommandNames { public static final String COMMENT = "comment"; public static final String COMMENT_LIST = "list"; public static final String COMMENT_RESOLVE = "resolve"; + + public static final String DISTRIBUTION = "distribution"; + public static final String DISTRIBUTION_ADD = "add"; + public static final String DISTRIBUTION_LIST = "list"; + public static final String DISTRIBUTION_RELEASE = "release"; } diff --git a/src/main/java/com/crowdin/cli/commands/picocli/DistributionAddSubcommand.java b/src/main/java/com/crowdin/cli/commands/picocli/DistributionAddSubcommand.java new file mode 100644 index 000000000..198a1c988 --- /dev/null +++ b/src/main/java/com/crowdin/cli/commands/picocli/DistributionAddSubcommand.java @@ -0,0 +1,77 @@ +package com.crowdin.cli.commands.picocli; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.client.ProjectClient; +import com.crowdin.cli.commands.Actions; +import com.crowdin.cli.commands.NewAction; +import com.crowdin.cli.commands.Outputter; +import com.crowdin.cli.properties.ProjectProperties; +import com.crowdin.client.distributions.model.ExportMode; +import org.apache.logging.log4j.util.Strings; +import picocli.CommandLine; + +import java.util.ArrayList; +import java.util.List; + +import static com.crowdin.client.distributions.model.ExportMode.BUNDLE; +import static com.crowdin.client.distributions.model.ExportMode.DEFAULT; + +@CommandLine.Command( + name = CommandNames.DISTRIBUTION_ADD, + sortOptions = false +) +class DistributionAddSubcommand extends ActCommandDistribution { + + @CommandLine.Parameters(descriptionKey = "crowdin.distribution.add.name") + protected String name; + + @CommandLine.Option(names = {"--export-mode"}, paramLabel = "...", descriptionKey = "crowdin.distribution.add.export-mode", defaultValue = "default", order = -2) + protected ExportMode exportMode; + + @CommandLine.Option(names = {"--file"}, paramLabel = "...", descriptionKey = "crowdin.distribution.add.file", order = -2) + protected List files; + + @CommandLine.Option(names = {"--bundle-id"}, paramLabel = "...", descriptionKey = "crowdin.distribution.add.bundle-id", order = -2) + protected List bundleIds; + + @CommandLine.Option(names = {"--branch"}, paramLabel = "...", descriptionKey = "branch", order = -2) + protected String branch; + + @CommandLine.Option(names = {"--plain"}, descriptionKey = "crowdin.list.usage.plain") + protected boolean plainView; + + @Override + protected NewAction getAction(Actions actions) { + Outputter out = new PicocliOutputter(System.out, isAnsi()); + ProjectClient projectClient = this.getProjectClient(this.getProperties(propertiesBuilders, out)); + + return actions.distributionAdd(noProgress, plainView, name, exportMode, files, bundleIds, branch, projectClient); + } + + @Override + protected List checkOptions() { + List errors = new ArrayList<>(); + + if (Strings.isEmpty(name)) { + errors.add(RESOURCE_BUNDLE.getString("error.distribution.empty_name")); + } + + if (exportMode == DEFAULT && files == null) { + errors.add(RESOURCE_BUNDLE.getString("error.distribution.empty_file")); + } + + if (exportMode == BUNDLE && bundleIds == null) { + errors.add(RESOURCE_BUNDLE.getString("error.distribution.empty_bundle_ids")); + } + + if (exportMode == BUNDLE && files != null) { + errors.add(RESOURCE_BUNDLE.getString("error.distribution.incorrect_file_command_usage")); + } + + if (exportMode == DEFAULT && bundleIds != null) { + errors.add(RESOURCE_BUNDLE.getString("error.distribution.incorrect_bundle_id_command_usage")); + } + + return errors; + } +} diff --git a/src/main/java/com/crowdin/cli/commands/picocli/DistributionListSubcommand.java b/src/main/java/com/crowdin/cli/commands/picocli/DistributionListSubcommand.java new file mode 100644 index 000000000..98578c95e --- /dev/null +++ b/src/main/java/com/crowdin/cli/commands/picocli/DistributionListSubcommand.java @@ -0,0 +1,27 @@ +package com.crowdin.cli.commands.picocli; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.commands.Actions; +import com.crowdin.cli.commands.NewAction; +import com.crowdin.cli.properties.ProjectProperties; +import picocli.CommandLine; + +@CommandLine.Command( + sortOptions = false, + name = CommandNames.DISTRIBUTION_LIST +) +class DistributionListSubcommand extends ActCommandDistribution { + + @CommandLine.Option(names = {"--plain"}, descriptionKey = "crowdin.list.usage.plain") + protected boolean plainView; + + @Override + protected NewAction getAction(Actions actions) { + return actions.distributionList(this.plainView); + } + + @Override + protected boolean isAnsi() { + return super.isAnsi() && !plainView; + } +} diff --git a/src/main/java/com/crowdin/cli/commands/picocli/DistributionReleaseSubcommand.java b/src/main/java/com/crowdin/cli/commands/picocli/DistributionReleaseSubcommand.java new file mode 100644 index 000000000..c14cc1b4b --- /dev/null +++ b/src/main/java/com/crowdin/cli/commands/picocli/DistributionReleaseSubcommand.java @@ -0,0 +1,25 @@ +package com.crowdin.cli.commands.picocli; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.commands.Actions; +import com.crowdin.cli.commands.NewAction; +import com.crowdin.cli.properties.ProjectProperties; +import picocli.CommandLine; + +@CommandLine.Command( + name = CommandNames.DISTRIBUTION_RELEASE, + sortOptions = false +) +class DistributionReleaseSubcommand extends ActCommandDistribution { + + @CommandLine.Parameters(descriptionKey = "crowdin.distribution.release.hash") + protected String hash; + + @CommandLine.Option(names = {"--plain"}, descriptionKey = "crowdin.list.usage.plain") + protected boolean plainView; + + @Override + protected NewAction getAction(Actions actions) { + return actions.distributionRelease(noProgress, plainView, hash); + } +} diff --git a/src/main/java/com/crowdin/cli/commands/picocli/DistributionSubcommand.java b/src/main/java/com/crowdin/cli/commands/picocli/DistributionSubcommand.java new file mode 100644 index 000000000..ed8178e0d --- /dev/null +++ b/src/main/java/com/crowdin/cli/commands/picocli/DistributionSubcommand.java @@ -0,0 +1,19 @@ +package com.crowdin.cli.commands.picocli; + +import picocli.CommandLine; + +@CommandLine.Command( + name = CommandNames.DISTRIBUTION, + subcommands = { + DistributionAddSubcommand.class, + DistributionListSubcommand.class, + DistributionReleaseSubcommand.class + } +) +class DistributionSubcommand extends HelpCommand { + + @Override + protected CommandLine getCommand(CommandLine rootCommand) { + return rootCommand.getSubcommands().get(CommandNames.DISTRIBUTION); + } +} diff --git a/src/main/java/com/crowdin/cli/commands/picocli/RootCommand.java b/src/main/java/com/crowdin/cli/commands/picocli/RootCommand.java index 4fb52de37..3f2b5399e 100644 --- a/src/main/java/com/crowdin/cli/commands/picocli/RootCommand.java +++ b/src/main/java/com/crowdin/cli/commands/picocli/RootCommand.java @@ -19,7 +19,8 @@ CheckVersionSubcommand.class, PreTranslateSubcommand.class, BranchSubcommand.class, - CommentSubcommand.class + CommentSubcommand.class, + DistributionSubcommand.class }) class RootCommand extends HelpCommand { @Override diff --git a/src/main/resources/messages/messages.properties b/src/main/resources/messages/messages.properties index ab5752ed0..df26cf0e7 100755 --- a/src/main/resources/messages/messages.properties +++ b/src/main/resources/messages/messages.properties @@ -329,6 +329,27 @@ crowdin.pre-translate.duplicate-translations=Adds translations even if the same crowdin.pre-translate.translate-untranslated-only=Applies pre-translation for untranslated strings only crowdin.pre-translate.translate-with-perfect-match-only=Applies pre-translation only for the strings with perfect match +# CROWDIN DISTRIBUTION COMMAND +crowdin.distribution.usage.description=Manage distributions in a Crowdin Project +crowdin.distribution.usage.customSynopsis=@|fg(green) crowdin distribution|@ [SUBCOMMAND] [CONFIG OPTIONS] [OPTIONS] + +# CROWDIN DISTRIBUTION LIST COMMAND +crowdin.distribution.list.usage.description=List distributions in a project +crowdin.distribution.list.usage.customSynopsis=@|fg(green) crowdin distribution list|@ [CONFIG OPTIONS] [OPTIONS] + +# CROWDIN DISTRIBUTION ADD COMMAND +crowdin.distribution.add.usage.description=Add a new distribution +crowdin.distribution.add.usage.customSynopsis=@|fg(green) crowdin distribution add|@ [CONFIG OPTIONS] [OPTIONS] +crowdin.distribution.add.name=Distribution name +crowdin.distribution.add.export-mode=Distribution export mode. Supported modes: default, bundle +crowdin.distribution.add.file=File path in the Crowdin project. Can be specified multiple times +crowdin.distribution.add.bundle-id=Bundle ID. Can be specified multiple times. Requires 'export-mode' to be set to 'bundle' + +# CROWDIN DISTRIBUTION RELEASE COMMAND +crowdin.distribution.release.usage.description=Release a distribution +crowdin.distribution.release.usage.customSynopsis=@|fg(green) crowdin distribution release|@ [CONFIG OPTIONS] [OPTIONS] +crowdin.distribution.release.hash=Distribution hash + error.collect_project_info=Failed to collect project info. Please contact our support team for help error.no_sources=No sources found for '%s' pattern. Check the source paths in your configuration file error.only_enterprise=Operation is available only for Crowdin Enterprise @@ -441,6 +462,13 @@ error.comment_language_not_specified=The '--language' option is required error.comment_type_not_specified_or_incorrect=The '--type' option is missing or incorrect. Supported values: comment, issue error.comment_should_not_have_issue_type=Comment should not have the --issue-type parameter. It can only be used if --type=issue +error.distribution_is_not_added=Distribution was not added +error.distribution_is_not_released=Distribution was not released +error.distribution.empty_file=The '--file' value can not be empty for the 'default' export mode +error.distribution.empty_bundle_ids=The '--bundle-id' value can not be empty for the 'bundle' export mode +error.distribution.incorrect_file_command_usage=The '--file' is used only for the 'default' export mode +error.distribution.incorrect_bundle_id_command_usage=The '--bundle-id' is used only for the 'bundle' export mode + error.pre_translate.engine_id=Machine Translation should be used with the '--engine-id' parameter error.pre_translate.duplicate_translations='--duplicate-translations' only works with the TM pre-translation method error.pre_translate.translate_untranslated_only='--translate-untranslated-only' only works with the TM pre-translation method @@ -493,6 +521,8 @@ error.init.path_not_exist=Path '%s' doesn't exist error.spinner.pre_translate=Failed to pre-translate the project. Please contact our support team for help error.spinner.reviewed_sources=Failed to load reviewed sources. Please contact our support team for help +error.file_not_found=File '%s' not found int the Crowdin project + message.new_version_text=New version of Crowdin CLI is available! %s -> %s message.new_version_text.2=Changelog: @|cyan https://github.com/crowdin/crowdin-cli/releases/latest|@ message.new_version_text.3=Please update for the best experience! @@ -573,6 +603,11 @@ message.task.list.verbose=@|yellow #%d|@ @|bold %s|@ @|green '%s'|@ @|bold %s|@ message.task.list_empty=No tasks found message.task.added=@|green,bold Task '%s'|@ @|green added successfully|@ +message.distribution.list=@|yellow %s|@ @|bold %s|@ +message.distribution.list_empty=No distributions found +message.distribution.added=@|green,bold Distribution '%s'|@ @|green added successfully|@ +message.distribution.released=@|green,bold Distribution '%s'|@ @|green released successfully|@ + message.bundle.download_success=@|yellow #%d|@ @|green,bold '%s'|@ @|green downloaded successfully|@ message.bundle.list=@|yellow #%d|@ @|bold '%s'|@ @|green %s|@ @|red %s|@ message.bundle.list_empty=No bundles found @@ -621,6 +656,8 @@ message.spinner.building_bundle=Building bundle message.spinner.building_bundle_percents=Building bundle @|bold (%d%%)|@ message.spinner.building_tm=Building translation memory message.spinner.building_tm_percents=Building translation memory @|bold (%d%%)|@ +message.spinner.releasing_distribution=Releasing distribution +message.spinner.releasing_distribution_percents=Releasing distribution @|bold (%d%%)|@ message.spinner.validation_success=Validation was successful message.spinner.pre_translate=Pre-translation is running... message.spinner.pre_translate_percents=Pre-translation is completed by @|bold (%d%%)|@ diff --git a/src/test/java/com/crowdin/cli/client/CrowdinClientDistributionTest.java b/src/test/java/com/crowdin/cli/client/CrowdinClientDistributionTest.java new file mode 100644 index 000000000..1c790278b --- /dev/null +++ b/src/test/java/com/crowdin/cli/client/CrowdinClientDistributionTest.java @@ -0,0 +1,70 @@ +package com.crowdin.cli.client; + +import com.crowdin.client.core.http.HttpClient; +import com.crowdin.client.core.http.impl.json.JacksonJsonTransformer; +import com.crowdin.client.core.model.ClientConfig; +import com.crowdin.client.core.model.Credentials; +import com.crowdin.client.distributions.model.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +public class CrowdinClientDistributionTest { + + private HttpClient httpClientMock; + private ClientDistribution client; + + private static final long projectId = 42; + private static final String preUrl = "https://testme.crowdin.com"; + private static final String url = "https://testme.crowdin.com/api/v2"; + + private static final String listDistributionUrl = String.format("%s/projects/%s/distributions", url, projectId); + private static final String addDistributionUrl = String.format("%s/projects/%s/distributions", url, projectId); + + + @BeforeEach + public void init() { + Credentials creds = new Credentials("VeryBigToken", "TestingCompany", preUrl); + httpClientMock = mock(HttpClient.class); + ClientConfig clientConfig = ClientConfig.builder() + .jsonTransformer(new JacksonJsonTransformer()) + .httpClient(httpClientMock) + .build(); + com.crowdin.client.Client internalClient = new com.crowdin.client.Client(creds, clientConfig); + client = new CrowdinClientDistribution(internalClient, Long.toString(projectId)); + } + + @Test + public void testListDistribution() { + DistributionResponseList response = new DistributionResponseList() {{ + setData(new ArrayList<>()); + }}; + when(httpClientMock.get(eq(listDistributionUrl), any(), eq(DistributionResponseList.class))) + .thenReturn(response); + + client.listDistribution(); + + verify(httpClientMock).get(eq(listDistributionUrl), any(), eq(DistributionResponseList.class)); + verifyNoMoreInteractions(httpClientMock); + } + + @Test + public void testAddDistribution() { + DistributionResponseObject response = new DistributionResponseObject() {{ + setData(new Distribution()); + }}; + when(httpClientMock.post(eq(addDistributionUrl), any(), any(), eq(DistributionResponseObject.class))) + .thenReturn(response); + + client.addDistribution(new AddDistributionRequest()); + + verify(httpClientMock).post(eq(addDistributionUrl), any(), any(), eq(DistributionResponseObject.class)); + verifyNoMoreInteractions(httpClientMock); + } + +} diff --git a/src/test/java/com/crowdin/cli/client/ProjectBuilder.java b/src/test/java/com/crowdin/cli/client/ProjectBuilder.java index b88cca425..73430581a 100644 --- a/src/test/java/com/crowdin/cli/client/ProjectBuilder.java +++ b/src/test/java/com/crowdin/cli/client/ProjectBuilder.java @@ -84,6 +84,7 @@ public ProjectBuilder addFile(String name, String type, Long id, Long directoryI setExportPattern(exportPattern); }} ); + file.setPath(name); files.add(file); return this; } diff --git a/src/test/java/com/crowdin/cli/commands/actions/CliActionsTest.java b/src/test/java/com/crowdin/cli/commands/actions/CliActionsTest.java index 901c575f8..9ead42a9f 100644 --- a/src/test/java/com/crowdin/cli/commands/actions/CliActionsTest.java +++ b/src/test/java/com/crowdin/cli/commands/actions/CliActionsTest.java @@ -107,6 +107,21 @@ public void testTmDownload() { assertNotNull(actions.tmDownload(null, null, null, null, null, false, null, null)); } + @Test + public void testDistributionAdd() { + assertNotNull(actions.distributionAdd(false, false, null, null, null, null, null, null)); + } + + @Test + public void testDistributionList() { + assertNotNull(actions.distributionList(true)); + } + + @Test + public void testDistributionRelease() { + assertNotNull(actions.distributionRelease(false,true,null)); + } + @Test public void testCheckNewVersion() { assertNotNull(actions.checkNewVersion()); diff --git a/src/test/java/com/crowdin/cli/commands/actions/DistributionAddActionTest.java b/src/test/java/com/crowdin/cli/commands/actions/DistributionAddActionTest.java new file mode 100644 index 000000000..d97021a1c --- /dev/null +++ b/src/test/java/com/crowdin/cli/commands/actions/DistributionAddActionTest.java @@ -0,0 +1,108 @@ +package com.crowdin.cli.commands.actions; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.client.ProjectBuilder; +import com.crowdin.cli.client.ProjectClient; +import com.crowdin.cli.commands.NewAction; +import com.crowdin.cli.commands.Outputter; +import com.crowdin.cli.commands.functionality.RequestBuilder; +import com.crowdin.cli.properties.NewPropertiesWithFilesUtilBuilder; +import com.crowdin.cli.properties.ProjectProperties; +import com.crowdin.cli.properties.PropertiesWithFiles; +import com.crowdin.cli.properties.helper.FileHelperTest; +import com.crowdin.cli.properties.helper.TempProject; +import com.crowdin.cli.utils.Utils; +import com.crowdin.client.distributions.model.AddDistributionRequest; +import com.crowdin.client.distributions.model.Distribution; +import com.crowdin.client.distributions.model.ExportMode; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.params.provider.Arguments.arguments; +import static org.mockito.Mockito.*; + +public class DistributionAddActionTest { + + NewAction action; + + @ParameterizedTest + @MethodSource + public void testDistributionAdd(String name, ExportMode exportMode, List files, List bundleIds, + String branch, Long branchId) { + TempProject project = new TempProject(FileHelperTest.class); + + NewPropertiesWithFilesUtilBuilder pbBuilder = NewPropertiesWithFilesUtilBuilder + .minimalBuiltPropertiesBean("*", Utils.PATH_SEPARATOR + "%original_file_name%-CR-%locale%") + .setBasePath(project.getBasePath()); + PropertiesWithFiles pb = pbBuilder.build(); + + List fileIds = files == null ? null : files.stream().map(f -> project.addFile(f).getId()).collect( + Collectors.toList()); + AddDistributionRequest request = RequestBuilder.addDistribution(name, exportMode, fileIds, bundleIds); + + ClientDistribution client = mock(ClientDistribution.class); + when(client.addDistribution(request)) + .thenReturn(new Distribution() {{ + setName(request.getName()); + setFileIds(request.getFileIds()); + setBundleIds(request.getBundleIds()); + setExportMode(request.getExportMode().toString()); + }}); + + ProjectBuilder projectBuilder = ProjectBuilder.emptyProject(Long.parseLong(pb.getProjectId())); + if (branch != null) { + projectBuilder.addBranches(branchId, branch); + } + Optional.ofNullable(fileIds).ifPresent(ids -> new ArrayList<>(ids).forEach( + f -> projectBuilder.addFile(Utils.sepAtStart(Paths.get(Optional.ofNullable(branch).orElse(""), + files.get(ids.indexOf(f))).toString()), + "gettext", f, null, branchId, + "/%original_file_name%-CR-%locale%"))); + + ProjectClient projectClient = mock(ProjectClient.class); + when(projectClient.downloadFullProject(branch)) + .thenReturn(projectBuilder.build()); + + action = new DistributionAddAction(true, true, name, exportMode, files, bundleIds, branch, projectClient); + action.act(Outputter.getDefault(), pb, client); + verify(client).addDistribution(request); + verifyNoMoreInteractions(client); + } + + public static Stream testDistributionAdd() { + return Stream.of(arguments("My Distribution 1", ExportMode.DEFAULT, Arrays.asList("first.po"), null, + null, null), + arguments("My Distribution 2", ExportMode.BUNDLE, null, Arrays.asList(9), + null, null), + arguments("My Distribution 3", ExportMode.DEFAULT, Arrays.asList("second.po"), null, + "master", 1l)); + } + + @Test + public void testAddDistributionThrows() { + NewPropertiesWithFilesUtilBuilder pbBuilder = NewPropertiesWithFilesUtilBuilder + .minimalBuiltPropertiesBean("*", Utils.PATH_SEPARATOR + "%original_file_name%-CR-%locale%") + .setBasePath(Utils.PATH_SEPARATOR); + PropertiesWithFiles pb = pbBuilder.build(); + ClientDistribution client = mock(ClientDistribution.class); + + AddDistributionRequest request = RequestBuilder.addDistribution(null, null, null, null); + + when(client.addDistribution(request)) + .thenThrow(new RuntimeException("Whoops")); + + action = new DistributionAddAction(true, false, null, null, null, null, null, null); + assertThrows(RuntimeException.class, () -> action.act(Outputter.getDefault(), pb, client)); + + verifyNoMoreInteractions(client); + } + +} diff --git a/src/test/java/com/crowdin/cli/commands/actions/DistributionListActionTest.java b/src/test/java/com/crowdin/cli/commands/actions/DistributionListActionTest.java new file mode 100644 index 000000000..f1dde978f --- /dev/null +++ b/src/test/java/com/crowdin/cli/commands/actions/DistributionListActionTest.java @@ -0,0 +1,87 @@ +package com.crowdin.cli.commands.actions; + +import static org.mockito.Mockito.*; + +import com.crowdin.cli.client.ClientDistribution; +import com.crowdin.cli.commands.NewAction; +import com.crowdin.cli.commands.Outputter; +import com.crowdin.cli.properties.ProjectProperties; +import com.crowdin.cli.properties.PropertiesWithFiles; +import com.crowdin.client.distributions.model.Distribution; +import com.crowdin.client.distributions.model.ExportMode; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class DistributionListActionTest { + + List standardList = Arrays.asList( + new Distribution() {{ + setName("Distribution 1"); + setExportMode(ExportMode.DEFAULT.toString()); + }}, + new Distribution() {{ + setName("Distribution 2"); + setExportMode(ExportMode.BUNDLE.toString()); + + }} + ); + List emptyList = Collections.emptyList(); + + Outputter out = Outputter.getDefault(); + PropertiesWithFiles pb; + + ClientDistribution clientMock = mock(ClientDistribution.class); + NewAction action; + + @Test + public void test_standard() { + when(clientMock.listDistribution()) + .thenReturn(standardList); + + action = new DistributionListAction(false); + action.act(out, pb, clientMock); + + verify(clientMock).listDistribution(); + verifyNoMoreInteractions(clientMock); + } + + @Test + public void test_plainView() { + when(clientMock.listDistribution()) + .thenReturn(standardList); + + action = new DistributionListAction(true); + action.act(out, pb, clientMock); + + verify(clientMock).listDistribution(); + verifyNoMoreInteractions(clientMock); + } + + @Test + public void test_emptyList() { + when(clientMock.listDistribution()) + .thenReturn(emptyList); + + action = new DistributionListAction(false); + action.act(out, pb, clientMock); + + verify(clientMock).listDistribution(); + verifyNoMoreInteractions(clientMock); + } + + @Test + public void test_emptyList_plainView() { + when(clientMock.listDistribution()) + .thenReturn(emptyList); + + action = new DistributionListAction(true); + action.act(out, pb, clientMock); + + verify(clientMock).listDistribution(); + verifyNoMoreInteractions(clientMock); + } +} diff --git a/src/test/java/com/crowdin/cli/commands/picocli/DistributionAddSubcommandTest.java b/src/test/java/com/crowdin/cli/commands/picocli/DistributionAddSubcommandTest.java new file mode 100644 index 000000000..1752788b3 --- /dev/null +++ b/src/test/java/com/crowdin/cli/commands/picocli/DistributionAddSubcommandTest.java @@ -0,0 +1,69 @@ +package com.crowdin.cli.commands.picocli; + +import com.crowdin.client.distributions.model.ExportMode; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; + +import static com.crowdin.cli.commands.picocli.GenericCommand.RESOURCE_BUNDLE; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +public class DistributionAddSubcommandTest extends PicocliTestUtils { + + @Test + public void testDistributionAddInvalidOptions() { + this.executeInvalidParams(CommandNames.DISTRIBUTION, CommandNames.DISTRIBUTION_ADD, "Test Distribution1", "--file", null); + } + + @ParameterizedTest + @MethodSource + public void testSubCommandCheckValidOptions(String name, ExportMode exportMode, List files, List bundleIds) { + DistributionAddSubcommand distributionAddSubcommand = new DistributionAddSubcommand(); + distributionAddSubcommand.name = name; + distributionAddSubcommand.exportMode = exportMode; + distributionAddSubcommand.files = files; + distributionAddSubcommand.bundleIds = bundleIds; + + List errors = distributionAddSubcommand.checkOptions(); + assertEquals(Collections.emptyList(), errors); + } + + public static Stream testSubCommandCheckValidOptions() { + return Stream.of( + arguments("Distribution 1", ExportMode.DEFAULT, Arrays.asList("strings.xml", "strings2.xml"), null), + arguments("Distribution 2", ExportMode.BUNDLE, null, Arrays.asList(1l, 2l)), + arguments("Distribution 3", null, Arrays.asList("strings.xml", "strings2.xml"), null)); + } + + @ParameterizedTest + @MethodSource + public void testSubCommandCheckInvalidOptions(String name, ExportMode exportMode, List files, + List bundleIds, List expErrors) { + DistributionAddSubcommand distributionAddSubcommand = new DistributionAddSubcommand(); + distributionAddSubcommand.name = name; + distributionAddSubcommand.exportMode = exportMode; + distributionAddSubcommand.files = files; + distributionAddSubcommand.bundleIds = bundleIds; + + List errors = distributionAddSubcommand.checkOptions(); + assertThat(errors, Matchers.equalTo(expErrors)); + } + + public static Stream testSubCommandCheckInvalidOptions() { + return Stream.of( + arguments("Distribution 1", ExportMode.DEFAULT, null, null, Arrays.asList(RESOURCE_BUNDLE.getString("error.distribution.empty_file"))), + arguments("Distribution 2", ExportMode.BUNDLE, null, null, Arrays.asList(RESOURCE_BUNDLE.getString("error.distribution.empty_bundle_ids"))), + arguments("Distribution 3", ExportMode.BUNDLE, Arrays.asList("file.json"), Arrays.asList(1l), Arrays.asList(RESOURCE_BUNDLE.getString("error.distribution.incorrect_file_command_usage"))), + arguments("Distribution 4", ExportMode.DEFAULT, Arrays.asList("file.json"), Arrays.asList(1l), Arrays.asList(RESOURCE_BUNDLE.getString("error.distribution.incorrect_bundle_id_command_usage"))) + ); + } +} diff --git a/src/test/java/com/crowdin/cli/commands/picocli/DistributionListSubcommandTest.java b/src/test/java/com/crowdin/cli/commands/picocli/DistributionListSubcommandTest.java new file mode 100644 index 000000000..d4178a41e --- /dev/null +++ b/src/test/java/com/crowdin/cli/commands/picocli/DistributionListSubcommandTest.java @@ -0,0 +1,17 @@ +package com.crowdin.cli.commands.picocli; + +import org.junit.jupiter.api.Test; + +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.verify; + +public class DistributionListSubcommandTest extends PicocliTestUtils { + + @Test + public void testDistributionList() { + this.execute(CommandNames.DISTRIBUTION, CommandNames.DISTRIBUTION_LIST); + verify(actionsMock) + .distributionList(anyBoolean()); + this.check(true); + } +} diff --git a/src/test/java/com/crowdin/cli/commands/picocli/PicocliTestUtils.java b/src/test/java/com/crowdin/cli/commands/picocli/PicocliTestUtils.java index 82e334d84..e2231818f 100644 --- a/src/test/java/com/crowdin/cli/commands/picocli/PicocliTestUtils.java +++ b/src/test/java/com/crowdin/cli/commands/picocli/PicocliTestUtils.java @@ -100,6 +100,10 @@ void mockActions() { .thenReturn(actionMock); when(actionsMock.taskAdd(any(), any(),any(), any(), anyLong(), any(), anyBoolean(), anyBoolean(), any())) .thenReturn(actionMock); + when(actionsMock.distributionList(anyBoolean())) + .thenReturn(actionMock); + when(actionsMock.distributionAdd(anyBoolean(), anyBoolean(), any(), any(), any(), any(), any(), any())) + .thenReturn(actionMock); when(actionsMock.bundleList(anyBoolean(), anyBoolean())) .thenReturn(actionMock); when(actionsMock.bundleAdd(any(), any(), any(), any(), any(), any(), anyBoolean())) diff --git a/src/test/java/com/crowdin/cli/properties/helper/TempProject.java b/src/test/java/com/crowdin/cli/properties/helper/TempProject.java index c6901dc2c..b2eb98d78 100644 --- a/src/test/java/com/crowdin/cli/properties/helper/TempProject.java +++ b/src/test/java/com/crowdin/cli/properties/helper/TempProject.java @@ -8,6 +8,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; +import java.util.Random; public class TempProject { @@ -30,7 +31,7 @@ public String getBasePath() { return dir.toString() + Utils.PATH_SEPARATOR; } - public File addFile(String path) { + public com.crowdin.client.sourcefiles.model.File addFile(String path) { try { Path file = dir.resolve(path); Path parentFile = file.getParent(); @@ -38,7 +39,11 @@ public File addFile(String path) { Files.createDirectories(parentFile); } Files.createFile(file); - return file.toFile(); + com.crowdin.client.sourcefiles.model.File crowdinFile = new com.crowdin.client.sourcefiles.model.File(); + crowdinFile.setName(file.toFile().getName()); + crowdinFile.setPath(file.toFile().getPath()); + crowdinFile.setId(new Random().nextLong()); + return crowdinFile; } catch (IOException e) { throw new RuntimeException("couldn't add file to folder", e); } diff --git a/website/mantemplates/crowdin-distribution-add.adoc b/website/mantemplates/crowdin-distribution-add.adoc new file mode 100644 index 000000000..af789246e --- /dev/null +++ b/website/mantemplates/crowdin-distribution-add.adoc @@ -0,0 +1,16 @@ +:includedir: ../generated-picocli-docs +:command: crowdin-distribution-add + +== crowdin distribution add + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-description] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-synopsis] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-arguments] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-commands] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-options] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-footer] diff --git a/website/mantemplates/crowdin-distribution-list.adoc b/website/mantemplates/crowdin-distribution-list.adoc new file mode 100644 index 000000000..d64cccb43 --- /dev/null +++ b/website/mantemplates/crowdin-distribution-list.adoc @@ -0,0 +1,16 @@ +:includedir: ../generated-picocli-docs +:command: crowdin-distribution-list + +== crowdin distribution list + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-description] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-synopsis] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-arguments] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-commands] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-options] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-footer] diff --git a/website/mantemplates/crowdin-distribution-release.adoc b/website/mantemplates/crowdin-distribution-release.adoc new file mode 100644 index 000000000..8e1e5b2a7 --- /dev/null +++ b/website/mantemplates/crowdin-distribution-release.adoc @@ -0,0 +1,16 @@ +:includedir: ../generated-picocli-docs +:command: crowdin-distribution-release + +== crowdin distribution release + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-description] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-synopsis] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-arguments] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-commands] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-options] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-footer] diff --git a/website/mantemplates/crowdin-distribution.adoc b/website/mantemplates/crowdin-distribution.adoc new file mode 100644 index 000000000..0ef876137 --- /dev/null +++ b/website/mantemplates/crowdin-distribution.adoc @@ -0,0 +1,16 @@ +:includedir: ../generated-picocli-docs +:command: crowdin-distribution + +== crowdin distribution + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-description] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-synopsis] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-arguments] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-commands] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-options] + +include::{includedir}/{command}.adoc[tag=picocli-generated-man-section-footer] diff --git a/website/sidebars.js b/website/sidebars.js index b53c23c6f..e0bc9b251 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -188,6 +188,21 @@ const sidebars = { 'commands/crowdin-task-list', ] }, + { + type: 'category', + label: 'crowdin distribution', + link: { + type: 'doc', + id: 'commands/crowdin-distribution' + }, + collapsible: true, + collapsed: true, + items: [ + 'commands/crowdin-distribution-add', + 'commands/crowdin-distribution-list', + 'commands/crowdin-distribution-release', + ] + }, 'commands/crowdin-pre-translate', ], },