This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new 41a36eb3c1 Fix Check for Delete and Copy/Move result filenames (#8939)
41a36eb3c1 is described below

commit 41a36eb3c1e4aca3c1119a9d5fc0fdc6a3764788
Author: Lance <[email protected]>
AuthorDate: Thu Oct 15 23:03:37 2026 +0800

    Fix Check for Delete and Copy/Move result filenames (#8939)
    
    Signed-off-by: leehaut <[email protected]>
---
 .../ActionCopyMoveResultFilenames.java             | 28 +++++----
 .../ActionCopyMoveResultFilenamesTest.java         | 69 ++++++++++++++++++++++
 .../ActionDeleteResultFilenames.java               | 20 ++-----
 .../ActionDeleteResultFilenamesTest.java           | 15 +++++
 4 files changed, 104 insertions(+), 28 deletions(-)

diff --git 
a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
 
b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
index 0200572e8e..ed698fbd92 100644
--- 
a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
+++ 
b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
@@ -43,16 +43,17 @@ import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.ActionBase;
 import org.apache.hop.workflow.action.IAction;
-import org.apache.hop.workflow.action.validator.AbstractFileValidator;
 import org.apache.hop.workflow.action.validator.ActionValidatorUtils;
 import org.apache.hop.workflow.action.validator.AndValidator;
-import org.apache.hop.workflow.action.validator.ValidatorContext;
 import org.apache.hop.workflow.engine.IWorkflowEngine;
 
 /**
- * This defines a 'copymoveresultfilenames' action. Its main use would be to 
copy or move files in
- * the result filenames to a destination folder. that can be used to control 
the flow in ETL cycles.
+ * This defines a 'copy move result filenames' action. Its main use would be 
to copy or move files
+ * in the result filenames to a destination folder. that can be used to 
control the flow in ETL
+ * cycles.
  */
+@Getter
+@Setter
 @Action(
     id = "COPY_MOVE_RESULT_FILENAMES",
     name = "i18n::ActionCopyMoveResultFilenames.Name",
@@ -61,8 +62,6 @@ import org.apache.hop.workflow.engine.IWorkflowEngine;
     categoryDescription = 
"i18n:org.apache.hop.workflow:ActionCategory.Category.FileManagement",
     keywords = "i18n::ActionCopyMoveResultFilenames.keyword",
     documentationUrl = "/workflow/actions/processresultfilenames.html")
-@Getter
-@Setter
 public class ActionCopyMoveResultFilenames extends ActionBase implements 
Cloneable, IAction {
   private static final Class<?> PKG = ActionCopyMoveResultFilenames.class;
   public static final String SUCCESS_IF_AT_LEAST_X_FILES = 
"success_when_at_least";
@@ -488,12 +487,15 @@ public class ActionCopyMoveResultFilenames extends 
ActionBase implements Cloneab
       WorkflowMeta workflowMeta,
       IVariables variables,
       IHopMetadataProvider metadataProvider) {
-    ValidatorContext ctx = new ValidatorContext();
-    AbstractFileValidator.putVariableSpace(ctx, getVariables());
-    AndValidator.putValidators(
-        ctx,
-        ActionValidatorUtils.notNullValidator(),
-        ActionValidatorUtils.fileDoesNotExistValidator());
-    ActionValidatorUtils.andValidator().validate(this, "filename", remarks, 
ctx);
+    // Delete only drops names from the result. Copy and move need a 
destination folder.
+    if (getAction() == ActionType.DELETE) {
+      return;
+    }
+    ActionValidatorUtils.andValidator()
+        .validate(
+            this,
+            "destinationFolder",
+            remarks,
+            
AndValidator.putValidators(ActionValidatorUtils.notBlankValidator()));
   }
 }
diff --git 
a/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesTest.java
 
b/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesTest.java
index c023653d8b..6d5b1f3ac6 100644
--- 
a/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesTest.java
+++ 
b/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesTest.java
@@ -19,12 +19,18 @@
 package org.apache.hop.workflow.actions.copymoveresultfilenames;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hop.core.ICheckResult;
 import org.apache.hop.workflow.action.ActionSerializationTestUtil;
 import org.junit.jupiter.api.Test;
 
+/** Unit test for {@link ActionCopyMoveResultFilenames} */
 class ActionCopyMoveResultFilenamesTest {
+
   @Test
   void testSerializationRoundTrip() throws Exception {
     ActionCopyMoveResultFilenames action =
@@ -49,4 +55,67 @@ class ActionCopyMoveResultFilenamesTest {
     assertTrue(action.isRemovedSourceFilename());
     assertTrue(action.isAddDestinationFilename());
   }
+
+  @Test
+  void checkRequiresDestinationFolderWhenCopying() {
+    ActionCopyMoveResultFilenames action = new ActionCopyMoveResultFilenames();
+    action.setAction(ActionCopyMoveResultFilenames.ActionType.COPY);
+
+    List<String> errors = errors(check(action));
+
+    assertEquals(1, errors.size());
+    assertTrue(errors.getFirst().contains("destinationFolder cannot be null or 
blank"));
+    assertFalse(errors.getFirst().contains("filename"));
+  }
+
+  @Test
+  void checkRequiresDestinationFolderWhenMoving() {
+    ActionCopyMoveResultFilenames action = new ActionCopyMoveResultFilenames();
+    action.setAction(ActionCopyMoveResultFilenames.ActionType.MOVE);
+
+    List<String> errors = errors(check(action));
+
+    assertEquals(1, errors.size());
+    assertTrue(errors.getFirst().contains("destinationFolder cannot be null or 
blank"));
+  }
+
+  @Test
+  void checkAcceptsADestinationFolder() {
+    ActionCopyMoveResultFilenames action = new ActionCopyMoveResultFilenames();
+    action.setAction(ActionCopyMoveResultFilenames.ActionType.COPY);
+    action.setDestinationFolder("/tmp/hop-result");
+
+    List<ICheckResult> remarks = check(action);
+
+    assertTrue(errors(remarks).isEmpty());
+    assertTrue(
+        remarks.stream().anyMatch(remark -> 
remark.getText().contains("destinationFolder is OK")));
+    assertTrue(remarks.stream().noneMatch(remark -> 
remark.getText().contains("filename")));
+  }
+
+  @Test
+  void checkSkipsDestinationFolderWhenDeleting() {
+    ActionCopyMoveResultFilenames action = new ActionCopyMoveResultFilenames();
+    action.setAction(ActionCopyMoveResultFilenames.ActionType.DELETE);
+
+    List<ICheckResult> remarks = check(action);
+
+    assertTrue(remarks.isEmpty());
+  }
+
+  private static List<ICheckResult> check(ActionCopyMoveResultFilenames 
action) {
+    List<ICheckResult> remarks = new ArrayList<>();
+    action.check(remarks, null, action, null);
+    return remarks;
+  }
+
+  private static List<String> errors(List<ICheckResult> remarks) {
+    List<String> errors = new ArrayList<>();
+    for (ICheckResult remark : remarks) {
+      if (remark.getType() == ICheckResult.TYPE_RESULT_ERROR) {
+        errors.add(remark.getText());
+      }
+    }
+    return errors;
+  }
 }
diff --git 
a/plugins/actions/deleteresultfilenames/src/main/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenames.java
 
b/plugins/actions/deleteresultfilenames/src/main/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenames.java
index c9a470880a..23c15187ae 100644
--- 
a/plugins/actions/deleteresultfilenames/src/main/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenames.java
+++ 
b/plugins/actions/deleteresultfilenames/src/main/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenames.java
@@ -36,15 +36,13 @@ import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.ActionBase;
 import org.apache.hop.workflow.action.IAction;
-import org.apache.hop.workflow.action.validator.AbstractFileValidator;
-import org.apache.hop.workflow.action.validator.ActionValidatorUtils;
-import org.apache.hop.workflow.action.validator.AndValidator;
-import org.apache.hop.workflow.action.validator.ValidatorContext;
 
 /**
- * This defines a 'deleteresultfilenames' action. Its main use would be to 
create empty folder that
- * can be used to control the flow in ETL cycles.
+ * This defines a 'delete result filenames' action. Its main use would be to 
create empty folder
+ * that can be used to control the flow in ETL cycles.
  */
+@Getter
+@Setter
 @Action(
     id = "DELETE_RESULT_FILENAMES",
     name = "i18n::ActionDeleteResultFilenames.Name",
@@ -53,8 +51,6 @@ import 
org.apache.hop.workflow.action.validator.ValidatorContext;
     categoryDescription = 
"i18n:org.apache.hop.workflow:ActionCategory.Category.FileManagement",
     keywords = "i18n::ActionDeleteResultFilenames.keyword",
     documentationUrl = "/workflow/actions/deleteresultfilenames.html")
-@Getter
-@Setter
 public class ActionDeleteResultFilenames extends ActionBase implements 
Cloneable, IAction {
   private static final Class<?> PKG = ActionDeleteResultFilenames.class;
 
@@ -156,12 +152,6 @@ public class ActionDeleteResultFilenames extends 
ActionBase implements Cloneable
       WorkflowMeta workflowMeta,
       IVariables variables,
       IHopMetadataProvider metadataProvider) {
-    ValidatorContext ctx = new ValidatorContext();
-    AbstractFileValidator.putVariableSpace(ctx, getVariables());
-    AndValidator.putValidators(
-        ctx,
-        ActionValidatorUtils.notNullValidator(),
-        ActionValidatorUtils.fileDoesNotExistValidator());
-    ActionValidatorUtils.andValidator().validate(this, "filename", remarks, 
ctx);
+    // Names come from the previous result. This action has no path of its own 
to validate.
   }
 }
diff --git 
a/plugins/actions/deleteresultfilenames/src/test/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenamesTest.java
 
b/plugins/actions/deleteresultfilenames/src/test/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenamesTest.java
index 5b1d8ef816..7876b91d5f 100644
--- 
a/plugins/actions/deleteresultfilenames/src/test/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenamesTest.java
+++ 
b/plugins/actions/deleteresultfilenames/src/test/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenamesTest.java
@@ -20,10 +20,15 @@ package 
org.apache.hop.workflow.actions.deleteresultfilenames;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hop.core.ICheckResult;
 import org.apache.hop.workflow.action.ActionSerializationTestUtil;
 import org.junit.jupiter.api.Test;
 
+/** Unit test for {@link ActionDeleteResultFilenames} */
 class ActionDeleteResultFilenamesTest {
+
   @Test
   void testSerializationRoundTrip() throws Exception {
     ActionDeleteResultFilenames action =
@@ -34,4 +39,14 @@ class ActionDeleteResultFilenamesTest {
     assertEquals("wildcard", action.getWildcard());
     assertEquals("exclude", action.getWildcardExclude());
   }
+
+  @Test
+  void checkDoesNotReportAMissingFilename() {
+    ActionDeleteResultFilenames action = new ActionDeleteResultFilenames();
+    List<ICheckResult> remarks = new ArrayList<>();
+
+    action.check(remarks, null, action, null);
+
+    assertTrue(remarks.isEmpty());
+  }
 }

Reply via email to