]> git.proxmox.com Git - cargo.git/blame - src/cargo/ops/cargo_compile.rs
Progress towards compiling with dependencies
[cargo.git] / src / cargo / ops / cargo_compile.rs
CommitLineData
62bff631
C
1/**
2 * Cargo compile currently does the following steps:
3 *
4 * All configurations are already injected as environment variables via the main cargo command
5 *
6 * 1. Read the manifest
7 * 2. Shell out to `cargo-resolve` with a list of dependencies and sources as stdin
8 * a. Shell out to `--do update` and `--do list` for each source
9 * b. Resolve dependencies and return a list of name/version/source
10 * 3. Shell out to `--do download` for each source
11 * 4. Shell out to `--do get` for each source, and build up the list of paths to pass to rustc -L
12 * 5. Call `cargo-rustc` with the results of the resolver zipped together with the results of the `get`
13 * a. Topologically sort the dependencies
14 * b. Compile each dependency in order, passing in the -L's pointing at each previously compiled dependency
15 */
16
17use std;
18use std::vec::Vec;
19use serialize::{Decodable};
20use hammer::{FlagDecoder,FlagConfig,FlagConfiguration,HammerError};
21use std::io;
22use std::io::BufReader;
23use std::io::process::{Process,ProcessExit,ProcessOutput,InheritFd,ProcessConfig};
04b91119
YK
24use std::os;
25use util::config;
26use util::config::{all_configs,ConfigValue};
27use cargo_read_manifest = ops::cargo_read_manifest::read_manifest;
28use core::Package;
21598204
YK
29use core::source::Source;
30use sources::path::PathSource;
04b91119 31use {CargoError,ToCargoError,CargoResult};
62bff631
C
32
33#[deriving(Decodable)]
34struct Options {
35 manifest_path: ~str
36}
37
38impl FlagConfig for Options {
39 fn config(_: Option<Options>, c: FlagConfiguration) -> FlagConfiguration { c }
40}
41
42pub fn compile() -> CargoResult<()> {
43 let options = try!(flags::<Options>());
6b447648 44 let manifest_bytes = try!(read_manifest(options.manifest_path));
62bff631 45
04b91119
YK
46 let configs = try!(all_configs(os::getcwd()));
47 let config_paths = configs.find(&~"paths").map(|v| v.clone()).unwrap_or_else(|| ConfigValue::new());
48
49 let paths = match config_paths.get_value() {
50 &config::String(_) => return Err(CargoError::new(~"The path was configured as a String instead of a List", 1)),
21598204 51 &config::List(ref list) => list.iter().map(|path| Path::new(path.as_slice())).collect()
04b91119
YK
52 };
53
21598204
YK
54 let source = PathSource::new(paths);
55 let names = try!(source.list());
56 try!(source.download(names.as_slice()));
57 let packages = try!(source.get(names));
04b91119 58
04b91119
YK
59 Ok(())
60 //call_rustc(~BufReader::new(manifest_bytes.as_slice()))
62bff631
C
61}
62
63fn flags<T: FlagConfig + Decodable<FlagDecoder, HammerError>>() -> CargoResult<T> {
64 let mut decoder = FlagDecoder::new::<T>(std::os::args().tail());
65 Decodable::decode(&mut decoder).to_cargo_error(|e: HammerError| e.message, 1)
66}
67
68fn read_manifest(manifest_path: &str) -> CargoResult<Vec<u8>> {
69 Ok((try!(exec_with_output("cargo-read-manifest", [~"--manifest-path", manifest_path.to_owned()], None))).output)
70}
71
72fn call_rustc(mut manifest_data: ~Reader:) -> CargoResult<()> {
73 let data: &mut Reader = manifest_data;
74 try!(exec_tty("cargo-rustc", [], Some(data)));
75 Ok(())
76}
77
78fn exec_with_output(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult<ProcessOutput> {
79 Ok((try!(exec(program, args, input, |_| {}))).wait_with_output())
80}
81
82fn exec_tty(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult<ProcessExit> {
83 Ok((try!(exec(program, args, input, |config| {
84 config.stdout = InheritFd(1);
85 config.stderr = InheritFd(2);
86 }))).wait())
87}
88
89fn exec(program: &str, args: &[~str], input: Option<&mut Reader>, configurator: |&mut ProcessConfig|) -> CargoResult<Process> {
90 let mut config = ProcessConfig::new();
91 config.program = program;
92 config.args = args;
93 configurator(&mut config);
94
95 println!("Executing {} {}", program, args);
96
6b447648 97 let mut process = try!(Process::configure(config).to_cargo_error(|e: io::IoError| format!("Could not configure process: {}", e), 1));
62bff631
C
98
99 input.map(|mut reader| io::util::copy(&mut reader, process.stdin.get_mut_ref()));
100
101 Ok(process)
102}
103