Repository: apache/camel-k
Pull request #3269 (2022-05-13 10:12:30)

Fix: support absolute paths on Windows
<!-- Description -->

Found this while working on #3257 

Thanks !



<!--
Enter your extended release note in the below block. If the PR requires
additional action from users switching to the new release, include the string
"action required". If no release note is required, write "NONE". 

You can (optionally) mark this PR with labels "kind/bug" or "kind/feature" to make sure
the text is added to the right section of the release notes. 
-->

**Release Note**
```release-note
NONE
```


oscerd: Needs to be backported to 1.9.x too.

Patch:
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 94e9b15f7..3c560f8c9 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -801,12 +801,7 @@ func resolvePodTemplate(ctx context.Context, cmd *cobra.Command, templateSrc str
 
 func (o *runCmdOptions) uploadFileOrDirectory(platform *v1.IntegrationPlatform, item string, integrationName string, cmd *cobra.Command, integration *v1.Integration) error {
 	path := strings.TrimPrefix(item, "file://")
-	localPath := path
-	targetPath := ""
-	if i := strings.Index(path, ":"); i > 0 {
-		targetPath = path[i+1:]
-		localPath = path[:i]
-	}
+	localPath, targetPath := getPaths(path, runtimeos.GOOS, filepath.IsAbs(path))
 	options := o.getSpectrumOptions(platform, cmd)
 	dirName, err := getDirName(localPath)
 	if err != nil {
@@ -852,6 +847,23 @@ func (o *runCmdOptions) uploadFileOrDirectory(platform *v1.IntegrationPlatform,
 	})
 }
 
+func getPaths(path string, os string, isAbs bool) (localPath string, targetPath string) {
+	localPath = path
+	targetPath = ""
+	parts := strings.Split(path, ":")
+	if len(parts) > 1 {
+		if os != "windows" || !isAbs {
+			localPath = parts[0]
+			targetPath = parts[1]
+		} else if isAbs && len(parts) == 3 {
+			// special case on Windows for absolute paths e.g C:\foo\bar\test.csv:remote/path
+			localPath = fmt.Sprintf("%s:%s", parts[0], parts[1])
+			targetPath = parts[2]
+		}
+	}
+	return localPath, targetPath
+}
+
 func getMountPath(targetPath string, dirName string, path string) (string, error) {
 	// if the target path is a file then use that as the exact mount path
 	if filepath.Ext(targetPath) != "" {


Test patch:
diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go
index be71a8425..46c032bc0 100644
--- a/pkg/cmd/run_test.go
+++ b/pkg/cmd/run_test.go
@@ -677,3 +677,69 @@ func TestMissingTrait(t *testing.T) {
 	assert.Equal(t, "Error: bogus.fail=i-must-fail is not a valid trait property\n", output)
 	assert.NotNil(t, err)
 }
+
+func TestGetsPaths(t *testing.T) {
+	tests := []struct {
+		path       string
+		localPath  string
+		remotePath string
+		os         string
+		isAbs      bool
+	}{
+		{
+			path:       "C:\\USER\\HOME\\:remote/path",
+			localPath:  "C:\\USER\\HOME\\",
+			remotePath: "remote/path",
+			os:         "windows",
+			isAbs:      true,
+		},
+		{
+			path:       "src\\main\\resources:remote/path",
+			localPath:  "src\\main\\resources",
+			remotePath: "remote/path",
+			os:         "windows",
+		},
+		{
+			path:       "C:\\USER\\HOME\\",
+			localPath:  "C:\\USER\\HOME\\",
+			remotePath: "",
+			os:         "windows",
+			isAbs:      true,
+		},
+		{
+			path:       "src\\main\\resources",
+			localPath:  "src\\main\\resources",
+			remotePath: "",
+			os:         "windows",
+		},
+		{
+			path:       "/home/user/name/dir:/remote/path",
+			localPath:  "/home/user/name/dir",
+			remotePath: "/remote/path",
+			os:         "linux",
+			isAbs:      true,
+		}, {
+			path:       "/home/user/name/dir",
+			localPath:  "/home/user/name/dir",
+			remotePath: "",
+			os:         "linux",
+			isAbs:      true,
+		}, {
+			path:       "src/main/resources:remote/path",
+			localPath:  "src/main/resources",
+			remotePath: "remote/path",
+			os:         "linux",
+		}, {
+			path:       "src/main/resources",
+			localPath:  "src/main/resources",
+			remotePath: "",
+			os:         "linux",
+		},
+	}
+	for _, test := range tests {
+		localPath, targetPath := getPaths(test.path, test.os, test.isAbs)
+		assert.Equal(t, test.localPath, localPath)
+		assert.Equal(t, test.remotePath, targetPath)
+
+	}
+}