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

Introduce a pure Swift runfiles library #1310

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4649c25
first commit
cerisier Sep 12, 2024
d8df061
workspace_name and not name
cerisier Sep 13, 2024
9aca5fd
specify internal accessibility for constant enum
cerisier Sep 13, 2024
19ad987
api fixes
cerisier Sep 17, 2024
647bab2
add tests
cerisier Sep 17, 2024
862e263
mutualize runfiles bzl
cerisier Sep 17, 2024
25dc904
add examples
cerisier Sep 17, 2024
0933c66
remove print
cerisier Sep 17, 2024
df79d83
add runfiles includes to swift-binary
cerisier Sep 17, 2024
ad99a68
Add documentation
cerisier Sep 17, 2024
d8b2ff7
add todo
cerisier Sep 17, 2024
7c102f8
add proper throwable error enums
cerisier Sep 17, 2024
6b269e4
format
cerisier Sep 18, 2024
189a8fc
URL(filePath: does not exist in foundation for Linux
cerisier Sep 18, 2024
589c964
Remove false test: argv0 is xctest without runfiles on macos but not …
cerisier Sep 18, 2024
ca0cd32
buildifier
cerisier Sep 18, 2024
6c7f993
trigger
cerisier Sep 18, 2024
030563f
Merge remote-tracking branch 'origin/master' into runfiles_library
cerisier Sep 24, 2024
7383bb8
remove runfiles walk up the path discovery
cerisier Sep 25, 2024
480e57c
fix wrong error name
cerisier Sep 25, 2024
04751c6
missing new line at end of file
cerisier Sep 27, 2024
dfd1810
Merge remote-tracking branch 'origin/master' into runfiles_library
cerisier Oct 21, 2024
8cacd1b
Merge remote-tracking branch 'origin/master' into runfiles_library
cerisier Dec 21, 2024
c16937f
Merge remote-tracking branch 'origin/master' into runfiles_library
cerisier Dec 30, 2024
5e19b04
Deduce the source repository from #filePath
cerisier Dec 30, 2024
b5fae40
Implement runfiles directory detection from argv0
cerisier Jan 3, 2025
39b8dfe
Update example
cerisier Jan 3, 2025
0c5ce1e
fix tests
cerisier Jan 4, 2025
9b426cf
Test runfiles path computation
cerisier Jan 4, 2025
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
13 changes: 13 additions & 0 deletions examples/runfiles/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
load("//swift:swift.bzl", "swift_binary")

swift_binary(
name = "binary",
srcs = ["main.swift"],
data = [
"data/sample.txt",
],
visibility = ["//visibility:public"],
deps = [
"//swift/runfiles",
],
)
1 change: 1 addition & 0 deletions examples/runfiles/data/sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello runfiles
17 changes: 17 additions & 0 deletions examples/runfiles/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import BazelRunfiles

let runfiles = try Runfiles.create()

// Runfiles lookup paths have the form `my_workspace/package/file`.
// Runfiles path lookup may return nil.
guard let runFile = runfiles.rlocation("build_bazel_rules_swift/examples/runfiles/data/sample.txt") else {
fatalError("couldn't resolve runfile")
}

print(runFile)

// Runfiles path lookup may return a non-existent path.
let content = try String(contentsOf: runFile, encoding: .utf8)

assert(content == "Hello runfiles")
print(content)
6 changes: 6 additions & 0 deletions swift/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ bzl_library(
],
)

bzl_library(
name = "runfiles",
srcs = ["runfiles.bzl"],
visibility = ["//swift:__subpackages__"],
)

bzl_library(
name = "swift_autoconfiguration",
srcs = ["swift_autoconfiguration.bzl"],
Expand Down
10 changes: 10 additions & 0 deletions swift/runfiles/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
load("//swift:swift_library.bzl", "swift_library")

swift_library(
name = "runfiles",
srcs = [
"Runfiles.swift",
],
module_name = "BazelRunfiles",
visibility = ["//visibility:public"],
)
74 changes: 74 additions & 0 deletions swift/runfiles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Swift BazelRunfiles library

This is a Bazel Runfiles lookup library for Bazel-built Swift binaries and tests.

Learn about runfiles: read [Runfiles guide](https://bazel.build/extending/rules#runfiles)
or watch [Fabian's BazelCon talk](https://www.youtube.com/watch?v=5NbgUMH1OGo).

## Usage

1. Depend on this runfiles library from your build rule:

```python
swift_binary(
name = "my_binary",
...
data = ["//path/to/my/data.txt"],
deps = ["@bazel_swift//swift/runfiles"],
)
```

2. Include the runfiles library:

```swift
import BazelRunfiles
```

3. Create a Runfiles instance and use `rlocation` to look up runfile urls:

```swift
import BazelRunfiles

let runfiles = try? Runfiles.create(sourceRepository: BazelRunfilesConstants.currentRepository)

let fileURL = runfiles?.rlocation("my_workspace/path/to/my/data.txt")
```

> The code above creates a manifest- or directory-based implementation based on
the environment variables in `Process.processInfo.environment`.
See `Runfiles.create()` for more info.

> The Runfiles.create function uses the runfiles manifest and the runfiles
directory from the RUNFILES_MANIFEST_FILE and RUNFILES_DIR environment
variables. If not present, the function looks for the manifest and directory
near CommandLine.arguments.first (argv[0]), the path of the main program.

> The BazelRunfilesConstants.currentRepository symbol is available in every
target that depends on the runfiles library.

If you want to start subprocesses, and the subprocess can't automatically
cerisier marked this conversation as resolved.
Show resolved Hide resolved
find the correct runfiles directory, you can explicitly set the right
environment variables for them:

```swift
import Foundation
import BazelRunfiles

let runfiles = try? Runfiles.create(sourceRepository: BazelRunfilesConstant.currentRepository)

guard let executableURL = runfiles.rlocation("my_workspace/path/to/binary") else {
return
}

let process = Process()
process.executableURL = executableURL
process.environment = runfiles.envVars()

do {
// Launch the process
try process.run()
process.waitUntilExit()
} catch {
// ...
}
```
Loading