mirror of
https://github.com/commercialhaskell/stackage.git
synced 2026-02-02 17:40:26 +01:00
Merge pull request #6407 from commercialhaskell/commenter-disabled
commenter disabled: count transitive dependents
This commit is contained in:
commit
edd0f78a76
14
CURATORS.md
14
CURATORS.md
@ -533,6 +533,20 @@ TARGET=nightly-2021-01-14 \ # the date doesn't matter
|
|||||||
curator snapshot
|
curator snapshot
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Finding disabled packages with lots of dependents
|
||||||
|
|
||||||
|
`commenter disabled` prints the number of transitive dependents a disabled package has. Low hanging fruit to get a lot of packages included again.
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
```
|
||||||
|
[...]
|
||||||
|
stringable is disabled with 10 dependents
|
||||||
|
llvm-hs is disabled with 12 dependents
|
||||||
|
th-data-compat is disabled with 12 dependents
|
||||||
|
amazonka-core is disabled with 96 dependents
|
||||||
|
gogol-core is disabled with 96 dependents
|
||||||
|
```
|
||||||
|
|
||||||
## Adding new curators
|
## Adding new curators
|
||||||
|
|
||||||
1. Add public ssh key to `~/.ssh/authorized_keys` on build server
|
1. Add public ssh key to `~/.ssh/authorized_keys` on build server
|
||||||
|
|||||||
@ -188,6 +188,7 @@ enum State {
|
|||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
struct VersionedPackage {
|
struct VersionedPackage {
|
||||||
package: Package,
|
package: Package,
|
||||||
version: Version,
|
version: Version,
|
||||||
@ -352,7 +353,7 @@ struct SnapshotPackage {
|
|||||||
// pantry-tree
|
// pantry-tree
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone)]
|
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Debug)]
|
||||||
struct Package(String);
|
struct Package(String);
|
||||||
|
|
||||||
impl fmt::Display for Package {
|
impl fmt::Display for Package {
|
||||||
@ -361,7 +362,7 @@ impl fmt::Display for Package {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialOrd, Ord, PartialEq, Eq)]
|
#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Debug)]
|
||||||
struct Version(String);
|
struct Version(String);
|
||||||
|
|
||||||
impl fmt::Display for Version {
|
impl fmt::Display for Version {
|
||||||
@ -457,3 +458,117 @@ pub fn diff_snapshot(a: String, b: String) {
|
|||||||
println!("{s}");
|
println!("{s}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
|
struct DisabledTransitively {
|
||||||
|
child: VersionedPackage,
|
||||||
|
parent: Package,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_disabled_transitviely(s: &str) -> Option<DisabledTransitively> {
|
||||||
|
let r = regex!(
|
||||||
|
r#"- *([^ ]+) < *0 *# tried [^ ]+-([\d.]+), but its \*[^*]+\* requires the disabled package: ([^ ]+)"#
|
||||||
|
);
|
||||||
|
if let Some(caps) = r.captures(s) {
|
||||||
|
let package = Package(caps.get(1).unwrap().as_str().to_owned());
|
||||||
|
let version = Version(caps.get(2).unwrap().as_str().to_owned());
|
||||||
|
let parent = Package(caps.get(3).unwrap().as_str().to_owned());
|
||||||
|
Some(DisabledTransitively {
|
||||||
|
child: VersionedPackage { package, version },
|
||||||
|
parent,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_disabled_transitviely() {
|
||||||
|
let s = "- Network-NineP < 0 # tried Network-NineP-0.4.7.1, but its *library* requires the disabled package: mstate";
|
||||||
|
assert_eq!(
|
||||||
|
parse_disabled_transitviely(s),
|
||||||
|
Some(DisabledTransitively {
|
||||||
|
child: VersionedPackage {
|
||||||
|
package: Package("Network-NineP".to_owned()),
|
||||||
|
version: Version("0.4.7.1".to_owned())
|
||||||
|
},
|
||||||
|
parent: Package("mstate".to_owned()),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type M = BTreeMap<Package, (Vec<VersionedPackage>, Option<usize>)>;
|
||||||
|
|
||||||
|
pub fn disabled() {
|
||||||
|
let mut disabled_transitively: Vec<DisabledTransitively> = vec![];
|
||||||
|
handle(false, |loc, lines| {
|
||||||
|
match loc {
|
||||||
|
Location::Lib => disabled_transitively.extend(
|
||||||
|
lines
|
||||||
|
.into_iter()
|
||||||
|
.map(|line| parse_disabled_transitviely(&line))
|
||||||
|
.flatten()
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
),
|
||||||
|
Location::Test | Location::Bench => (),
|
||||||
|
}
|
||||||
|
vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut packages: BTreeSet<Package> = BTreeSet::new();
|
||||||
|
let mut disabled: M = BTreeMap::new();
|
||||||
|
|
||||||
|
for DisabledTransitively { child, parent } in disabled_transitively {
|
||||||
|
packages.insert(child.package.clone());
|
||||||
|
packages.insert(parent.clone());
|
||||||
|
disabled
|
||||||
|
.entry(child.package.clone())
|
||||||
|
.or_insert_with(|| (vec![], None));
|
||||||
|
let t = disabled.entry(parent).or_insert_with(|| (vec![], None));
|
||||||
|
t.0.push(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut packages_len = packages.len();
|
||||||
|
while packages_len > 0 {
|
||||||
|
let mut new_packages: BTreeSet<Package> = BTreeSet::new();
|
||||||
|
for package in packages {
|
||||||
|
let (_, count) = disabled.get(&package).unwrap();
|
||||||
|
if count.is_none() && !process(&package, &mut disabled) {
|
||||||
|
new_packages.insert(package.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packages = new_packages;
|
||||||
|
packages_len = packages.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut v: Vec<_> = disabled
|
||||||
|
.into_iter()
|
||||||
|
.map(|(package, (_, count))| (count, package))
|
||||||
|
.collect();
|
||||||
|
v.sort();
|
||||||
|
for (count, package) in v {
|
||||||
|
let count = count.unwrap();
|
||||||
|
if count != 0 {
|
||||||
|
println!("{package} is disabled with {count} dependents");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process(package: &Package, m: &mut M) -> bool {
|
||||||
|
let (children, count) = m.get(package).unwrap();
|
||||||
|
assert!(count.is_none(), "{:?}", package);
|
||||||
|
let mut count = 0;
|
||||||
|
for child in children {
|
||||||
|
let (_, child_count) = m
|
||||||
|
.get(&child.package)
|
||||||
|
.unwrap_or_else(|| panic!("{}", child.package));
|
||||||
|
match child_count {
|
||||||
|
None => return false,
|
||||||
|
Some(i) => count += 1 + i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.entry(package.clone())
|
||||||
|
.and_modify(|tup| tup.1 = Some(count))
|
||||||
|
.or_insert_with(|| panic!("{}", package));
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|||||||
@ -19,19 +19,21 @@ enum Header {
|
|||||||
about = "Automates generation of bounds in build-constraints.yaml"
|
about = "Automates generation of bounds in build-constraints.yaml"
|
||||||
)]
|
)]
|
||||||
enum Opt {
|
enum Opt {
|
||||||
Clear,
|
|
||||||
Add,
|
Add,
|
||||||
Outdated,
|
Clear,
|
||||||
DiffSnapshot { a: String, b: String },
|
DiffSnapshot { a: String, b: String },
|
||||||
|
Disabled,
|
||||||
|
Outdated,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let opt = Opt::from_args();
|
let opt = Opt::from_args();
|
||||||
match opt {
|
match opt {
|
||||||
Opt::Clear => commenter::clear(),
|
|
||||||
Opt::Add => add(),
|
Opt::Add => add(),
|
||||||
Opt::Outdated => commenter::outdated(),
|
Opt::Clear => commenter::clear(),
|
||||||
Opt::DiffSnapshot { a, b } => commenter::diff_snapshot(a, b),
|
Opt::DiffSnapshot { a, b } => commenter::diff_snapshot(a, b),
|
||||||
|
Opt::Disabled => commenter::disabled(),
|
||||||
|
Opt::Outdated => commenter::outdated(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user