diff --git a/tools/dotcms-cli/api-data-model/src/main/java/com/dotcms/common/AssetsUtils.java b/tools/dotcms-cli/api-data-model/src/main/java/com/dotcms/common/AssetsUtils.java index 91cd88d2d1ef..a3d908866715 100644 --- a/tools/dotcms-cli/api-data-model/src/main/java/com/dotcms/common/AssetsUtils.java +++ b/tools/dotcms-cli/api-data-model/src/main/java/com/dotcms/common/AssetsUtils.java @@ -203,6 +203,7 @@ public static List parseRootPaths(final File workspace, final File sourc // Check if we are inside the workspace but also inside the files folder if (sourceCount > workspaceCount + 1 || (sourceCount == workspaceCount + 1 && !sourcePath.startsWith(filesPath))) { logger.warn("Invalid source path provided for a files push {}. Source path must be inside the files folder will fallback to workspace. {}", sourcePath, workspacePath); + //if a source path is provided, but it is not inside the files folder but still is a valid folder then we will fall back to the workspace return parseRootPaths(workspacePath, workspaceCount, workspaceCount); } diff --git a/tools/dotcms-cli/cli/src/main/java/com/dotcms/cli/common/FilesUtils.java b/tools/dotcms-cli/cli/src/main/java/com/dotcms/cli/common/FilesUtils.java index ee1ab2838a96..c97f6952d02d 100644 --- a/tools/dotcms-cli/cli/src/main/java/com/dotcms/cli/common/FilesUtils.java +++ b/tools/dotcms-cli/cli/src/main/java/com/dotcms/cli/common/FilesUtils.java @@ -1,6 +1,10 @@ package com.dotcms.cli.common; import com.dotcms.model.language.Language; +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; import java.util.List; import java.util.Set; @@ -61,4 +65,16 @@ public static String cleanFileName(final String badFileName) { return cleanName.toString(); } + /** + * Checks if the specified directory is not empty. + * @param path the directory to check + * @return true if the directory is not empty, false otherwise + * @throws IOException if an I/O error occurs + */ + public static boolean isDirectoryNotEmpty(Path path) throws IOException { + try (DirectoryStream directoryStream = Files.newDirectoryStream(path)) { + return directoryStream.iterator().hasNext(); + } + } + } diff --git a/tools/dotcms-cli/cli/src/test/java/com/dotcms/cli/command/files/FilesPushCommandIT.java b/tools/dotcms-cli/cli/src/test/java/com/dotcms/cli/command/files/FilesPushCommandIT.java index a4f6f8c973ea..f4f40e907cee 100644 --- a/tools/dotcms-cli/cli/src/test/java/com/dotcms/cli/command/files/FilesPushCommandIT.java +++ b/tools/dotcms-cli/cli/src/test/java/com/dotcms/cli/command/files/FilesPushCommandIT.java @@ -1,5 +1,6 @@ package com.dotcms.cli.command.files; +import static com.dotcms.cli.common.FilesUtils.isDirectoryNotEmpty; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -22,6 +23,7 @@ import org.mockito.InjectMocks; import org.mockito.Mockito; import picocli.CommandLine; +import picocli.CommandLine.ExitCode; @QuarkusTest @TestProfile(DotCMSITProfile.class) @@ -363,4 +365,42 @@ void testPushRetryAttempts() throws IOException { deleteTempDirectory(tempFolder); } } + + /** + * Given Scenario: Pull down a workspace doesn't matter if it is empty, + * Call the push command with a path that doesn't match any files folder but exists within the workspace. + * Expected Result: When the command is called passing a folder that exists within the workspace but its outside files it should return OK cause we default to the workspace root + * If the command is called with a path that doesn't match any files folder in the workspace, it should return OK. + * + * @throws IOException If an I/O error occurs. + */ + @Test + void testPushNonFilesMatchingPath() throws IOException { + + // Create a temporal folder for the pull + var tempFolder = createTempFolder(); + final CommandLine commandLine = createCommand(); + final StringWriter writer = new StringWriter(); + try (PrintWriter out = new PrintWriter(writer)) { + //Pull down a workspace if empty + commandLine.setOut(out); + final String path = String.format("//%s", "default"); + int status = commandLine.execute(FilesCommand.NAME, FilesPull.NAME, path, "--workspace", tempFolder.toString()); + Assertions.assertEquals(CommandLine.ExitCode.OK, status); + + status = commandLine.execute(FilesCommand.NAME, FilesPush.NAME, "--workspace", tempFolder.toAbsolutePath().toString(), "content-types"); + Assertions.assertEquals(CommandLine.ExitCode.OK, status); + + Assertions.assertTrue(isDirectoryNotEmpty(tempFolder)); + + //But if called with a path that doesn't match any files folder in the workspace + status = commandLine.execute(FilesCommand.NAME, FilesPush.NAME, "--workspace", tempFolder.toAbsolutePath().toString(), "non-existing-folder"); + Assertions.assertEquals(ExitCode.SOFTWARE, status); + + } finally { + deleteTempDirectory(tempFolder); + } + } + + }