-
Notifications
You must be signed in to change notification settings - Fork 147
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce a pure Swift runfiles library (#1310)
Fixes #890 # Main implementation I followed guidance from @fmeum and based this implementation on the runfiles library of `rules_python` where applicable since this was pointed as the reference implementation. In addition to `rules_python` implementation, this implementation uses a similar mechanism as the C++ implementation for deducing the `RUNFILES_DIR` and `RUNFILES_MANIFEST_FILE` location based on `argv0`. --------- Co-authored-by: Brentley Jones <github@brentleyjones.com> Co-authored-by: Luis Padron <heyluispadron@gmail.com> Co-authored-by: Fabian Meumertzheim <fabian@meumertzhe.im>
- Loading branch information
1 parent
d92bc8b
commit 25ac7f2
Showing
9 changed files
with
979 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
load("//swift:swift.bzl", "swift_binary") | ||
|
||
swift_binary( | ||
name = "runfiles_example", | ||
srcs = ["main.swift"], | ||
data = [ | ||
"data/sample.txt", | ||
], | ||
visibility = ["//visibility:public"], | ||
deps = [ | ||
"//swift/runfiles", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello runfiles |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import BazelRunfiles | ||
|
||
do { | ||
let runfiles = try Runfiles.create() | ||
// Runfiles lookup paths have the form `my_workspace/package/file`. | ||
// Runfiles path lookup may throw. | ||
let fileURL = try runfiles.rlocation("build_bazel_rules_swift/examples/runfiles/data/sample.txt") | ||
print("file: \(fileURL)") | ||
|
||
// Runfiles path lookup may return a non-existent path. | ||
let content = try String(contentsOf: fileURL, encoding: .utf8) | ||
|
||
assert(content == "Hello runfiles") | ||
print(content) | ||
} catch { | ||
print("runfiles error: \(error)") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# 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 = ["@build_bazel_rules_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 | ||
|
||
do { | ||
let runfiles = try Runfiles.create() | ||
let fileURL = try runfiles.rlocation("my_workspace/path/to/my/data.txt") | ||
print("file: \(fileURL)") | ||
} catch { | ||
print("runfiles error: \(error)") | ||
} | ||
``` | ||
|
||
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` (e.g. `argv[0]` the path of the main program). | ||
|
||
If you want to start subprocesses, the runfiles library helps you set the required environment variables for them to find their runfiles: | ||
|
||
```swift | ||
import BazelRunfiles | ||
import Foundation | ||
|
||
do { | ||
|
||
let runfiles = try Runfiles.create() | ||
let executableURL = try runfiles.rlocation("my_workspace/path/to/binary") | ||
|
||
let process = Process() | ||
process.executableURL = executableURL | ||
process.environment = runfiles.envVars() | ||
|
||
do { | ||
// Launch the process | ||
try process.run() | ||
process.waitUntilExit() | ||
} catch { | ||
// ... | ||
} | ||
} catch { | ||
fatalError("runfiles error: \(error)") | ||
} | ||
``` |
Oops, something went wrong.