Skip to content

Commit b8a1f7f

Browse files
authored
Merge pull request #1 from rust-analyzer/dep-track
2 parents 77f3b37 + 02e989a commit b8a1f7f

File tree

4 files changed

+147
-67
lines changed

4 files changed

+147
-67
lines changed

.github/workflows/main.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,22 @@ on:
1212
jobs:
1313
run:
1414
name: Run
15-
runs-on: macos-latest
15+
runs-on: ubuntu-latest
1616
steps:
17-
- uses: actions/checkout@master
18-
- name: Install Rust
19-
run: rustup update nightly && rustup default nightly
17+
- name: Checkout repository
18+
uses: actions/checkout@v3
19+
- name: Install Rust toolchain
20+
run: |
21+
rustup update --no-self-update stable && rustup default stable
22+
- name: Cache Dependencies
23+
uses: Swatinem/rust-cache@988c164c3d0e93c4dbab36aaf5bbeb77425b2894
2024
- run: cargo build
2125
- name: Configure crates.io token
2226
run: |
2327
echo "[registry]" >> $HOME/.cargo/credentials
2428
echo "token = \"${{ secrets.CRATESIO_TOKEN }}\"" >> $HOME/.cargo/credentials
2529
if: github.event_name != 'pull_request'
26-
- run: cargo run ${{ secrets.GH_TOKEN }}
30+
- run: cargo run publish ${{ secrets.GH_TOKEN }}
2731
if: github.event_name != 'pull_request'
32+
- run: cargo run nopublish ${{ secrets.GH_TOKEN }}
33+
if: github.event_name == 'pull_request'

Cargo.lock

Lines changed: 53 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
name = "rustc-auto-publish"
33
version = "0.1.0"
44
authors = ["Alex Crichton <alex@alexcrichton.com>"]
5+
publish = false
6+
edition = "2021"
57

68
[dependencies]
9+
cargo_metadata = "0.17.0"
710
curl = "0.4"
811
flate2 = "1.0"
912
semver = { version = "1.0", features = ["serde"] }

src/main.rs

Lines changed: 80 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ use std::str;
1010
use std::thread;
1111
use std::time::Duration;
1212

13+
use cargo_metadata::{Metadata, Package};
14+
1315
const PREFIX: &str = "ra-ap";
1416

1517
fn main() {
16-
let token = std::env::args().nth(1);
18+
let do_publish = std::env::args().nth(1).unwrap() == "publish";
19+
let token = std::env::args().nth(2);
1720
let commit = latest_master_commit(&token);
1821
println!("latest commit: {}", commit);
1922

@@ -27,48 +30,50 @@ fn main() {
2730

2831
let target_crates = vec![
2932
RustcApCrate {
30-
name: "rustc_lexer",
31-
dir: "compiler/rustc_lexer",
32-
},
33-
RustcApCrate {
34-
name: "rustc_serialize",
35-
dir: "compiler/rustc_serialize",
36-
},
37-
RustcApCrate {
38-
name: "rustc_macros",
39-
dir: "compiler/rustc_macros",
40-
},
41-
RustcApCrate {
42-
name: "rustc_index",
43-
dir: "compiler/rustc_index",
33+
name: "rustc_lexer".to_owned(),
34+
dir: "compiler/rustc_lexer".to_owned(),
4435
},
4536
RustcApCrate {
46-
name: "rustc_parse_format",
47-
dir: "compiler/rustc_parse_format",
37+
name: "rustc_parse_format".to_owned(),
38+
dir: "compiler/rustc_parse_format".to_owned(),
4839
},
4940
RustcApCrate {
50-
name: "rustc_abi",
51-
dir: "compiler/rustc_abi",
41+
name: "rustc_abi".to_owned(),
42+
dir: "compiler/rustc_abi".to_owned(),
5243
},
5344
];
5445

5546
println!("learning about the dependency graph");
5647
let rustc_packages = get_rustc_packages(&target_crates, &dst);
48+
println!(
49+
"found packages: {:?}",
50+
rustc_packages
51+
.iter()
52+
.map(|it| &it.package.name)
53+
.collect::<Vec<_>>()
54+
);
5755
let mut crates = Vec::new();
5856
let mut seen = HashSet::new();
5957

6058
for RustcPackageInfo { package, metadata } in rustc_packages.iter() {
6159
fill(&metadata, &package, &mut crates, &mut seen);
6260
}
61+
let crates = crates_in_topological_order(&crates);
6362

64-
let version_to_publish = get_version_to_publish(&crates);
65-
println!("going to publish {}", version_to_publish);
63+
println!(
64+
"topologically sorted: {:?}",
65+
crates.iter().map(|it| &it.name).collect::<Vec<_>>()
66+
);
67+
if do_publish {
68+
let version_to_publish = get_version_to_publish(&crates);
69+
println!("going to publish {}", version_to_publish);
6670

67-
for p in crates.iter() {
68-
publish(p, &commit, &version_to_publish);
71+
for p in crates {
72+
publish(p, &commit, &version_to_publish);
6973

70-
// Give the crates time to make their way into the index
71-
thread::sleep(Duration::from_secs(45));
74+
// Give the crates time to make their way into the index
75+
thread::sleep(Duration::from_secs(45));
76+
}
7277
}
7378
}
7479

@@ -134,31 +139,38 @@ fn download_src(dst: &Path, commit: &str) {
134139
}
135140

136141
fn get_rustc_packages(target_crates: &[RustcApCrate], dst: &Path) -> Vec<RustcPackageInfo> {
142+
let mut work = target_crates.to_vec();
137143
let mut packages = Vec::new();
138144

139-
for RustcApCrate { name, dir } in target_crates.iter() {
140-
let metadata = Command::new("cargo")
141-
.current_dir(dst.join(dir))
142-
.arg("metadata")
143-
.arg("--format-version=1")
144-
.output()
145-
.expect("failed to execute cargo");
146-
if !metadata.status.success() {
147-
panic!("failed to run rustc: {:?}", metadata);
145+
while let Some(RustcApCrate { name, dir }) = work.pop() {
146+
if packages
147+
.iter()
148+
.any(|it: &RustcPackageInfo| it.package.name == name)
149+
{
150+
continue;
148151
}
149-
let output = str::from_utf8(&metadata.stdout).unwrap();
150-
let output: Metadata = serde_json::from_str(output).unwrap();
152+
let mut cmd = cargo_metadata::MetadataCommand::new();
153+
cmd.manifest_path(dst.join(dir).join("Cargo.toml"));
154+
let metadata = cmd.exec().unwrap();
151155

152-
let rustc_package = output
156+
let rustc_package = metadata
153157
.packages
154158
.iter()
155159
.find(|p| p.name == *name)
156160
.expect(&format!("failed to find {}", &name))
157161
.clone();
162+
for dep in rustc_package.dependencies.iter() {
163+
if let Some(path) = &dep.path {
164+
work.push(RustcApCrate {
165+
name: dep.name.clone(),
166+
dir: path.to_string(),
167+
})
168+
}
169+
}
158170

159171
packages.push(RustcPackageInfo {
160172
package: rustc_package,
161-
metadata: output,
173+
metadata,
162174
})
163175
}
164176

@@ -176,6 +188,8 @@ fn fill<'a>(
176188
}
177189
let node = output
178190
.resolve
191+
.as_ref()
192+
.unwrap()
179193
.nodes
180194
.iter()
181195
.find(|n| n.id == pkg.id)
@@ -189,34 +203,38 @@ fn fill<'a>(
189203
pkgs.push(pkg);
190204
}
191205

192-
#[derive(Deserialize)]
193-
struct Metadata {
194-
packages: Vec<Package>,
195-
resolve: Resolve,
196-
}
206+
// dirt topo sort
207+
fn crates_in_topological_order<'a>(pkgs: &[&'a Package]) -> Vec<&'a Package> {
208+
let mut res = Vec::new();
209+
let mut visited = HashSet::default();
197210

198-
#[derive(Deserialize, Clone)]
199-
struct Package {
200-
id: String,
201-
name: String,
202-
source: Option<String>,
203-
manifest_path: String,
204-
}
211+
for pkg in pkgs {
212+
go(pkgs, &mut visited, &mut res, pkg);
213+
}
205214

206-
#[derive(Deserialize)]
207-
struct Resolve {
208-
nodes: Vec<ResolveNode>,
209-
}
215+
return res;
210216

211-
#[derive(Deserialize)]
212-
struct ResolveNode {
213-
id: String,
214-
dependencies: Vec<String>,
217+
fn go<'a>(
218+
pkgs: &[&'a Package],
219+
visited: &mut HashSet<String>,
220+
res: &mut Vec<&'a Package>,
221+
source: &'a Package,
222+
) {
223+
if !visited.insert(source.name.clone()) {
224+
return;
225+
}
226+
for dep in source.dependencies.iter() {
227+
if let Some(dep) = pkgs.iter().find(|it| it.name == dep.name) {
228+
go(pkgs, visited, res, dep)
229+
}
230+
}
231+
res.push(source)
232+
}
215233
}
216-
217-
struct RustcApCrate<'a> {
218-
name: &'a str,
219-
dir: &'a str,
234+
#[derive(Clone)]
235+
struct RustcApCrate {
236+
name: String,
237+
dir: String,
220238
}
221239

222240
struct RustcPackageInfo {

0 commit comments

Comments
 (0)