File: build.rs

package info (click to toggle)
hippotat 1.3.2
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 700 kB
  • sloc: sh: 407; makefile: 132; perl: 84; python: 79; ansic: 34
file content (83 lines) | stat: -rw-r--r-- 2,225 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use serde::Deserialize;
use std::process::Command;

// We don't use cargo-metadata because it has a very unstable API!

#[derive(Deserialize, Debug)]
struct Metadata {
  workspace_members: Vec<PackageId>,
  resolve: MResolve,
  packages: Vec<MPackage>,
}
#[derive(Deserialize, Debug)]
struct MResolve {
  nodes: Vec<MNode>,
}
#[derive(Deserialize, Debug)]
struct MNode {
  id: PackageId,
  dependencies: Vec<PackageId>,
}
#[derive(Deserialize, Debug)]
struct MPackage {
  id: PackageId,
  version: String,
  name: String,
}
#[derive(Deserialize, Debug, Eq, PartialEq)]
#[serde(transparent)]
struct PackageId(String);

impl Metadata {
  fn package(&self, id: &PackageId) -> &MPackage {
    self.packages.iter()
      .find(|p| &p.id == id).expect("missing")
  }
}

struct Context<'c> {
  hippo: &'c MNode,
  metadata: &'c Metadata,
}

impl Context<'_> {
  fn emit_for_package(&self, package: &str, versions: &[&str]) {
    let pkg = self.hippo.dependencies.iter()
      .map(|i| self.metadata.package(i))
      .find(|i| i.name == package).expect("no nix in hippotat's deps");

    let pkg = &pkg.version;
    let pkg: semver::Version = pkg.parse().expect(pkg);

    for test in versions {
      let cfg = test.replace('.', "_").replace(">=", "ge_");
      let test: semver::VersionReq = test.parse().unwrap();
      let cfg = format!("{package}_{cfg}");
      println!(r#"cargo:rustc-check-cfg=cfg({cfg})"#);
      if test.matches(&pkg) {
        println!("cargo:rustc-cfg={cfg}");
      }
    }
  }
}

fn main(){
  let x = Command::new("cargo")
    .args(["metadata", "--format-version=1"])
    .stderr(std::process::Stdio::inherit())
    .output().unwrap();
  if !x.status.success() { panic!() }
  let output = std::str::from_utf8(&x.stdout).unwrap();
//  eprintln!("{}", output);
  let metadata: Metadata = serde_json::from_str(&output).unwrap();

  let hippo = metadata.workspace_members.iter()
    .map(|i| metadata.package(i))
    .find(|p| p.name == "hippotat").expect("no hippotat in workspace?");
  let hippo = metadata.resolve.nodes.iter()
    .find(|n| n.id == hippo.id).expect("no hippotat in nodes!");

  let ctx = Context { hippo, metadata: &metadata };

  ctx.emit_for_package("nix", &[">=0.27", ">=0.28"]);
}