aboutsummaryrefslogtreecommitdiff
path: root/xtask/src/codegen/gen_unstable_future_descriptor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'xtask/src/codegen/gen_unstable_future_descriptor.rs')
-rw-r--r--xtask/src/codegen/gen_unstable_future_descriptor.rs175
1 files changed, 16 insertions, 159 deletions
diff --git a/xtask/src/codegen/gen_unstable_future_descriptor.rs b/xtask/src/codegen/gen_unstable_future_descriptor.rs
index eaf063371..fee68c365 100644
--- a/xtask/src/codegen/gen_unstable_future_descriptor.rs
+++ b/xtask/src/codegen/gen_unstable_future_descriptor.rs
@@ -2,81 +2,27 @@
2 2
3use crate::codegen::update; 3use crate::codegen::update;
4use crate::codegen::{self, project_root, Mode, Result}; 4use crate::codegen::{self, project_root, Mode, Result};
5use chrono::prelude::*;
6use fs::read_to_string;
7use graphql_client::*;
8use proc_macro2::TokenStream;
9use quote::quote; 5use quote::quote;
10use regex::Regex;
11use reqwest;
12use serde::*;
13use std::fs; 6use std::fs;
14use std::fs::File;
15use std::io::copy;
16use std::io::prelude::*;
17use std::path::PathBuf;
18use std::process::Command; 7use std::process::Command;
19use walkdir::WalkDir; 8use walkdir::WalkDir;
20 9
21type URI = String; 10pub fn generate_unstable_future_descriptor(mode: Mode) -> Result<()> {
22type DateTime = String; 11 let path = project_root().join(codegen::STORAGE);
23 12 fs::create_dir_all(path.clone())?;
24#[derive(GraphQLQuery)]
25#[graphql(
26 schema_path = "src/codegen/schema.graphql",
27 query_path = "src/codegen/last_commit_that_affected_path.graphql"
28)]
29struct LastCommitThatAffectedPath;
30
31fn deep_destructuring(
32 response_body: Response<last_commit_that_affected_path::ResponseData>,
33) -> CommitInfo {
34 let t = response_body.data.unwrap().repository.unwrap().object.unwrap().on;
35
36 use last_commit_that_affected_path::LastCommitThatAffectedPathRepositoryObjectOn::Commit;
37 let commit = match t {
38 Commit(data) => data,
39 _ => panic!("type does not match"),
40 };
41 let edges = commit.history.edges.unwrap();
42 let node = edges.first().unwrap().as_ref().unwrap().node.as_ref().unwrap();
43 CommitInfo { commit_url: node.commit_url.clone(), committed_date: node.committed_date.clone() }
44}
45
46struct CommitInfo {
47 commit_url: String,
48 committed_date: String,
49}
50
51fn last_update(
52 owner: &str,
53 name: &str,
54 path: &str,
55 auth_token: Option<&str>,
56) -> Result<CommitInfo> {
57 let query =
58 LastCommitThatAffectedPath::build_query(last_commit_that_affected_path::Variables {
59 owner: owner.to_owned(),
60 name: name.to_owned(),
61 path: path.to_owned(),
62 });
63
64 let client = reqwest::blocking::Client::new();
65 let mut headers = reqwest::header::HeaderMap::new();
66 headers.insert("User-Agent", "https://github.com/rust-analyzer/rust-analyzer".parse()?);
67 let mut request = client.post("https://api.github.com/graphql").headers(headers).json(&query);
68
69 if auth_token.is_some() {
70 request = request.bearer_auth(auth_token.unwrap());
71 }
72
73 let response = request.send()?;
74 13
75 let response_body: Response<last_commit_that_affected_path::ResponseData> = response.json()?; 14 Command::new("git").current_dir(path.clone()).arg("init").output()?;
76 Ok(deep_destructuring(response_body)) 15 Command::new("git")
77} 16 .current_dir(path.clone())
17 .args(&["remote", "add", "-f", "origin", codegen::REPOSITORY_URL])
18 .output()?;
19 Command::new("git")
20 .current_dir(path.clone())
21 .args(&["sparse-checkout", "set", "/src/doc/unstable-book/src/"])
22 .output()?;
23 Command::new("git").current_dir(path.clone()).args(&["pull", "origin", "master"]).output()?;
78 24
79fn generate_descriptor(src_dir: PathBuf) -> Result<TokenStream> { 25 let src_dir = path.join("src/doc/unstable-book/src");
80 let files = WalkDir::new(src_dir.join("language-features")) 26 let files = WalkDir::new(src_dir.join("language-features"))
81 .into_iter() 27 .into_iter()
82 .chain(WalkDir::new(src_dir.join("library-features"))) 28 .chain(WalkDir::new(src_dir.join("library-features")))
@@ -107,98 +53,9 @@ fn generate_descriptor(src_dir: PathBuf) -> Result<TokenStream> {
107 #(#definitions),* 53 #(#definitions),*
108 ]; 54 ];
109 }; 55 };
110 Ok(ts)
111}
112
113fn add_anchor(text: impl std::fmt::Display, anchor: &str) -> String {
114 let anchor_str = format!(
115 r#"//The anchor is used to check if file is up to date and represent the time
116 //of the last commit that affected path where located data for generation
117 //ANCHOR: {}"#,
118 anchor
119 );
120 format!("{}\n\n{}\n", anchor_str, text)
121}
122
123fn is_actual(path: &PathBuf, str_datetime: &str) -> bool {
124 let re = Regex::new(r"//ANCHOR: (\S*)").unwrap();
125 let opt_str = fs::read_to_string(path);
126 if opt_str.is_err() {
127 return false;
128 }
129 let text = opt_str.unwrap();
130 let opt_datetime = re.captures(text.as_str());
131 if opt_datetime.is_none() {
132 return false;
133 }
134 let str_file_dt = opt_datetime.unwrap().get(1).unwrap().as_str();
135 let file_dt = str_file_dt.parse::<chrono::DateTime<Utc>>().unwrap();
136 let datetime = str_datetime.parse::<chrono::DateTime<Utc>>().unwrap();
137
138 file_dt == datetime
139}
140
141fn download_tar(
142 owner: &str,
143 name: &str,
144 auth_token: Option<&str>,
145 destination: &PathBuf,
146 fname: &str,
147) -> Result<()> {
148 let mut headers = reqwest::header::HeaderMap::new();
149 headers.insert("User-Agent", "https://github.com/rust-analyzer/rust-analyzer".parse()?);
150 let mut request = reqwest::blocking::Client::new()
151 .get(format!("https://api.github.com/repos/{}/{}/tarball", owner, name).as_str())
152 .headers(headers);
153
154 if auth_token.is_some() {
155 request = request.bearer_auth(auth_token.unwrap());
156 }
157
158 let response = request.send()?;
159 let download_url = response.url();
160
161 let mut response = reqwest::blocking::Client::new()
162 .get(download_url.as_str())
163 .send()?;
164
165 let mut n = fname.to_string();
166 n.push_str(".tar.gz");
167 let fpath = destination.join(n);
168 let mut file = File::create(fpath)?;
169 response.copy_to(&mut file)?;
170
171 Ok(())
172}
173
174pub fn generate_unstable_future_descriptor(mode: Mode) -> Result<()> {
175 const auth_token: Option<&str> = None;
176
177 let path = project_root().join(codegen::STORAGE);
178 fs::create_dir_all(path.clone())?;
179
180 let commit_info =
181 last_update(codegen::REPO_OWNER, codegen::REPO_NAME, codegen::REPO_PATH, auth_token)?;
182
183 if is_actual(
184 &project_root().join(codegen::GENERATION_DESTINATION),
185 commit_info.committed_date.as_str(),
186 ) {
187 return Ok(());
188 }
189
190 download_tar(codegen::REPO_OWNER, codegen::REPO_NAME, auth_token, &path, "repository")?;
191 Command::new("tar")
192 .args(&["-xvf", concat!("repository",".tar.gz"), "--wildcards", "*/src/doc/unstable-book/src", "--strip=1"])
193 .current_dir(codegen::STORAGE)
194 .output()?;
195
196 let src_dir = path.join(codegen::REPO_PATH);
197 let gen_holder = generate_descriptor(src_dir)?.to_string();
198 let gen_holder = add_anchor(gen_holder, commit_info.committed_date.as_str());
199 56
200 let destination = project_root().join(codegen::GENERATION_DESTINATION); 57 let destination = project_root().join(codegen::UNSTABLE_FEATURE);
201 let contents = crate::reformat(gen_holder)?; 58 let contents = crate::reformat(ts.to_string())?;
202 update(destination.as_path(), &contents, mode)?; 59 update(destination.as_path(), &contents, mode)?;
203 60
204 Ok(()) 61 Ok(())