为什么 homrebrew 公式测试失败并显示 serde_json 错误 "expected value at line 1 column 1"

Why does the homrebrew formula test fail with a serde_json error "expected value at line 1 column 1"

我有一个用 cargo 编译的 rust 库,生成的二进制文件应该捆绑一个包含 json 个文件的文件夹。这些 json 文件由我的程序通过以下方式读取:

let filename = "./fonts/console.json";
let data = read_to_string(Path::new(filename).as_os_str())
    .unwrap_or(format!("Unable to read file \"{}\"", color(filename, Colors::Red)));
serde_json::from_str(&data).unwrap_or_else(|error| {
    panic!(
        "JSON parsing error encountered for: \"{}\"\nError: {}",
        color(filename, Colors::Red),
        color(&format!("{}", error), Colors::Yellow)
    )
})

当我 运行 cargo build --release 我得到一个我 运行 这样的二进制文件:

λ my_thing test


test



并且上面rust代码的代码路径被触发没有任何错误。 我还想补充一点,cargo install mything 也按预期工作。没有让我认为这不是 cargo bundle 编译问题的问题...?!

现在我想在自制软件上发布这个库,所以我写了这个公式:

class Mything < Formula
  desc "Description etc"
  homepage "https://hpomepage.com"
  url "https://github.com/path/to/archive/refs/tags/v3.0.0.tar.gz"
  sha256 "547a8e3059e1543debd8e0f10e9efd05c27d13b0717echs7634e1c4cf49d44cb"
  license "GPL-3.0-or-later"

  depends_on "rust" => :build

  def install
    chdir "rust" do
      system "make"
      system "cargo", "build", "--release", "--bin", "mything"
      bin.install "target/release/mything"
    end
  end

  test do
    print "#{bin}/mything test -f console\n"
    # ^-- I added this for debugging to make 100% sure I'm not getting the binaries mixed up
    assert_match "\n\n\ntest\n\n\n",
      shell_output("#{bin}/mything test -f console")
  end
end

安装这个工作正常但是当我 运行 brew test mything 我得到:

λ brew test mything
==> Testing mything
/opt/homebrew/Cellar/mything/3.0.0/bin/mything test -f console
==> /opt/homebrew/Cellar/mything/3.0.0/bin/mything test -f console
thread 'main' panicked at 'JSON parsing error encountered for: "./fonts/console.json"
Error: expected value at line 1 column 1', src/font.rs:88:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error: mything: failed
An exception occurred within a child process:
  Minitest::Assertion: Expected: 0
  Actual: 101
/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/minitest-5.15.0/lib/minitest/assertions.rb:183:in `assert'
/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/minitest-5.15.0/lib/minitest/assertions.rb:218:in `assert_equal'
/opt/homebrew/Library/Homebrew/formula_assertions.rb:26:in `shell_output'
/opt/homebrew/Library/Taps/homebrew/homebrew-core/Formula/mything.rb:21:in `block in <class:Mything>'
/opt/homebrew/Library/Homebrew/formula.rb:2112:in `block (3 levels) in run_test'
/opt/homebrew/Library/Homebrew/utils.rb:595:in `with_env'
/opt/homebrew/Library/Homebrew/formula.rb:2111:in `block (2 levels) in run_test'
/opt/homebrew/Library/Homebrew/formula.rb:948:in `with_logging'
/opt/homebrew/Library/Homebrew/formula.rb:2110:in `block in run_test'
/opt/homebrew/Library/Homebrew/mktemp.rb:63:in `block in run'
/opt/homebrew/Library/Homebrew/mktemp.rb:63:in `chdir'
/opt/homebrew/Library/Homebrew/mktemp.rb:63:in `run'
/opt/homebrew/Library/Homebrew/formula.rb:2363:in `mktemp'
/opt/homebrew/Library/Homebrew/formula.rb:2104:in `run_test'
/opt/homebrew/Library/Homebrew/test.rb:43:in `block in <main>'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/timeout.rb:93:in `block in timeout'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/timeout.rb:33:in `block in catch'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/timeout.rb:33:in `catch'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/timeout.rb:33:in `catch'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/timeout.rb:108:in `timeout'
/opt/homebrew/Library/Homebrew/test.rb:48:in `<main>'

现在我复制该输出的打印第一行并运行以相同的方式复制它:

λ /opt/homebrew/Cellar/mything/3.0.0/bin/mything test -f console


test


并且有效。这与 brew 在这里测试的二进制文件完全相同。

我知道的不多ruby所以我很有可能把测试弄错了? 我在测试中也尝试这样做:

system bin/"cfonts", "test", "-f", "console"

同样的错误也失败了。

当我 运行 现在那个二进制文件是通过 brew 安装的,在我的 PATH 中它一切正常,这太疯狂了...

λ mything test -f console


test


λ which mything
/opt/homebrew/bin/mything

感谢任何帮助。

问题当然是相对路径只在该文件夹所在的某些目录中有效。 生锈问题 after-all.

所以我在编译时使用include_str宏将json文件的内容包含到二进制文件中:

let font_content = include_str!("../fonts/console.json");

serde_json::from_str(&font_content).unwrap_or_else(|error| {
    panic!(
        "JSON parsing error encountered for: \"{}\"\nError: {}",
        color(filename, Colors::Red),
        color(&format!("{}", error), Colors::Yellow)
    )
})

现在冲泡配方可以正常工作了:

class Mything < Formula
  desc "Description etc"
  homepage "https://hpomepage.com"
  url "https://github.com/path/to/archive/refs/tags/v3.0.0.tar.gz"
  sha256 "547a8e3059e1543debd8e0f10e9efd05c27d13b0717echs7634e1c4cf49d44cb"
  license "GPL-3.0-or-later"

  depends_on "rust" => :build

  def install
    chdir "rust" do
      system "make"
      system "cargo", "build", "--release", "--bin", "mything"
      bin.install "target/release/mything"
    end
  end

  test do
    assert_match "\n\n\ntest\n\n\n",
      shell_output("#{bin}/mything test -f console")
  end
end
λ brew test cfonts
==> Testing cfonts
==> /opt/homebrew/Cellar/mything/3.0.0/bin/mything test -f console