summaryrefslogtreecommitdiffstats
path: root/src/doc/rustc-dev-guide/ci
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xsrc/doc/rustc-dev-guide/ci/check-in.sh38
-rwxr-xr-xsrc/doc/rustc-dev-guide/ci/check_line_lengths.sh43
-rw-r--r--src/doc/rustc-dev-guide/ci/date-check/Cargo.lock133
-rw-r--r--src/doc/rustc-dev-guide/ci/date-check/Cargo.toml12
-rw-r--r--src/doc/rustc-dev-guide/ci/date-check/src/main.rs242
-rwxr-xr-xsrc/doc/rustc-dev-guide/ci/linkcheck.sh31
6 files changed, 499 insertions, 0 deletions
diff --git a/src/doc/rustc-dev-guide/ci/check-in.sh b/src/doc/rustc-dev-guide/ci/check-in.sh
new file mode 100755
index 000000000..4477789c7
--- /dev/null
+++ b/src/doc/rustc-dev-guide/ci/check-in.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+set -eu
+
+# This is not a very smart script
+if [ $# != 2 ]; then
+ echo "usage: $0 <since> <number-of-prs-merged>"
+ if [ $# = 0 ]; then
+ echo "help: you can find the last check-in at" \
+ "https://rust-lang.zulipchat.com/#narrow/stream/238009-t-compiler.2Fmeetings/search/wg-rustc-dev-guide"
+ elif [ $# = 1 ] ; then
+ echo "help: you can find the number of PRs merged at" \
+ "https://github.com/rust-lang/rustc-dev-guide/pulls?q=is%3Apr+is%3Amerged+updated%3A%3E$1"
+ fi
+ exit 1
+fi
+
+curl() {
+ command curl -s "$@"
+}
+
+# Get recently updated PRs
+curl "https://api.github.com/repos/rust-lang/rustc-dev-guide/pulls?state=closed&per_page=$2" \
+ | jq '[.[] | select(.merged_at > "'"$1"'")]' > pulls.json
+
+show_pulls() {
+ jq -r '.[] | { title, number, html_url, user: .user.login } | "- " + .title + " [#" + (.number | tostring) + "](" + .html_url + ")"'
+}
+
+echo "### Most notable changes"
+echo
+show_pulls < pulls.json
+echo
+echo "### Most notable WIPs"
+echo
+# If there are more than 30 PRs open at a time, you'll need to set `per_page`.
+# For now this seems unlikely.
+curl "https://api.github.com/repos/rust-lang/rustc-dev-guide/pulls?state=open" | show_pulls
diff --git a/src/doc/rustc-dev-guide/ci/check_line_lengths.sh b/src/doc/rustc-dev-guide/ci/check_line_lengths.sh
new file mode 100755
index 000000000..31cda5c65
--- /dev/null
+++ b/src/doc/rustc-dev-guide/ci/check_line_lengths.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+if [ "$1" == "--help" ]; then
+ echo 'Usage:' "[MAX_LINE_LENGTH=n] $0 [file ...]"
+ exit 1
+fi
+
+if [ "$MAX_LINE_LENGTH" == "" ]; then
+ MAX_LINE_LENGTH=100
+fi
+
+if [ "$1" == "" ]; then
+ shopt -s globstar
+ files=( src/**/*.md )
+else
+ files=( "$@" )
+fi
+
+echo "Checking line lengths in all source files <= $MAX_LINE_LENGTH chars..."
+
+echo "Offending files and lines:"
+(( bad_lines = 0 ))
+(( inside_block = 0 ))
+for file in "${files[@]}"; do
+ echo "$file"
+ (( line_no = 0 ))
+ while IFS="" read -r line || [[ -n "$line" ]] ; do
+ (( line_no++ ))
+ if [[ "$line" =~ ^'```' ]] ; then
+ (( inside_block = !$inside_block ))
+ continue
+ fi
+ if ! (( $inside_block )) \
+ && ! [[ "$line" =~ " | "|"-|-"|"://"|"]:"|\[\^[^\ ]+\]: ]] \
+ && (( "${#line}" > $MAX_LINE_LENGTH )) ; then
+ (( bad_lines++ ))
+ echo -e "\t$line_no : $line"
+ fi
+ done < "$file"
+done
+
+echo "$bad_lines offending lines found."
+(( $bad_lines == 0 ))
diff --git a/src/doc/rustc-dev-guide/ci/date-check/Cargo.lock b/src/doc/rustc-dev-guide/ci/date-check/Cargo.lock
new file mode 100644
index 000000000..00fa3def8
--- /dev/null
+++ b/src/doc/rustc-dev-guide/ci/date-check/Cargo.lock
@@ -0,0 +1,133 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+
+[[package]]
+name = "chrono"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
+dependencies = [
+ "libc",
+ "num-integer",
+ "num-traits",
+ "time",
+ "winapi",
+]
+
+[[package]]
+name = "date-check"
+version = "0.1.0"
+dependencies = [
+ "chrono",
+ "glob",
+ "regex",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
+name = "libc"
+version = "0.2.82"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "num-integer"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "regex"
+version = "1.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
+
+[[package]]
+name = "time"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
+dependencies = [
+ "libc",
+ "wasi",
+ "winapi",
+]
+
+[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/src/doc/rustc-dev-guide/ci/date-check/Cargo.toml b/src/doc/rustc-dev-guide/ci/date-check/Cargo.toml
new file mode 100644
index 000000000..472529511
--- /dev/null
+++ b/src/doc/rustc-dev-guide/ci/date-check/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "date-check"
+version = "0.1.0"
+authors = ["Noah Lev <camelidcamel@gmail.com>"]
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+glob = "0.3"
+regex = "1"
+chrono = "0.4"
diff --git a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
new file mode 100644
index 000000000..bbea2bf38
--- /dev/null
+++ b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
@@ -0,0 +1,242 @@
+use std::{
+ collections::BTreeMap,
+ convert::TryInto as _,
+ env, fmt, fs,
+ path::{Path, PathBuf},
+};
+
+use chrono::{Datelike as _, TimeZone as _, Utc};
+use glob::glob;
+use regex::Regex;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+struct Date {
+ year: u32,
+ month: u32,
+}
+
+impl Date {
+ fn months_since(self, other: Date) -> Option<u32> {
+ let self_chrono = Utc.ymd(self.year.try_into().unwrap(), self.month, 1);
+ let other_chrono = Utc.ymd(other.year.try_into().unwrap(), other.month, 1);
+ let duration_since = self_chrono.signed_duration_since(other_chrono);
+ let months_since = duration_since.num_days() / 30;
+ if months_since < 0 {
+ None
+ } else {
+ Some(months_since.try_into().unwrap())
+ }
+ }
+}
+
+impl fmt::Display for Date {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:04}-{:02}", self.year, self.month)
+ }
+}
+
+fn make_date_regex() -> Regex {
+ Regex::new(
+ r"(?x) # insignificant whitespace mode
+ <!--\s*
+ [dD]ate:\s*
+ (?P<y>\d{4}) # year
+ -
+ (?P<m>\d{2}) # month
+ \s*-->",
+ )
+ .unwrap()
+}
+
+fn collect_dates_from_file(date_regex: &Regex, text: &str) -> Vec<(usize, Date)> {
+ let mut line = 1;
+ let mut end_of_last_cap = 0;
+ date_regex
+ .captures_iter(&text)
+ .map(|cap| {
+ (
+ cap.get(0).unwrap().range(),
+ Date {
+ year: cap["y"].parse().unwrap(),
+ month: cap["m"].parse().unwrap(),
+ },
+ )
+ })
+ .map(|(byte_range, date)| {
+ line += text[end_of_last_cap..byte_range.end]
+ .chars()
+ .filter(|c| *c == '\n')
+ .count();
+ end_of_last_cap = byte_range.end;
+ (line, date)
+ })
+ .collect()
+}
+
+fn collect_dates(paths: impl Iterator<Item = PathBuf>) -> BTreeMap<PathBuf, Vec<(usize, Date)>> {
+ let date_regex = make_date_regex();
+ let mut data = BTreeMap::new();
+ for path in paths {
+ let text = fs::read_to_string(&path).unwrap();
+ let dates = collect_dates_from_file(&date_regex, &text);
+ if !dates.is_empty() {
+ data.insert(path, dates);
+ }
+ }
+ data
+}
+
+fn filter_dates(
+ current_month: Date,
+ min_months_since: u32,
+ dates_by_file: impl Iterator<Item = (PathBuf, Vec<(usize, Date)>)>,
+) -> impl Iterator<Item = (PathBuf, Vec<(usize, Date)>)> {
+ dates_by_file
+ .map(move |(path, dates)| {
+ (
+ path,
+ dates
+ .into_iter()
+ .filter(|(_, date)| {
+ current_month
+ .months_since(*date)
+ .expect("found date that is after current month")
+ >= min_months_since
+ })
+ .collect::<Vec<_>>(),
+ )
+ })
+ .filter(|(_, dates)| !dates.is_empty())
+}
+
+fn main() {
+ let root_dir = env::args()
+ .nth(1)
+ .expect("expect root Markdown directory as CLI argument");
+ let root_dir_path = Path::new(&root_dir);
+ let glob_pat = format!("{}/**/*.md", root_dir);
+ let today_chrono = Utc::today();
+ let current_month = Date {
+ year: today_chrono.year_ce().1,
+ month: today_chrono.month(),
+ };
+
+ let dates_by_file = collect_dates(glob(&glob_pat).unwrap().map(Result::unwrap));
+ let dates_by_file: BTreeMap<_, _> =
+ filter_dates(current_month, 6, dates_by_file.into_iter()).collect();
+
+ if dates_by_file.is_empty() {
+ println!("empty");
+ } else {
+ println!("Date Reference Triage for {}", current_month);
+ println!("## Procedure");
+ println!();
+ println!(
+ "Each of these dates should be checked to see if the docs they annotate are \
+ up-to-date. Each date should be updated (in the Markdown file where it appears) to \
+ use the current month ({current_month}), or removed if the docs it annotates are not \
+ expected to fall out of date quickly.",
+ current_month = current_month
+ );
+ println!();
+ println!(
+ "Please check off each date once a PR to update it (and, if applicable, its \
+ surrounding docs) has been merged. Please also mention that you are working on a \
+ particular set of dates so duplicate work is avoided."
+ );
+ println!();
+ println!("Finally, once all the dates have been updated, please close this issue.");
+ println!();
+ println!("## Dates");
+ println!();
+
+ for (path, dates) in dates_by_file {
+ println!(
+ "- [ ] {}",
+ path.strip_prefix(&root_dir_path).unwrap().display()
+ );
+ for (line, date) in dates {
+ println!(" - [ ] line {}: {}", line, date);
+ }
+ }
+ println!();
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_months_since() {
+ let date1 = Date {
+ year: 2020,
+ month: 3,
+ };
+ let date2 = Date {
+ year: 2021,
+ month: 1,
+ };
+ assert_eq!(date2.months_since(date1), Some(10));
+ }
+
+ #[test]
+ fn test_date_regex() {
+ let regex = make_date_regex();
+ assert!(regex.is_match("foo <!-- date: 2021-01 --> bar"));
+ }
+
+ #[test]
+ fn test_date_regex_capitalized() {
+ let regex = make_date_regex();
+ assert!(regex.is_match("foo <!-- Date: 2021-08 --> bar"));
+ }
+
+ #[test]
+ fn test_collect_dates_from_file() {
+ let text = "Test1\n<!-- date: 2021-01 -->\nTest2\nFoo<!-- date: 2021-02 \
+ -->\nTest3\nTest4\nFoo<!-- date: 2021-03 -->Bar\n<!-- date: 2021-04 \
+ -->\nTest5\nTest6\nTest7\n<!-- date: \n\n2021-05 -->\nTest8
+ ";
+ assert_eq!(
+ collect_dates_from_file(&make_date_regex(), text),
+ vec![
+ (
+ 2,
+ Date {
+ year: 2021,
+ month: 1,
+ }
+ ),
+ (
+ 4,
+ Date {
+ year: 2021,
+ month: 2,
+ }
+ ),
+ (
+ 7,
+ Date {
+ year: 2021,
+ month: 3,
+ }
+ ),
+ (
+ 8,
+ Date {
+ year: 2021,
+ month: 4,
+ }
+ ),
+ (
+ 14,
+ Date {
+ year: 2021,
+ month: 5,
+ }
+ ),
+ ]
+ );
+ }
+}
diff --git a/src/doc/rustc-dev-guide/ci/linkcheck.sh b/src/doc/rustc-dev-guide/ci/linkcheck.sh
new file mode 100755
index 000000000..5d49d1337
--- /dev/null
+++ b/src/doc/rustc-dev-guide/ci/linkcheck.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+set -e
+set -o pipefail
+
+# https://docs.github.com/en/actions/reference/environment-variables
+if [ "$GITHUB_EVENT_NAME" = "schedule" ] ; then # running in scheduled job
+ FLAGS=""
+
+ echo "Doing full link check."
+ set -x
+elif [ "$GITHUB_EVENT_NAME" = "pull_request" ] ; then # running in PR CI build
+ if [ -z "$BASE_SHA" ]; then
+ echo "error: unexpected state: BASE_SHA must be non-empty in CI"
+ exit 1
+ fi
+
+ CHANGED_FILES=$(git diff --name-only $BASE_SHA... | tr '\n' ' ')
+ FLAGS="--no-cache -f $CHANGED_FILES"
+
+ echo "Checking files changed since $BASE_SHA: $CHANGED_FILES"
+ set -x
+else # running locally
+ COMMIT_RANGE=master...
+ CHANGED_FILES=$(git diff --name-only $COMMIT_RANGE | tr '\n' ' ')
+ FLAGS="-f $CHANGED_FILES"
+
+ echo "Checking files changed in $COMMIT_RANGE: $CHANGED_FILES"
+fi
+
+exec mdbook-linkcheck $FLAGS