blob: 59eba1b944e9013d2573a230f01f325febd12667 [file] [log] [blame]
Brian Silvermancc09f182022-03-09 15:40:20 -08001// Copyright 2020 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::env::args;
16use std::error;
17use std::fs::File;
18use std::path::Path;
19use std::process::Command;
20
21// A simple wrapper around a binary to ensure we always create some outputs
22// Optional outputs are not available in Skylark :(
23// Syntax: $0 output1 output2 ... -- program [arg1...argn]
24fn ensure() -> Result<i32, Box<dyn error::Error>> {
25 let index = args().position(|a| a == "--").ok_or("no --")?;
26 let optional_outputs = args().take(index).collect::<Vec<String>>();
27 let exe = args().nth(index + 1).ok_or("no exe")?;
28 let exe_args = args().skip(index + 2).collect::<Vec<String>>();
29 if exe_args.is_empty() {
30 return Err("no exe args".into());
31 }
32 match Command::new(exe).args(exe_args).status()?.code() {
33 Some(code) => {
34 if code == 0 {
35 for out in optional_outputs {
36 if !Path::new(&out).exists() {
37 let _ = File::create(out)?;
38 }
39 }
40 }
41 Ok(code)
42 }
43 None => Err("process killed".into()),
44 }
45}
46
47fn main() {
48 std::process::exit(match ensure() {
49 Ok(exit_code) => exit_code,
50 Err(e) => {
51 println!("Usage: [optional_output1...optional_outputN] -- program [arg1...argn]");
52 println!("{:?}", args());
53 println!("{:?}", e);
54 -1
55 }
56 });
57}