Skip to content

Commit 23b187e

Browse files
committed
adding current state
1 parent aff288f commit 23b187e

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/cli.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ pub struct PackageSelectOptions {
6161
/// regardless, set this flag.
6262
#[structopt(long = "ignore-publish")]
6363
ignore_publish: bool,
64+
/// Automatically detect the packages, which changed compared to the given git commit.
65+
///
66+
/// Compares the current git `head` to the reference given, identifies which files changed
67+
/// and attempts to identify the packages and its dependents through that mechanism. You
68+
/// can use any `tag`, `branch` or `commit`, but you must be sure it is available
69+
/// (and up to date) locally.
70+
#[structopt(short = "c", long="changed-since")]
71+
pub changed_since: String,
6472
}
6573

6674
#[derive(StructOpt, Debug)]
@@ -348,6 +356,7 @@ fn make_pkg_predicate(args: PackageSelectOptions) -> Result<Box<dyn Fn(&Package)
348356
skip,
349357
ignore_pre_version,
350358
ignore_publish,
359+
changed_since,
351360
} = args;
352361

353362
if !packages.is_empty() {
@@ -357,8 +366,24 @@ fn make_pkg_predicate(args: PackageSelectOptions) -> Result<Box<dyn Fn(&Package)
357366
.into(),
358367
);
359368
}
369+
if changed_since.len() != 0 {
370+
return Err(
371+
"-p/--packages is mutually exlusive to using -c/--changed-since"
372+
.into(),
373+
);
374+
}
360375
}
361376

377+
if changed_since.len() != 0 {
378+
if !skip.is_empty() || !ignore_pre_version.is_empty() {
379+
return Err(
380+
"-c/--changed-since is mutually exlusive to using -s/--skip and -i/--ignore-version-pre"
381+
.into(),
382+
);
383+
}
384+
}
385+
386+
362387
let publish = move |p: &Package| {
363388
let publ = if ignore_publish {
364389
true
@@ -371,6 +396,8 @@ fn make_pkg_predicate(args: PackageSelectOptions) -> Result<Box<dyn Fn(&Package)
371396
publ
372397
};
373398

399+
400+
374401
if !packages.is_empty() {
375402
trace!("going for matching against {:?}", packages);
376403
return Ok(Box::new(move |p: &Package| {

src/util.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,48 @@ use serde::Deserialize;
88
use std::{collections::HashMap, error::Error, fs, time::Duration};
99
use tokio::runtime::Runtime;
1010
use toml_edit::{Document, InlineTable, Item, Table, Value};
11+
use petgraph::Graph;
12+
use git2::{Repository};
1113

14+
pub fn changed_packages<'a>(ws: &'a Workspace, reference: &str) -> Vec<Package> {
15+
let path = ws.root();
16+
let repo = Repository::open(&path).expect("Workspace isn't a git repo");
17+
let current_head = repo.head()
18+
.and_then(|b| b.peel_to_commit())
19+
.and_then(|c| c.tree())
20+
.expect("Could not determine current git HEAD");
21+
let main = repo
22+
.find_reference(reference)
23+
.and_then(|d| d.peel_to_commit())
24+
.and_then(|c| c.tree())
25+
.expect(format!("Reference {:?} not found in git repository", reference));
26+
27+
let diff = repo
28+
.diff_tree_to_tree(Some(&current_head), Some(&main), None)
29+
.expect("Diffing failed");
30+
31+
let files = diff
32+
.deltas()
33+
.filter_map(|d| d.new_file().path().clone())
34+
.filter_map(|d| if d.is_file() { d.parent() } else { Some(d) })
35+
.map(|l| path.join(l))
36+
.collect::<Vec<_>>();
37+
38+
let cfg = git2::Config::default().unwrap();
39+
40+
for m in members_deep(ws) {
41+
let root = m.root();
42+
for f in files.iter() {
43+
if f.starts_with(root) {
44+
println!("{:?}: {:}", f, m.name());
45+
break;
46+
}
47+
}
48+
}
49+
50+
}
51+
52+
// Find all members of the workspace, into the total depth
1253
pub fn members_deep<'a>(ws: &'a Workspace) -> Vec<Package> {
1354
let mut total_list = Vec::new();
1455
for m in ws.members() {

0 commit comments

Comments
 (0)