mirror of
https://github.com/commercialhaskell/stackage.git
synced 2026-01-11 23:08:30 +01:00
Add commenter script to help manage bounds issues
This commit is contained in:
parent
c5246029a7
commit
7f6003b459
50
CURATORS.md
50
CURATORS.md
@ -406,6 +406,56 @@ errors for builds, tests and benchmarks.
|
||||
|
||||
[tell-me-when-its-released]: https://github.com/commercialhaskell/stackage/blob/master/CURATORS.md#waiting-for-new-releases
|
||||
|
||||
### Large scale enabling/disabling of packages
|
||||
|
||||
`etc/commenter` is a binary that semi-automates the translation of
|
||||
`./check` errors into lines that can be copy pasted into
|
||||
`build-constraints.yaml`. It can only handle bounds issues,
|
||||
compilation issues still need to be analyzed manually.
|
||||
|
||||
Example usage: After disabling a few packages you get this curator output:
|
||||
|
||||
```
|
||||
ConfigFile (GHC 9 bounds issues, @maintainer) (not present) depended on by:
|
||||
- [ ] xdg-desktop-entry-0.1.1.1 (-any). @maintainer. Used by: library
|
||||
|
||||
|
||||
pipes-misc (GHC 9 bounds issues, @maintainer) (not present) depended on by:
|
||||
- [ ] pipes-fluid-0.6.0.1 (>=0.5). @handles. Used by: test-suite
|
||||
|
||||
|
||||
testing-feat (GHC 9 bounds issues, Grandfathered dependencies) (not present) depended on by:
|
||||
- [ ] dual-tree-0.2.3.0 (-any). Grandfathered dependencies. @handles. Used by: test-suite
|
||||
```
|
||||
|
||||
Copy this into `etc/commenter/comments.txt` and run `./commenter` (currently requires Rust)
|
||||
|
||||
You will get this output:
|
||||
```
|
||||
LIBS + EXES
|
||||
|
||||
- xdg-desktop-entry < 0 # tried xdg-desktop-entry-0.1.1.1, but its *library* requires the disabled package: ConfigFile
|
||||
|
||||
TESTS
|
||||
|
||||
- dual-tree # tried dual-tree-0.2.3.0, but its *test-suite* requires the disabled package: testing-feat
|
||||
- pipes-fluid # tried pipes-fluid-0.6.0.1, but its *test-suite* requires the disabled package: pipes-misc
|
||||
```
|
||||
|
||||
The lines under LIBS+EXES should be pasted in the shared section (currently called "GHC 9 bounds issues").
|
||||
|
||||
TESTS have a similar section under `skipped-tests`, and BENCHMARKS under `skipped-benchmarks`.
|
||||
|
||||
#### Re-enabling
|
||||
|
||||
We can periodically remove all packages under the bounds sections and then re-run the disabling flow above until we get a clean plan. This way we will automatically pick up packages that have been fixed.
|
||||
|
||||
#### Notes
|
||||
|
||||
* Please keep these lists sorted as the diffs will be much cleaner when we re-enable packages and re-run this flow
|
||||
* Please make sure to separate bounds issues from compilation failures/test run failures, as we cannot verify that a package builds or that tests pass without running the build!
|
||||
|
||||
|
||||
## Adding new curators
|
||||
|
||||
1. Add public ssh key to `~/.ssh/authorized_keys` on build server
|
||||
|
||||
3
etc/commenter/.gitignore
vendored
Normal file
3
etc/commenter/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/target
|
||||
/comments.txt
|
||||
/out.txt
|
||||
40
etc/commenter/Cargo.lock
generated
Normal file
40
etc/commenter/Cargo.lock
generated
Normal file
@ -0,0 +1,40 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "commenter"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
10
etc/commenter/Cargo.toml
Normal file
10
etc/commenter/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "commenter"
|
||||
version = "0.1.0"
|
||||
authors = ["Adam Bergmark <adam@bergmark.nl>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
regex = "1.5.4"
|
||||
1
etc/commenter/README.md
Normal file
1
etc/commenter/README.md
Normal file
@ -0,0 +1 @@
|
||||
Helps automate mass-disabling of packages in Stackage's build-constraint.yaml.
|
||||
2
etc/commenter/commenter
Executable file
2
etc/commenter/commenter
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
cargo run -- $@
|
||||
133
etc/commenter/src/main.rs
Normal file
133
etc/commenter/src/main.rs
Normal file
@ -0,0 +1,133 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead};
|
||||
use std::path::Path;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
type H = HashMap<Header, Vec<(String, String, String)>>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
enum Header {
|
||||
Versioned { package: String, version: String },
|
||||
Missing { package: String },
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut lib_exes: H = Default::default();
|
||||
let mut tests: H = Default::default();
|
||||
let mut benches: H = Default::default();
|
||||
let mut last_header: Option<Header> = None;
|
||||
let empty = Regex::new(r#"^\s*$"#).unwrap();
|
||||
let header_versioned =
|
||||
Regex::new(r#"^(?P<package>[a-zA-z]([a-zA-z0-9.-]*?))-(?P<version>(\d+(\.\d+)*)).+?is out of bounds for:$"#).unwrap();
|
||||
let header_missing =
|
||||
Regex::new(r#"^(?P<package>[a-zA-z]([a-zA-z0-9.-]*)).+?depended on by:$"#).unwrap();
|
||||
let package =
|
||||
Regex::new(r#"^- \[ \] (?P<package>[a-zA-z]([a-zA-z0-9.-]*?))-(?P<version>(\d+(\.\d+)*)).+?Used by: (?P<component>.+)$"#)
|
||||
.unwrap();
|
||||
|
||||
if let Ok(lines) = read_lines("./comments.txt") {
|
||||
for line in lines {
|
||||
if let Ok(line) = line {
|
||||
if empty.captures(&line).is_some() {
|
||||
} else if let Some(cap) = package.captures(&line) {
|
||||
let root = last_header.clone().unwrap();
|
||||
let package = cap.name("package").unwrap().as_str();
|
||||
let version = cap.name("version").unwrap().as_str();
|
||||
let component = cap.name("component").unwrap().as_str();
|
||||
match component {
|
||||
"library" | "executable" => {
|
||||
insert(&mut lib_exes, root, package, version, component)
|
||||
}
|
||||
"benchmark" => insert(&mut benches, root, package, version, "benchmarks"),
|
||||
"test-suite" => insert(&mut tests, root, package, version, component),
|
||||
_ => panic!("Bad component: {}", component),
|
||||
}
|
||||
} else if let Some(cap) = header_versioned.captures(&line) {
|
||||
let package = cap.name("package").unwrap().as_str().to_owned();
|
||||
let version = cap.name("version").unwrap().as_str().to_owned();
|
||||
last_header = Some(Header::Versioned { package, version });
|
||||
} else if let Some(cap) = header_missing.captures(&line) {
|
||||
let package = cap.name("package").unwrap().as_str().to_owned();
|
||||
last_header = Some(Header::Missing { package });
|
||||
} else {
|
||||
panic!("Unhandled: {:?}", line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !lib_exes.is_empty() {
|
||||
println!("\nLIBS + EXES\n");
|
||||
}
|
||||
for (header, packages) in lib_exes {
|
||||
for (package, version, component) in packages {
|
||||
printer(" ", &package, true, &version, &component, &header);
|
||||
}
|
||||
}
|
||||
|
||||
if !tests.is_empty() {
|
||||
println!("\nTESTS\n");
|
||||
}
|
||||
for (header, packages) in tests {
|
||||
for (package, version, component) in packages {
|
||||
printer(" ", &package, false, &version, &component, &header);
|
||||
}
|
||||
}
|
||||
|
||||
if !benches.is_empty() {
|
||||
println!("\nBENCHMARKS\n");
|
||||
}
|
||||
for (header, packages) in benches {
|
||||
for (package, version, component) in packages {
|
||||
printer(" ", &package, false, &version, &component, &header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn printer(
|
||||
indent: &str,
|
||||
package: &str,
|
||||
lt0: bool,
|
||||
version: &str,
|
||||
component: &str,
|
||||
header: &Header,
|
||||
) -> () {
|
||||
let lt0 = if lt0 { " < 0" } else { "" };
|
||||
println!(
|
||||
"{indent}- {package}{lt0} # tried {package}-{version}, but its *{component}* {cause}",
|
||||
indent = indent,
|
||||
package = package,
|
||||
lt0 = lt0,
|
||||
version = version,
|
||||
component = component,
|
||||
cause = match header {
|
||||
Header::Versioned { package, version } => format!(
|
||||
"does not support: {package}-{version}",
|
||||
package = package,
|
||||
version = version
|
||||
),
|
||||
Header::Missing { package } => format!(
|
||||
"requires the disabled package: {package}",
|
||||
package = package
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn insert(h: &mut H, header: Header, package: &str, version: &str, component: &str) {
|
||||
(*h.entry(header).or_insert_with(|| vec![])).push((
|
||||
package.to_owned(),
|
||||
version.to_owned(),
|
||||
component.to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let file = File::open(filename)?;
|
||||
Ok(io::BufReader::new(file).lines())
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user