// Copyright 2020 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use std::env::args; use std::error; use std::fs::File; use std::path::Path; use std::process::Command; // A simple wrapper around a binary to ensure we always create some outputs // Optional outputs are not available in Skylark :( // Syntax: $0 output1 output2 ... -- program [arg1...argn] fn ensure() -> Result> { let index = args().position(|a| a == "--").ok_or("no --")?; let optional_outputs = args().take(index).collect::>(); let exe = args().nth(index + 1).ok_or("no exe")?; let exe_args = args().skip(index + 2).collect::>(); if exe_args.is_empty() { return Err("no exe args".into()); } match Command::new(exe).args(exe_args).status()?.code() { Some(code) => { if code == 0 { for out in optional_outputs { if !Path::new(&out).exists() { let _ = File::create(out)?; } } } Ok(code) } None => Err("process killed".into()), } } fn main() { std::process::exit(match ensure() { Ok(exit_code) => exit_code, Err(e) => { println!("Usage: [optional_output1...optional_outputN] -- program [arg1...argn]"); println!("{:?}", args()); println!("{e:?}"); -1 } }); }