Skip to content

Commit 526a70a

Browse files
Correctly translate paths to local requirements.txt file in environment dependencies (#2736)
## Changes Correctly translate paths to local requirement.txt file in environment dependencies ## Why At the moment we don't translate paths to requirements.txt files which makes it impossible to reference local path to such files in environment dependencies. This PR fixes this ``` dependencies: - -r ../requirements.txt ``` ## Tests Added acceptance test <!-- If your PR needs to be included in the release notes for next release, add a separate entry in NEXT_CHANGELOG.md as part of your PR. --> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent f5e193e commit 526a70a

12 files changed

Lines changed: 189 additions & 1 deletion

File tree

NEXT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
### CLI
1010

1111
### Bundles
12+
* Correctly translate paths to local requirements.txt file in environment dependencies ([#2736](https://github.com/databricks/cli/pull/2736))
1213
* Check for running resources with --fail-on-active-runs before any mutative operation during deploy ([#2743](https://github.com/databricks/cli/pull/2743))
1314

1415
### API Changes
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
bundle:
2+
name: "dependencies"
3+
4+
5+
resources:
6+
jobs:
7+
test_job:
8+
name: "Test Job"
9+
tasks:
10+
- task_key: "main"
11+
python_wheel_task:
12+
package_name: "test_package"
13+
entry_point: "main"
14+
environment_key: "test_env"
15+
16+
environments:
17+
- environment_key: "test_env"
18+
spec:
19+
client: "1"
20+
dependencies:
21+
- "-r ./requirements.txt"
22+
- "test_package"
23+
- "test_package==2.0.1"
24+
- "test_package>=2.0.1"
25+
- "dist/*.whl"
26+
- "/Workspace/Users/test@databricks.com/test-package.whl"
27+
- "beautifulsoup4>=1.0.0,~=1.2.0,<2.0.0"
28+
- "beautifulsoup4[security, tests] ~= 4.12.3"
29+
- "requests[security] @ https://github.com/psf/requests/archive/refs/heads/main.zip"

acceptance/bundle/environments/dependencies/dist/test.whl

Whitespace-only changes.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
>>> [CLI] bundle validate
3+
Name: dependencies
4+
Target: default
5+
Workspace:
6+
User: [USERNAME]
7+
Path: /Workspace/Users/[USERNAME]/.bundle/dependencies/default
8+
9+
Validation OK!
10+
11+
>>> [CLI] bundle deploy
12+
Uploading dist/test.whl...
13+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dependencies/default/files...
14+
Deploying resources...
15+
Updating deployment state...
16+
Deployment complete!
17+
18+
>>> jq -s .[] | select(.path=="/api/2.2/jobs/create") | .body.environments out.requests.txt
19+
[
20+
{
21+
"environment_key": "test_env",
22+
"spec": {
23+
"client": "1",
24+
"dependencies": [
25+
"-r /Workspace/Users/[USERNAME]/.bundle/dependencies/default/files/requirements.txt",
26+
"test_package",
27+
"test_package==2.0.1",
28+
"test_package>=2.0.1",
29+
"/Workspace/Users/[USERNAME]/.bundle/dependencies/default/artifacts/.internal/test.whl",
30+
"/Workspace/Users/test@databricks.com/test-package.whl",
31+
"beautifulsoup4>=1.0.0,~=1.2.0,<2.0.0",
32+
"beautifulsoup4[security, tests] ~= 4.12.3",
33+
"requests[security] @ https://github.com/psf/requests/archive/refs/heads/main.zip"
34+
]
35+
}
36+
}
37+
]
38+
39+
>>> [CLI] bundle validate -o json
40+
[
41+
"-r /Workspace/Users/[USERNAME]/.bundle/dependencies/default/files/requirements.txt",
42+
"test_package",
43+
"test_package==2.0.1",
44+
"test_package>=2.0.1",
45+
"./dist/*.whl",
46+
"/Workspace/Users/test@databricks.com/test-package.whl",
47+
"beautifulsoup4>=1.0.0,~=1.2.0,<2.0.0",
48+
"beautifulsoup4[security, tests] ~= 4.12.3",
49+
"requests[security] @ https://github.com/psf/requests/archive/refs/heads/main.zip"
50+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Flask==2.0.1
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
trace $CLI bundle validate
5+
6+
trace $CLI bundle deploy
7+
trace jq -s '.[] | select(.path=="/api/2.2/jobs/create") | .body.environments' out.requests.txt
8+
trace $CLI bundle validate -o json | jq '.resources.jobs.test_job.environments[0].spec.dependencies'
9+
rm out.requests.txt
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cloud = false
2+
RecordRequests = true

bundle/config/mutator/paths/job_paths_visitor.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,30 @@ func jobRewritePatterns() []jobRewritePattern {
8585
},
8686
}
8787

88+
jobEnvironmentsWithRequirementsPatterns := []jobRewritePattern{
89+
{
90+
dyn.NewPattern(
91+
dyn.Key("resources"),
92+
dyn.Key("jobs"),
93+
dyn.AnyKey(),
94+
dyn.Key("environments"),
95+
dyn.AnyIndex(),
96+
dyn.Key("spec"),
97+
dyn.Key("dependencies"),
98+
dyn.AnyIndex(),
99+
),
100+
TranslateModeEnvironmentRequirements,
101+
func(s string) bool {
102+
_, ok := libraries.IsLocalRequirementsFile(s)
103+
return !ok
104+
},
105+
},
106+
}
107+
88108
taskPatterns := jobTaskRewritePatterns(base)
89109
forEachPatterns := jobTaskRewritePatterns(base.Append(dyn.Key("for_each_task"), dyn.Key("task")))
90110
allPatterns := append(taskPatterns, jobEnvironmentsPatterns...)
111+
allPatterns = append(allPatterns, jobEnvironmentsWithRequirementsPatterns...)
91112
allPatterns = append(allPatterns, forEachPatterns...)
92113
return allPatterns
93114
}

bundle/config/mutator/paths/translation_mode.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,7 @@ const (
2929
// It a "./" prefix to the path if it does not already have one.
3030
// This allows for disambiguating between paths and PyPI package names.
3131
TranslateModeLocalRelativeWithPrefix
32+
33+
// TranslateModeEnvironmentRequirements translates a local requirements file path to be absolute.
34+
TranslateModeEnvironmentRequirements
3235
)

bundle/config/mutator/translate_paths.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313

1414
"github.com/databricks/cli/bundle/config/mutator/paths"
15+
"github.com/databricks/cli/bundle/libraries"
1516

1617
"github.com/databricks/cli/bundle"
1718
"github.com/databricks/cli/bundle/config"
@@ -91,6 +92,11 @@ func (t *translateContext) rewritePath(
9192
input string,
9293
opts translateOptions,
9394
) (string, error) {
95+
// If the input is a local requirements file, we need to translate it to an absolute path.
96+
if reqPath, ok := libraries.IsLocalRequirementsFile(input); ok {
97+
input = reqPath
98+
}
99+
94100
// We assume absolute paths point to a location in the workspace
95101
if path.IsAbs(input) {
96102
return "", nil
@@ -143,6 +149,10 @@ func (t *translateContext) rewritePath(
143149
interp, err = t.translateLocalRelativePath(ctx, input, localPath, localRelPath)
144150
case paths.TranslateModeLocalRelativeWithPrefix:
145151
interp, err = t.translateLocalRelativeWithPrefixPath(ctx, input, localPath, localRelPath)
152+
case paths.TranslateModeEnvironmentRequirements:
153+
interp, err = t.translateFilePath(ctx, input, localPath, localRelPath)
154+
// Add the -r flag to the path to indicate it's a requirements file used for environment dependencies.
155+
interp = "-r " + interp
146156
default:
147157
return "", fmt.Errorf("unsupported translate mode: %d", opts.Mode)
148158
}

0 commit comments

Comments
 (0)