]> git.proxmox.com Git - cargo.git/blame - src/cargo/ops/cargo_rustc/layout.rs
auto merge of #647 : dotdash/cargo/entry, r=alexcrichton
[cargo.git] / src / cargo / ops / cargo_rustc / layout.rs
CommitLineData
9f5d9b81
AC
1//! Management of the directory layout of a build
2//!
3//! The directory layout is a little tricky at times, hence a separate file to
4//! house this logic. The current layout looks like this:
5//!
39f0bd47
AC
6//! ```ignore
7//! # This is the root directory for all output, the top-level package
8//! # places all of its output here.
9//! target/
9f5d9b81 10//!
39f0bd47
AC
11//! # This is the root directory for all output of *dependencies*
12//! deps/
9f5d9b81 13//!
39f0bd47
AC
14//! # This is the location at which the output of all custom build
15//! # commands are rooted
16//! native/
c2b23512 17//!
39f0bd47
AC
18//! # Each package gets its own directory for where its output is
19//! # placed. We can't track exactly what's getting put in here, so
20//! # we just assume that all relevant output is in these
21//! # directories.
22//! $pkg1/
23//! $pkg2/
24//! $pkg3/
c2b23512 25//!
39f0bd47
AC
26//! # Hidden directory that holds all of the fingerprint files for all
27//! # packages
28//! .fingerprint/
79768eb0 29//!
39f0bd47
AC
30//! # This is a temporary directory as part of the build process. When a
31//! # build starts, it initially moves the old `deps` directory to this
32//! # location. This is done to ensure that there are no stale artifacts
33//! # lying around in the build directory which may cause a build to
34//! # succeed where it would fail elsewhere.
35//! #
36//! # If a package is determined to be fresh, its files are moved out of
37//! # this directory and back into `deps`.
38//! old-deps/
9f5d9b81 39//!
39f0bd47
AC
40//! # Similar to old-deps, this is where all of the output under
41//! # `target/` is moved at the start of a build.
42//! old-root/
c2b23512 43//!
39f0bd47
AC
44//! # Same as the two above old directories
45//! old-native/
46//! old-fingerprint/
47//! ```
9f5d9b81 48
1679210e 49use std::io::{mod, fs, IoResult};
a09ad635 50use std::io::fs::PathExtensions;
9f5d9b81 51
c2b23512
AC
52use core::Package;
53use util::hex::short_hash;
54
9f5d9b81
AC
55pub struct Layout {
56 root: Path,
57 deps: Path,
c2b23512 58 native: Path,
79768eb0 59 fingerprint: Path,
9f5d9b81
AC
60
61 old_deps: Path,
62 old_root: Path,
c2b23512 63 old_native: Path,
79768eb0 64 old_fingerprint: Path,
9f5d9b81
AC
65}
66
67pub struct LayoutProxy<'a> {
68 root: &'a Layout,
69 primary: bool,
70}
71
72impl Layout {
73 pub fn new(root: Path) -> Layout {
74 Layout {
75 deps: root.join("deps"),
c2b23512 76 native: root.join("native"),
79768eb0 77 fingerprint: root.join(".fingerprint"),
9f5d9b81
AC
78 old_deps: root.join("old-deps"),
79 old_root: root.join("old-root"),
c2b23512 80 old_native: root.join("old-native"),
79768eb0 81 old_fingerprint: root.join("old-fingerprint"),
9f5d9b81
AC
82 root: root,
83 }
84 }
85
86 pub fn prepare(&mut self) -> IoResult<()> {
87 if !self.root.exists() {
88 try!(fs::mkdir_recursive(&self.root, io::UserRWX));
89 }
90
91 if self.old_deps.exists() {
92 try!(fs::rmdir_recursive(&self.old_deps));
93 }
94 if self.old_root.exists() {
95 try!(fs::rmdir_recursive(&self.old_root));
96 }
c2b23512 97 if self.old_native.exists() {
260ecb5f 98 try!(fs::rmdir_recursive(&self.old_native));
c2b23512 99 }
79768eb0
AC
100 if self.old_fingerprint.exists() {
101 try!(fs::rmdir_recursive(&self.old_fingerprint));
102 }
9f5d9b81
AC
103 if self.deps.exists() {
104 try!(fs::rename(&self.deps, &self.old_deps));
105 }
c2b23512
AC
106 if self.native.exists() {
107 try!(fs::rename(&self.native, &self.old_native));
108 }
79768eb0
AC
109 if self.fingerprint.exists() {
110 try!(fs::rename(&self.fingerprint, &self.old_fingerprint));
111 }
9f5d9b81
AC
112
113 try!(fs::mkdir(&self.deps, io::UserRWX));
c2b23512 114 try!(fs::mkdir(&self.native, io::UserRWX));
79768eb0 115 try!(fs::mkdir(&self.fingerprint, io::UserRWX));
9f5d9b81
AC
116 try!(fs::mkdir(&self.old_root, io::UserRWX));
117
118 for file in try!(fs::readdir(&self.root)).iter() {
119 if !file.is_file() { continue }
120
121 try!(fs::rename(file, &self.old_root.join(file.filename().unwrap())));
122 }
123
124 Ok(())
125 }
126
127 pub fn dest<'a>(&'a self) -> &'a Path { &self.root }
128 pub fn deps<'a>(&'a self) -> &'a Path { &self.deps }
c2b23512
AC
129 pub fn native(&self, package: &Package) -> Path {
130 self.native.join(self.native_name(package))
131 }
79768eb0 132 pub fn fingerprint(&self) -> &Path { &self.fingerprint }
c2b23512 133
9f5d9b81
AC
134 pub fn old_dest<'a>(&'a self) -> &'a Path { &self.old_root }
135 pub fn old_deps<'a>(&'a self) -> &'a Path { &self.old_deps }
c2b23512
AC
136 pub fn old_native(&self, package: &Package) -> Path {
137 self.old_native.join(self.native_name(package))
138 }
79768eb0 139 pub fn old_fingerprint(&self) -> &Path { &self.old_fingerprint }
c2b23512
AC
140
141 fn native_name(&self, pkg: &Package) -> String {
142 format!("{}-{}", pkg.get_name(), short_hash(pkg.get_package_id()))
143 }
9f5d9b81
AC
144}
145
146impl Drop for Layout {
147 fn drop(&mut self) {
148 let _ = fs::rmdir_recursive(&self.old_deps);
149 let _ = fs::rmdir_recursive(&self.old_root);
c2b23512 150 let _ = fs::rmdir_recursive(&self.old_native);
79768eb0 151 let _ = fs::rmdir_recursive(&self.old_fingerprint);
9f5d9b81
AC
152 }
153}
154
155impl<'a> LayoutProxy<'a> {
156 pub fn new(root: &'a Layout, primary: bool) -> LayoutProxy<'a> {
157 LayoutProxy {
158 root: root,
159 primary: primary,
160 }
161 }
162
163 pub fn root(&self) -> &'a Path {
164 if self.primary {self.root.dest()} else {self.root.deps()}
165 }
166 pub fn deps(&self) -> &'a Path { self.root.deps() }
167
c2b23512
AC
168 pub fn native(&self, pkg: &Package) -> Path { self.root.native(pkg) }
169
9f5d9b81
AC
170 pub fn old_root(&self) -> &'a Path {
171 if self.primary {self.root.old_dest()} else {self.root.old_deps()}
172 }
c2b23512
AC
173
174 pub fn old_native(&self, pkg: &Package) -> Path {
175 self.root.old_native(pkg)
176 }
3f110840
AC
177
178 pub fn proxy(&self) -> &'a Layout { self.root }
9f5d9b81 179}