Skip to content
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

fix: windows escape symbols #684

Merged
merged 6 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@
Utils.PATH_SEPARATOR +
project.getSourceLanguageId() + "-REV"
);
return Utils.unixPath(path);
return Utils.toUnixPath(path);

Check warning on line 235 in src/main/java/com/crowdin/cli/commands/actions/DownloadSourcesAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/DownloadSourcesAction.java#L235

Added line #L235 was not covered by tests
},
Function.identity()
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ public void act(Outputter out, ProjectProperties properties, ClientScreenshot cl
request.setBranchId(branch.getId());
}
if (nonNull(pathToSourceFile)) {
final String normalizedPath = Utils.unixPath(Utils.sepAtStart(pathToSourceFile));
final String normalizedPath = Utils.toUnixPath(Utils.sepAtStart(pathToSourceFile));
FileInfo fileInfo = project.getFileInfos().stream()
.filter(f -> normalizedPath.equals(f.getPath())).findFirst()
.orElseThrow(() -> new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.file_not_exists"), pathToSourceFile)));
request.setFileId(fileInfo.getId());
}
if (nonNull(directoryPath)) {
final String normalizedPath = Utils.unixPath(Utils.sepAtStart(directoryPath));
final String normalizedPath = Utils.toUnixPath(Utils.sepAtStart(directoryPath));
Directory directory = project.getDirectories().values().stream()
.filter(d -> normalizedPath.equals(d.getPath())).findFirst()
.orElseThrow(() -> new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.dir_not_exists"), directoryPath)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ public void act(Outputter out, ProjectProperties pb, ProjectClient client) {
List<LanguageProgress> progresses;

if (file != null) {
String filePath = Utils.unixPath(Utils.sepAtStart(file));
String filePath = Utils.toUnixPath(Utils.sepAtStart(file));
Long fileId = project.getFileInfos().stream()
.filter(f -> filePath.equals(f.getPath()))
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.file_not_exists"), file)))
.getId();
progresses = client.getFileProgress(fileId);
} else if (directory != null) {
String directoryPath = Utils.unixPath(Utils.sepAtStart(directory));
String directoryPath = Utils.toUnixPath(Utils.sepAtStart(directory));
Long directoryId = project.getDirectories().values().stream()
.filter(d -> directoryPath.equals(d.getPath()))
.findFirst()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public static Stream<File> getFiles(String basePath, String sourcePattern, List<
public static List<String> filterProjectFiles(
List<String> filePaths, String sourcePattern, List<String> ignorePatterns, boolean preserveHierarchy, PlaceholderUtil placeholderUtil
) {
filePaths = filePaths.stream().map((Utils.isWindows() ? Utils::windowsPath : Utils::unixPath)).map(Utils::noSepAtStart).collect(Collectors.toList());
sourcePattern = Utils.noSepAtStart(Utils.isWindows() ? Utils.windowsPath(sourcePattern) : Utils.unixPath(sourcePattern));
filePaths = filePaths.stream().map((Utils.isWindows() ? Utils::toWindowsPath : Utils::toUnixPath)).map(Utils::noSepAtStart).collect(Collectors.toList());
sourcePattern = Utils.noSepAtStart(Utils.isWindows() ? Utils.toWindowsPath(sourcePattern) : Utils.toUnixPath(sourcePattern));
ignorePatterns = (ignorePatterns != null)
? ignorePatterns.stream().map((Utils.isWindows() ? Utils::windowsPath : Utils::unixPath)).map(Utils::noSepAtStart).collect(Collectors.toList()) : Collections.emptyList();
? ignorePatterns.stream().map((Utils.isWindows() ? Utils::toWindowsPath : Utils::toUnixPath)).map(Utils::noSepAtStart).collect(Collectors.toList()) : Collections.emptyList();

Predicate<String> sourcePredicate;
Predicate<String> ignorePredicate;
Expand Down
30 changes: 20 additions & 10 deletions src/main/java/com/crowdin/cli/utils/PlaceholderUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import java.util.Set;
import java.util.stream.Collectors;

import static com.crowdin.cli.utils.Utils.isWindows;

public class PlaceholderUtil {

public static final String PLACEHOLDER_ANDROID_CODE = "%android_code%";
Expand Down Expand Up @@ -51,13 +53,16 @@
private static final String SET_CLOSE_BRACKET = "]";
public static final String ROUND_BRACKET_OPEN = "(";
public static final String ROUND_BRACKET_CLOSE = ")";
public static final String ESCAPE_ROUND_BRACKET_OPEN = "\\(";
public static final String ESCAPE_ROUND_BRACKET_CLOSE = "\\)";
private static final String ESCAPE_DOT = "\\.";
public static final String ESCAPE_ROUND_BRACKET_OPEN = isWindows() ? "^(" : "\\(";
public static final String ESCAPE_ROUND_BRACKET_CLOSE = isWindows() ? "^)" : "\\)";
private static final String ESCAPE_DOT = isWindows() ? "^." : "\\.";
private static final String ESCAPE_DOT_REGEX = "\\.";
private static final String ESCAPE_DOT_PLACEHOLDER = "{ESCAPE_DOT}";
private static final String ESCAPE_QUESTION = "\\?";
private static final String ESCAPE_QUESTION = isWindows() ? "^?" : "\\?";
private static final String ESCAPE_QUESTION_REGEX = "\\?";
private static final String ESCAPE_QUESTION_PLACEHOLDER = "{ESCAPE_QUESTION_MARK}";
private static final String ESCAPE_ASTERISK = "\\*";
private static final String ESCAPE_ASTERISK = isWindows() ? "^*" : "\\*";
private static final String ESCAPE_ASTERISK_REGEX = "\\*";
private static final String ESCAPE_ASTERISK_PLACEHOLDER = "{ESCAPE_ASTERISK}";
private static final String ESCAPE_ASTERISK_REPLACEMENT_FROM = ".+" + Utils.PATH_SEPARATOR;
private static final String ESCAPE_ASTERISK_REPLACEMENT_TO = "(.+" + Utils.PATH_SEPARATOR_REGEX + ")?";
Expand Down Expand Up @@ -228,13 +233,13 @@
}

public static String formatSourcePatternForRegex(String toFormat) {
if(Utils.isWindows()){
if (isWindows()) {
toFormat = toFormat
.replace("\\", "\\\\");
.replace("\\", "\\\\");

Check warning on line 238 in src/main/java/com/crowdin/cli/utils/PlaceholderUtil.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/utils/PlaceholderUtil.java#L238

Added line #L238 was not covered by tests
}
toFormat = toFormat
.replace(ESCAPE_DOT, ESCAPE_DOT_PLACEHOLDER)
.replace(DOT, ESCAPE_DOT)
.replace(DOT, ESCAPE_DOT_REGEX)
.replace(ESCAPE_DOT_PLACEHOLDER, ESCAPE_DOT)

.replace(ESCAPE_QUESTION, ESCAPE_QUESTION_PLACEHOLDER)
Expand All @@ -252,10 +257,15 @@

toFormat = toFormat
.replace(ROUND_BRACKET_OPEN, ESCAPE_ROUND_BRACKET_OPEN)

.replace(ROUND_BRACKET_CLOSE, ESCAPE_ROUND_BRACKET_CLOSE)

.replace(ESCAPE_ASTERISK_REPLACEMENT_FROM, ESCAPE_ASTERISK_REPLACEMENT_TO);

if (isWindows()) {
toFormat = toFormat
.replace(ESCAPE_ASTERISK, ESCAPE_ASTERISK_REGEX)
.replace(ESCAPE_DOT, ESCAPE_DOT_REGEX)
.replace(ESCAPE_QUESTION, ESCAPE_QUESTION_REGEX);

Check warning on line 267 in src/main/java/com/crowdin/cli/utils/PlaceholderUtil.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/utils/PlaceholderUtil.java#L264-L267

Added lines #L264 - L267 were not covered by tests
}
return toFormat
.replace(PLACEHOLDER_FILE_EXTENSION, "[^/]+")
.replace(PLACEHOLDER_FILE_NAME, "[^/]+")
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/com/crowdin/cli/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,16 @@
System.getProperty("os.version"));
}

public static String unixPath(String path) {
return (path != null) ? path.replaceAll("[\\\\/]+", "/") : null;
public static String toUnixPath(String path) {
if (path == null) {
return null;

Check warning on line 91 in src/main/java/com/crowdin/cli/utils/Utils.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/utils/Utils.java#L91

Added line #L91 was not covered by tests
}
return isWindows()
? path.replaceAll("[\\\\/]+", "/")
: path.replaceAll("\\\\{2,}", "/").replaceAll("/+", "/");
}

public static String windowsPath(String path) {
public static String toWindowsPath(String path) {
return (path != null) ? path.replaceAll("[\\\\/]+", "\\\\") : null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,90 @@ public void testFilterProjectFiles_dest() {
assertThat(actual, containsInAnyOrder(expected));
}

@ParameterizedTest
@MethodSource
@DisabledOnOs({OS.LINUX, OS.MAC})
public void testFilterProjectFiles_escapeSymbols_windows(List<String> filePaths, String sourcePattern, List<String> expected) {
List<String> actual = SourcesUtils.filterProjectFiles(
filePaths, sourcePattern, Collections.emptyList(), true, PlaceholderUtilBuilder.STANDART.build(""));
assertEquals(expected.size(), actual.size());
assertThat(actual, containsInAnyOrder(expected.toArray()));
}

static Stream<Arguments> testFilterProjectFiles_escapeSymbols_windows() {
String file1 = "here\\file-1.po";
String file1Symbol = "here\\file?1.po";
String file2 = "here\\file-2.po";
String file2Symbol = "here\\file*2.po";
String file3 = "here\\file-3.po";
String file3Symbol = "here\\file.3.po";
List<String> allFiles = Arrays.asList(file1, file1Symbol, file2, file2Symbol, file3, file3Symbol);
return Stream.of(
arguments(
allFiles,
"here\\file^?1.po",
Arrays.asList(file1Symbol)
),
arguments(
allFiles,
"here\\file^*2.po",
Arrays.asList(file2Symbol)
),
arguments(
allFiles,
"here\\file^.3.po",
Arrays.asList(file3Symbol)
),
arguments(
allFiles,
"here\\*.po",
allFiles
)
);
}

@ParameterizedTest
@MethodSource
@DisabledOnOs(OS.WINDOWS)
public void testFilterProjectFiles_escapeSymbols_unix(List<String> filePaths, String sourcePattern, List<String> expected) {
List<String> actual = SourcesUtils.filterProjectFiles(
filePaths, sourcePattern, Collections.emptyList(), true, PlaceholderUtilBuilder.STANDART.build(""));
assertEquals(expected.size(), actual.size());
assertThat(actual, containsInAnyOrder(expected.toArray()));
}

static Stream<Arguments> testFilterProjectFiles_escapeSymbols_unix() {
String file1 = "here/file-1.po";
String file1Symbol = "here/file?1.po";
String file2 = "here/file-2.po";
String file2Symbol = "here/file*2.po";
String file3 = "here/file-3.po";
String file3Symbol = "here/file.3.po";
List<String> allFiles = Arrays.asList(file1, file1Symbol, file2, file2Symbol, file3, file3Symbol);
return Stream.of(
arguments(
allFiles,
"here/file\\?1.po",
Arrays.asList(file1Symbol)
),
arguments(
allFiles,
"here/file\\*2.po",
Arrays.asList(file2Symbol)
),
arguments(
allFiles,
"here/file\\.3.po",
Arrays.asList(file3Symbol)
),
arguments(
allFiles,
"here/*.po",
allFiles
)
);
}

@ParameterizedTest
@MethodSource
public void testContainsParameter(String sourcePattern, boolean expected) {
Expand Down
15 changes: 12 additions & 3 deletions src/test/java/com/crowdin/cli/utils/UtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Optional;
import org.apache.commons.lang3.SystemUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -36,13 +38,20 @@ public void testBuildUserAgent() {
}

@Test
public void testUnixPath() {
assertEquals("/path/to/file", Utils.unixPath("\\path\\to\\file"));
@DisabledOnOs({OS.LINUX, OS.MAC})
andrii-bodnar marked this conversation as resolved.
Show resolved Hide resolved
public void testUnixPath_windows() {
assertEquals("/path/to/file", Utils.toUnixPath("\\path\\to\\\\file"));
}

@Test
@DisabledOnOs(OS.WINDOWS)
public void testUnixPath_unix() {
assertEquals("/path/to/file", Utils.toUnixPath("/path/to\\\\file"));
}

@Test
public void testWindowsPath() {
assertEquals("\\path\\to\\file", Utils.windowsPath("/path/to/file"));
assertEquals("\\path\\to\\file", Utils.toWindowsPath("/path/to/file"));
}

@Test
Expand Down
Loading