]>
Commit | Line | Data |
---|---|---|
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 | 49 | use std::io::{mod, fs, IoResult}; |
a09ad635 | 50 | use std::io::fs::PathExtensions; |
9f5d9b81 | 51 | |
c2b23512 AC |
52 | use core::Package; |
53 | use util::hex::short_hash; | |
54 | ||
9f5d9b81 AC |
55 | pub 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 | ||
67 | pub struct LayoutProxy<'a> { | |
68 | root: &'a Layout, | |
69 | primary: bool, | |
70 | } | |
71 | ||
72 | impl 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 | ||
146 | impl 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 | ||
155 | impl<'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 | } |