【问题标题】:bazel, python rules, created files how to get thembazel,python 规则,创建的文件如何获取它们
【发布时间】:2021-08-17 12:19:44
【问题描述】:

如何访问我的 python 正在创建的文件?
所以在python里面我得到了类似的东西:

from pathlib import Path
p = Path('my_file.txt')
p.write_text('testing')
print("Testing done")

然后,当我执行bazel run my_file 时,我可以在终端文本中看到一切顺利以及打印信息,但是当我试图找到 my_file.txt 时,什么也没有。那么我需要对我的规则做些什么才能在 bazel 运行完成后访问该文件?

【问题讨论】:

  • 在程序的顶部放置import os。将您的 print() 呼叫更改为 print("Testing done in", os.getcwd())。然后在呼叫显示给您的文件夹中查找您的文件。我认为您正在寻找不存在的文件。
  • @BoarGules 像预期的那样,它在 bazel cashe 文件夹中,脚本完成后会被清除,更改 cwd 对我来说不是一个选项 :)
  • 然后放一个显式路径,比如r'c:\path\to\my_file.txt'。如果文件必须在 bazel 文件夹中,则将其写出两次,每个位置一次。
  • 我无法访问任何其他路径,因为它位于 docker 内,所以我无法访问我的工作区 :( 这就是为什么不能为 /workspace 更改 cwd 的原因

标签: python bazel bazel-rules


【解决方案1】:

如果您能提供更多详细信息可能会有所帮助:

  1. python 代码是如何运行的?它是作为一个动作运行的吗?
  2. my_file 目标是什么?
  3. 你提到你有一些规则。这些 Starlark 规则是你写的吗?

但要直接回答:当使用bazel run 运行二进制文件时,它会在包含二进制文件所有依赖项的符号链接的“运行文件树”中执行。所以你的文件将被放在二进制文件的 runfiles 目录中。

my_program.py:

import os
from pathlib import Path

print("current working directory: " + os.getcwd())

p = Path('my_file.txt')
p.write_text('testing')
print("Testing done")

BUILD:

py_binary(
  name = "my_program",
  srcs = ["my_program.py"],
)
$ bazel run my_program
INFO: Analyzed target //:my_program (18 packages loaded, 90 targets configured).
INFO: Found 1 target...
Target //:my_program up-to-date:
  bazel-bin/my_program
INFO: Elapsed time: 0.226s, Critical Path: 0.01s
INFO: 5 processes: 5 internal.
INFO: Build completed successfully, 5 total actions
INFO: Build completed successfully, 5 total actions
current working directory: /home/ahumesky/.cache/bazel/_bazel_ahumesky/5123c9882cdbb6c5e34f583431173549/execroot/__main__/bazel-out/k8-fastbuild/bin/my_program.runfiles/__main__
Testing done

$ ls /home/ahumesky/.cache/bazel/_bazel_ahumesky/5123c9882cdbb6c5e34f583431173549/execroot/__main__/bazel-out/k8-fastbuild/bin/my_program.runfiles/__main__
external  my_file.txt  my_program  my_program.py

$ cat /home/ahumesky/.cache/bazel/_bazel_ahumesky/5123c9882cdbb6c5e34f583431173549/execroot/__main__/bazel-out/k8-fastbuild/bin/my_program.runfiles/__main__/my_file.txt 
testing

如果可能,最好将输出文件路径作为参数传递给程序,以便文件位于某个已知位置:

import sys
from pathlib import Path

p = Path(sys.argv[1])
p.write_text('testing')
print("Testing done")

$ bazel run my_program -- /tmp/output.txt
INFO: Analyzed target //:my_program (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //:my_program up-to-date:
  bazel-bin/my_program
INFO: Elapsed time: 0.040s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Build completed successfully, 1 total action
Testing done

$ cat /tmp/output.txt
testing

或者,如果你直接运行程序,那么文件将在当前工作目录中:

$ bazel build my_program
INFO: Analyzed target //:my_program (18 packages loaded, 90 targets configured).
INFO: Found 1 target...
Target //:my_program up-to-date:
  bazel-bin/my_program
INFO: Elapsed time: 0.219s, Critical Path: 0.01s
INFO: 5 processes: 5 internal.
INFO: Build completed successfully, 5 total actions

$ bazel-bin/my_program
current working directory: /home/ahumesky/test
Testing done

$ cat my_file.txt
testing

【讨论】:

    【解决方案2】:

    script:你可以使用BUILD_WORKING_DIRECTORY env 变量在工作目录中创建文件路径

    【讨论】:

      【解决方案3】:

      write_text() 返回写入文本文件的字符数,也许你可以检查一下。或者,试试print(p.read_text())

      【讨论】:

      • 它在 bazel 的缓存中,所以不是这样 ;)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      相关资源
      最近更新 更多