Skip to content

Commit

Permalink
feat: replace file id with file path in task add command (#641)
Browse files Browse the repository at this point in the history
  • Loading branch information
katerina20 committed Sep 19, 2023
1 parent 9246038 commit fdf9cec
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 49 deletions.
5 changes: 4 additions & 1 deletion src/main/java/com/crowdin/cli/commands/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ NewAction<BaseProperties, ClientTm> tmDownload(

NewAction<ProjectProperties, ClientTask> taskList(boolean plainView, boolean isVerbose, String status, Long assigneeId);

NewAction<ProjectProperties, ClientTask> taskAdd(String title, Integer type, String language, List<Long> fileId, Long workflowStep, String description, boolean skipAssignedStrings, boolean skipUntranslatedStrings, boolean includePreTranslatedStringsOnly, List<Long> labels);
NewAction<ProjectProperties, ClientTask> taskAdd(
boolean noProgress, String title, Integer type, String language, List<String> files, String branch, Long workflowStep,
String description, boolean skipAssignedStrings, boolean skipUntranslatedStrings, boolean includePreTranslatedStringsOnly,
List<Long> labels, ProjectClient projectClient);

NewAction<ProjectProperties, ClientDistribution> distributionList(boolean plainView);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,11 @@ public NewAction<ProjectProperties, ClientTask> taskList(boolean plainView, bool
}

@Override
public NewAction<ProjectProperties, ClientTask> taskAdd(String title, Integer type, String language, List<Long> fileId, Long workflowStep, String description, boolean skipAssignedStrings, boolean skipUntranslatedStrings, boolean includePreTranslatedStringsOnly, List<Long> labels) {
return new TaskAddAction(title, type, language, fileId, workflowStep, description, skipAssignedStrings, skipUntranslatedStrings, includePreTranslatedStringsOnly, labels);
public NewAction<ProjectProperties, ClientTask> taskAdd(boolean noProgress, String title, Integer type, String language,
List<String> files, String branch, Long workflowStep, String description, boolean skipAssignedStrings,
boolean skipUntranslatedStrings, boolean includePreTranslatedStringsOnly, List<Long> labels, ProjectClient projectClient
) {
return new TaskAddAction(noProgress, title, type, language, files, branch, workflowStep, description, skipAssignedStrings, skipUntranslatedStrings, includePreTranslatedStringsOnly, labels, projectClient);
}

@Override
Expand Down
65 changes: 60 additions & 5 deletions src/main/java/com/crowdin/cli/commands/actions/TaskAddAction.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
package com.crowdin.cli.commands.actions;

import com.crowdin.cli.client.ClientTask;
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.ProjectFilesUtils;
import com.crowdin.cli.commands.functionality.PropertiesBeanUtils;
import com.crowdin.cli.properties.ProjectProperties;

import com.crowdin.cli.utils.Utils;
import com.crowdin.cli.utils.console.ConsoleSpinner;
import com.crowdin.client.sourcefiles.model.FileInfo;
import com.crowdin.client.tasks.model.AddTaskRequest;
import com.crowdin.client.tasks.model.CrowdinTaskCreateFormRequest;
import com.crowdin.client.tasks.model.EnterpriseTaskCreateFormRequest;
import com.crowdin.client.tasks.model.Task;

import lombok.AllArgsConstructor;

import java.util.List;
import java.util.Optional;
import java.util.*;

import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE;
import static com.crowdin.cli.utils.console.ExecutionStatus.OK;
import static com.crowdin.cli.utils.console.ExecutionStatus.WARNING;
import static java.util.Objects.nonNull;

@AllArgsConstructor
class TaskAddAction implements NewAction<ProjectProperties, ClientTask> {

private boolean noProgress;

private String title;

private Integer type;

private String language;

private List<Long> fileId;
private List<String> files;

private String branch;

private Long workflowStep;

Expand All @@ -43,16 +54,52 @@ class TaskAddAction implements NewAction<ProjectProperties, ClientTask> {

private List<Long> labels;

private ProjectClient projectClient;

@Override
public void act(Outputter out, ProjectProperties pb, ClientTask client) {
boolean isOrganization = PropertiesBeanUtils.isOrganization(pb.getBaseUrl());
Task task;
AddTaskRequest addTaskRequest;
CrowdinProjectFull project = ConsoleSpinner.execute(out, "message.spinner.fetching_project_info", "error.collect_project_info",
this.noProgress, false, () -> this.projectClient.downloadFullProject(this.branch));

List<Long> fileIds = new ArrayList<>();
boolean isIdUsed = false;
Map<String, FileInfo> paths = ProjectFilesUtils.buildFilePaths(project.getDirectories(), project.getBranches(), project.getFileInfos());
for (String file : files) {
// TODO: Remove backward compatibility with file ids
if (isConvertibleToLong(file)) {
isIdUsed = true;
Long id = Long.parseLong(file);
boolean isFileExist = paths.values().stream().anyMatch(p -> p.getId().equals(id));
if (isFileExist) {
fileIds.add(id);
} else {
out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("error.file_id_not_exists"), file)));
}
} else {
final String path = Utils.normalizePath(Utils.noSepAtStart(file));
if (paths.containsKey(path)) {
fileIds.add(paths.get(path).getId());
} else {
out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("error.file_not_exists"), path)));
}
}
}
// TODO: Remove backward compatibility with file ids
if (isIdUsed) {
out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("message.file_id_deprecated"))));
}
if (fileIds.isEmpty()) {
throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.task.no_valid_file")));
}

if (isOrganization) {
addTaskRequest = new EnterpriseTaskCreateFormRequest();
Optional.ofNullable(title).ifPresent(value -> ((EnterpriseTaskCreateFormRequest) addTaskRequest).setTitle(value));
Optional.ofNullable(language).ifPresent(value -> ((EnterpriseTaskCreateFormRequest) addTaskRequest).setLanguageId(value));
Optional.ofNullable(fileId).ifPresent(value -> ((EnterpriseTaskCreateFormRequest) addTaskRequest).setFileIds(value));
Optional.ofNullable(fileIds).ifPresent(value -> ((EnterpriseTaskCreateFormRequest) addTaskRequest).setFileIds(value));
Optional.ofNullable(description).ifPresent(value -> ((EnterpriseTaskCreateFormRequest) addTaskRequest).setDescription(value));
Optional.ofNullable(skipAssignedStrings).ifPresent(value -> ((EnterpriseTaskCreateFormRequest) addTaskRequest).setSkipAssignedStrings(value));
Optional.ofNullable(includePreTranslatedStringsOnly).ifPresent(value -> ((EnterpriseTaskCreateFormRequest) addTaskRequest).setIncludePreTranslatedStringsOnly(value));
Expand All @@ -63,7 +110,7 @@ public void act(Outputter out, ProjectProperties pb, ClientTask client) {
Optional.ofNullable(title).ifPresent(value -> ((CrowdinTaskCreateFormRequest) addTaskRequest).setTitle(value));
Optional.ofNullable(type).ifPresent(value -> ((CrowdinTaskCreateFormRequest) addTaskRequest).setType(value));
Optional.ofNullable(language).ifPresent(value -> ((CrowdinTaskCreateFormRequest) addTaskRequest).setLanguageId(value));
Optional.ofNullable(fileId).ifPresent(value -> ((CrowdinTaskCreateFormRequest) addTaskRequest).setFileIds(value));
Optional.ofNullable(fileIds).ifPresent(value -> ((CrowdinTaskCreateFormRequest) addTaskRequest).setFileIds(value));
Optional.ofNullable(description).ifPresent(value -> ((CrowdinTaskCreateFormRequest) addTaskRequest).setDescription(value));
Optional.ofNullable(skipAssignedStrings).ifPresent(value -> ((CrowdinTaskCreateFormRequest) addTaskRequest).setSkipAssignedStrings(value));
Optional.ofNullable(skipUntranslatedStrings).ifPresent(value -> ((CrowdinTaskCreateFormRequest) addTaskRequest).setSkipUntranslatedStrings(value));
Expand All @@ -79,4 +126,12 @@ public void act(Outputter out, ProjectProperties pb, ClientTask client) {
out.println(OK.withIcon(String.format(RESOURCE_BUNDLE.getString("message.task.added"), task.getTitle())));
}

private boolean isConvertibleToLong(String str) {
try {
Long.parseLong(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.crowdin.cli.client.ClientTask;
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;
Expand All @@ -25,4 +26,8 @@ protected ProjectProperties getProperties(PropertiesBuilders propertiesBuilders,
protected ClientTask getClient(ProjectProperties properties) {
return Clients.getClientTask(properties.getApiToken(), properties.getBaseUrl(), properties.getProjectId());
}

protected ProjectClient getProjectClient(ProjectProperties properties) {
return Clients.getProjectClient(properties.getApiToken(), properties.getBaseUrl(), Long.parseLong(properties.getProjectId()));
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.crowdin.cli.commands.picocli;

import com.crowdin.cli.client.ClientTask;
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.commands.functionality.PropertiesBeanUtils;
import com.crowdin.cli.properties.ProjectProperties;

Expand All @@ -29,8 +31,11 @@ class TaskAddSubcommand extends ActCommandTask {
@CommandLine.Option(names = {"--language"}, paramLabel = "...", descriptionKey = "crowdin.task.add.language", order = -2)
protected String language;

@CommandLine.Option(names = {"--file"}, paramLabel = "...", descriptionKey = "crowdin.task.add.file-id", order = -2)
protected List<Long> files;
@CommandLine.Option(names = {"--file"}, paramLabel = "...", descriptionKey = "crowdin.task.add.file", order = -2)
protected List<String> files;

@CommandLine.Option(names = {"--branch"}, paramLabel = "...", descriptionKey = "branch", order = -2)
protected String branch;

@CommandLine.Option(names = {"--workflow-step"}, paramLabel = "...", descriptionKey = "crowdin.task.add.workflow-step", order = -2)
protected Long workflowStep;
Expand All @@ -53,18 +58,23 @@ class TaskAddSubcommand extends ActCommandTask {
@Override
protected NewAction<ProjectProperties, ClientTask> getAction(Actions actions) {
int intType = TRANSLATE_TASK_TYPE.equalsIgnoreCase(type) ? 0 : 1;
Outputter out = new PicocliOutputter(System.out, isAnsi());
ProjectClient projectClient = this.getProjectClient(this.getProperties(propertiesBuilders, out));

return actions.taskAdd(
title,
intType,
language,
files,
workflowStep,
description,
skipAssignedStrings,
skipUntranslatedStrings,
includePreTranslatedStringsOnly,
labels
noProgress,
title,
intType,
language,
files,
branch,
workflowStep,
description,
skipAssignedStrings,
skipUntranslatedStrings,
includePreTranslatedStringsOnly,
labels,
projectClient
);
}

Expand Down Expand Up @@ -108,7 +118,7 @@ protected List<String> checkOptions(boolean isEnterprise) {
}

if (files == null || files.isEmpty()) {
errors.add(RESOURCE_BUNDLE.getString("error.task.empty_fileId"));
errors.add(RESOURCE_BUNDLE.getString("error.task.empty_file"));
}

if (TRANSLATE_TASK_TYPE.equalsIgnoreCase(type) && includePreTranslatedStringsOnly) {
Expand Down
7 changes: 5 additions & 2 deletions src/main/resources/messages/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ crowdin.task.add.usage.customSynopsis=@|fg(green) crowdin task add|@ <title> [CO
crowdin.task.add.title=Task title
crowdin.task.add.type=Task type. Possible values: translate, proofread (crowdin.com only)
crowdin.task.add.language=Task Language Identifier
crowdin.task.add.file-id=File ID. Could be specified multiple times
crowdin.task.add.file=File path in the Crowdin project. Can be specified multiple times
crowdin.task.add.workflow-step=Task workflow step (Crowdin Enterprise only)
crowdin.task.add.description=Task description
crowdin.task.add.skip-assigned-strings=Skip strings already included in other tasks
Expand Down Expand Up @@ -416,6 +416,7 @@ error.clearing_temp=Failed to delete temporary files
error.while_checking_base_path=Failed to check the base path. Try to run the application with admin permission
error.skip_untranslated_both_strings_and_files=You cannot skip strings and files at the same time. Please use one of these parameters instead.
error.file_not_exists=Project doesn't contain the '%s' file
error.file_id_not_exists=Project doesn't contain file with id '%s'
error.dir_not_exists=Project doesn't contain the '%s' directory
error.label_not_exists=Project doesn't contain the '%s' label
error.branch_not_exists=Project doesn't contain the '%s' branch
Expand Down Expand Up @@ -468,11 +469,12 @@ error.task.unsupported.type=Unsupported task type. Possible values: translate, p
error.task.empty_type=Task type can not be empty. Possible values: translate, proofread
error.task.empty_title=Task title can not be empty
error.task.empty_language=Language can not be empty. (e.g. es-ES, en-US)
error.task.empty_fileId=The '--file' value can not be empty
error.task.empty_file=The '--file' value can not be empty
error.task.empty_workflow_step=Workflow step id can not be empty
error.task.translate_type_skip_untranslated_strings=The '--skip-untranslated-strings' option can't be used with the 'translate' task type
error.task.translate_type_include_pre_translated_strings=The '--include-pre-translated-strings-only' option can't be used with the 'translate' task type
error.task.skip_untranslated_strings_include_pre_translated=The '--include-pre-translated-strings-only' option should be used with the '--skip-untranslated-strings' option
error.task.no_valid_file=No valid file specified for the task. At least one valid file is required

error.bundle_is_not_added=Bundle was not added: '%s'
error.bundle.empty_name=Bundle name can't be empty
Expand Down Expand Up @@ -610,6 +612,7 @@ message.no_targets_to_exec=Couldn't find any targets to download
message.no_target_to_exec=Couldn't find @|bold '%s'|@ target to download
message.description=%s @|bold '%s'|@
message.obsolete_file=Obsolete file @|bold '%s'|@
message.file_id_deprecated=File id is deprecated and will be removed in future releases. Please use file path instead

message.download_sources.preserve_hierarchy_warning=Because the @|bold 'preserve_hierarchy'|@ parameter is set to 'false':\n\t- CLI might download some unexpected files that match the pattern;\n\t- Source file hierarchy may not be preserved and will be the same as in Crowdin.
message.download_translations.preserve_hierarchy_warning=Because the @|bold 'preserve_hierarchy'|@ parameter is set to 'false' CLI might download some unexpected files that match the pattern
Expand Down
Loading

0 comments on commit fdf9cec

Please sign in to comment.