Skip to content

Commit f939663

Browse files
authored
Merge pull request #6 from spennydl/patch-api
API to allow applying patches to crates
2 parents fa1480b + 2e0eaee commit f939663

File tree

6 files changed

+222
-25
lines changed

6 files changed

+222
-25
lines changed

examples/docs-builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn main() -> Result<(), Box<dyn Error>> {
2626
.enable_networking(false);
2727

2828
let mut build_dir = workspace.build_dir("docs");
29-
build_dir.build(&toolchain, &krate, sandbox, |build| {
29+
build_dir.build(&toolchain, &krate, sandbox).run(|build| {
3030
build.cargo().args(&["doc", "--no-deps"]).run()?;
3131
Ok(())
3232
})?;

src/build.rs

Lines changed: 99 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ use crate::{Crate, Toolchain, Workspace};
44
use failure::Error;
55
use remove_dir_all::remove_dir_all;
66
use std::path::PathBuf;
7+
use std::vec::Vec;
8+
9+
#[derive(Clone)]
10+
pub(crate) struct CratePatch {
11+
pub(crate) name: String,
12+
pub(crate) uri: String,
13+
pub(crate) branch: String,
14+
}
715

816
/// Directory in the [`Workspace`](struct.Workspace.html) where builds can be executed.
917
///
@@ -15,12 +23,44 @@ pub struct BuildDirectory {
1523
name: String,
1624
}
1725

18-
impl BuildDirectory {
19-
pub(crate) fn new(workspace: Workspace, name: &str) -> Self {
20-
Self {
21-
workspace,
26+
/// Builder for configuring builds in a [`BuildDirectory`](struct.BuildDirectory.html).
27+
pub struct BuildBuilder<'a> {
28+
build_dir: &'a mut BuildDirectory,
29+
toolchain: &'a Toolchain,
30+
krate: &'a Crate,
31+
sandbox: SandboxBuilder,
32+
patches: Vec<CratePatch>,
33+
}
34+
35+
impl<'a> BuildBuilder<'a> {
36+
/// Add a patch to this build.
37+
/// Patches get added to the crate's Cargo.toml in the `patch.crates-io` table.
38+
/// # Example
39+
///
40+
/// ```no_run
41+
/// # use rustwide::{WorkspaceBuilder, Toolchain, Crate, cmd::SandboxBuilder};
42+
/// # use std::error::Error;
43+
/// # fn main() -> Result<(), Box<dyn Error>> {
44+
/// # let workspace = WorkspaceBuilder::new("".as_ref(), "").init()?;
45+
/// # let toolchain = Toolchain::Dist { name: "".into() };
46+
/// # let krate = Crate::local("".as_ref());
47+
/// # let sandbox = SandboxBuilder::new();
48+
/// let mut build_dir = workspace.build_dir("foo");
49+
/// build_dir.build(&toolchain, &krate, sandbox)
50+
/// .patch_with_git("bar", "https://github.com/foo/bar", "baz")
51+
/// .run(|build| {
52+
/// build.cargo().args(&["test", "--all"]).run()?;
53+
/// Ok(())
54+
/// })?;
55+
/// # Ok(())
56+
/// # }
57+
pub fn patch_with_git(mut self, name: &str, uri: &str, branch: &str) -> Self {
58+
self.patches.push(CratePatch {
2259
name: name.into(),
23-
}
60+
uri: uri.into(),
61+
branch: branch.into(),
62+
});
63+
self
2464
}
2565

2666
/// Run a sandboxed build of the provided crate with the provided toolchain. The closure will
@@ -29,6 +69,39 @@ impl BuildDirectory {
2969
///
3070
/// All the state will be kept on disk as long as the closure doesn't exit: after that things
3171
/// might be removed.
72+
/// # Example
73+
///
74+
/// ```no_run
75+
/// # use rustwide::{WorkspaceBuilder, Toolchain, Crate, cmd::SandboxBuilder};
76+
/// # use std::error::Error;
77+
/// # fn main() -> Result<(), Box<dyn Error>> {
78+
/// # let workspace = WorkspaceBuilder::new("".as_ref(), "").init()?;
79+
/// # let toolchain = Toolchain::Dist { name: "".into() };
80+
/// # let krate = Crate::local("".as_ref());
81+
/// # let sandbox = SandboxBuilder::new();
82+
/// let mut build_dir = workspace.build_dir("foo");
83+
/// build_dir.build(&toolchain, &krate, sandbox).run(|build| {
84+
/// build.cargo().args(&["test", "--all"]).run()?;
85+
/// Ok(())
86+
/// })?;
87+
/// # Ok(())
88+
/// # }
89+
pub fn run<R, F: FnOnce(&Build) -> Result<R, Error>>(self, f: F) -> Result<R, Error> {
90+
self.build_dir
91+
.run(self.toolchain, self.krate, self.sandbox, self.patches, f)
92+
}
93+
}
94+
95+
impl BuildDirectory {
96+
pub(crate) fn new(workspace: Workspace, name: &str) -> Self {
97+
Self {
98+
workspace,
99+
name: name.into(),
100+
}
101+
}
102+
103+
/// Create a build in this build directory. Returns a builder that can be used
104+
/// to configure the build and run it.
32105
///
33106
/// # Example
34107
///
@@ -41,26 +114,42 @@ impl BuildDirectory {
41114
/// # let krate = Crate::local("".as_ref());
42115
/// # let sandbox = SandboxBuilder::new();
43116
/// let mut build_dir = workspace.build_dir("foo");
44-
/// build_dir.build(&toolchain, &krate, sandbox, |build| {
117+
/// build_dir.build(&toolchain, &krate, sandbox).run(|build| {
45118
/// build.cargo().args(&["test", "--all"]).run()?;
46119
/// Ok(())
47120
/// })?;
48121
/// # Ok(())
49122
/// # }
50123
/// ```
51-
pub fn build<R, F: FnOnce(&Build) -> Result<R, Error>>(
124+
pub fn build<'a>(
125+
&'a mut self,
126+
toolchain: &'a Toolchain,
127+
krate: &'a Crate,
128+
sandbox: SandboxBuilder,
129+
) -> BuildBuilder {
130+
BuildBuilder {
131+
build_dir: self,
132+
toolchain,
133+
krate,
134+
sandbox,
135+
patches: Vec::new(),
136+
}
137+
}
138+
139+
pub(crate) fn run<R, F: FnOnce(&Build) -> Result<R, Error>>(
52140
&mut self,
53141
toolchain: &Toolchain,
54142
krate: &Crate,
55143
sandbox: SandboxBuilder,
144+
patches: Vec<CratePatch>,
56145
f: F,
57146
) -> Result<R, Error> {
58147
let source_dir = self.source_dir();
59148
if source_dir.exists() {
60149
remove_dir_all(&source_dir)?;
61150
}
62151

63-
let mut prepare = Prepare::new(&self.workspace, toolchain, krate, &source_dir);
152+
let mut prepare = Prepare::new(&self.workspace, toolchain, krate, &source_dir, patches);
64153
prepare.prepare()?;
65154

66155
std::fs::create_dir_all(self.target_dir())?;
@@ -123,7 +212,7 @@ impl Build<'_> {
123212
/// # let krate = Crate::local("".as_ref());
124213
/// # let sandbox = SandboxBuilder::new();
125214
/// let mut build_dir = workspace.build_dir("foo");
126-
/// build_dir.build(&toolchain, &krate, sandbox, |build| {
215+
/// build_dir.build(&toolchain, &krate, sandbox).run(|build| {
127216
/// build.cmd("rustfmt").args(&["--check", "src/main.rs"]).run()?;
128217
/// Ok(())
129218
/// })?;
@@ -160,7 +249,7 @@ impl Build<'_> {
160249
/// # let krate = Crate::local("".as_ref());
161250
/// # let sandbox = SandboxBuilder::new();
162251
/// let mut build_dir = workspace.build_dir("foo");
163-
/// build_dir.build(&toolchain, &krate, sandbox, |build| {
252+
/// build_dir.build(&toolchain, &krate, sandbox).run(|build| {
164253
/// build.cargo().args(&["test", "--all"]).run()?;
165254
/// Ok(())
166255
/// })?;

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ mod tools;
2929
mod utils;
3030
mod workspace;
3131

32-
pub use crate::build::{Build, BuildDirectory};
32+
pub use crate::build::{Build, BuildBuilder, BuildDirectory};
3333
pub use crate::crates::Crate;
3434
pub use crate::prepare::PrepareError;
3535
pub use crate::toolchain::Toolchain;

0 commit comments

Comments
 (0)