Skip to content

Commit af88207

Browse files
authored
Merge pull request #1749 from Kobzol/src-change-defaults
Make it possible to run sync-team against local data
2 parents 4c2bdca + 339f44b commit af88207

File tree

7 files changed

+78
-49
lines changed

7 files changed

+78
-49
lines changed

.github/workflows/dry-run.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ jobs:
143143
cargo build --release
144144
./target/release/rust-team sync print-plan \
145145
--services github \
146-
--team-json team-api 2>&1 | tee -a output.txt
146+
--src team-api 2>&1 | tee -a output.txt
147147
148148
- name: Prepare comment
149149
run: |

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ jobs:
9797
ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
9898
ZULIP_USERNAME: ${{ secrets.ZULIP_USERNAME }}
9999
run: |
100-
RUST_LOG="sync_team=debug" cargo run sync apply --team-json build
100+
RUST_LOG="sync_team=debug" cargo run sync apply --src build
101101
102102
- name: Disable Jekyll
103103
run: touch build/.nojekyll

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ serde = "1"
2020
serde_derive = "1"
2121
serde_json = "1"
2222
serde-untagged = "0.1"
23+
tempfile = "3.19.1"
2324
toml = "0.8"
2425

2526
sync-team = { path = "sync-team" }

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,11 @@ cargo run -- sync --services github,mailgun
158158
cargo run -- sync --services github,mailgun apply
159159
```
160160

161-
By default, the synchronization will be based on data from the live `team` endpoint.
162-
When making changes to the tool it might be useful to test
163-
with dummy data though. You can do that by passing the `--team-repo` flag to the CLI:
161+
By default, the synchronization will be based on data from the current `team` repository checkout.
162+
You can also perform the sync based on the live `team` endpoint using `--src=production`, or on an existing directory on disk that contains the prebuilt JSON files using `--src=<path>`.
164163

165164
```
166-
cargo run -- sync --team-json <directory>
165+
cargo run -- sync --src=<directory>
167166
```
168167

169168
The `<directory>` with JSON data can be generated using `cargo run static-api`.

src/main.rs

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use clap::Parser;
2525
use log::{error, info, warn};
2626
use std::collections::{BTreeMap, HashMap};
2727
use std::path::PathBuf;
28+
use std::str::FromStr;
2829
use sync_team::run_sync_team;
2930
use sync_team::team_api::TeamApi;
3031

@@ -88,6 +89,9 @@ enum Cli {
8889
#[clap(subcommand)]
8990
Ci(CiOpts),
9091
/// Perform synchronization of the local data to live services.
92+
/// By default, a dry-run against the local team repository data
93+
/// is performed.
94+
///
9195
/// Environment variables:
9296
/// - GITHUB_TOKEN Authentication token with GitHub
9397
/// - MAILGUN_API_TOKEN Authentication token with Mailgun
@@ -114,19 +118,62 @@ struct SyncOpts {
114118
), value_delimiter = ',')]
115119
services: Vec<String>,
116120

117-
/// Path to a checkout of `rust-lang/team`.
118-
#[clap(long, global(true), conflicts_with = "team_json")]
119-
team_repo: Option<PathBuf>,
120-
121-
/// Path to a directory with prebuilt JSON data from the `team` repository.
122-
#[clap(long, global(true))]
123-
team_json: Option<PathBuf>,
124-
121+
/// Source of the data against which is the sync performed.
122+
/// Possible values:
123+
/// - in-tree => use the current team checkout
124+
/// - production => use the live REST API team endpoint
125+
/// - <path> => use prebuilt directory at <path>
126+
#[arg(
127+
long("src"),
128+
global(true),
129+
default_value = "in-tree",
130+
verbatim_doc_comment
131+
)]
132+
source: DataSource,
133+
134+
/// Command that should be performed.
125135
#[clap(subcommand)]
126136
command: Option<SyncCommand>,
127137
}
128138

129-
#[derive(clap::Parser, Debug)]
139+
#[derive(Clone, Debug)]
140+
enum DataSource {
141+
/// Load data from the current `team` repo checkout.
142+
InTree,
143+
/// Load data from a prebuilt directory with JSON files.
144+
Prebuilt {
145+
/// Location of the directory.
146+
path: PathBuf,
147+
},
148+
/// Load data from the production `team` REST API.
149+
Production,
150+
}
151+
152+
impl FromStr for DataSource {
153+
type Err = String;
154+
155+
fn from_str(input: &str) -> Result<Self, Self::Err> {
156+
match input {
157+
"in-tree" => Ok(Self::InTree),
158+
"production" => Ok(Self::Production),
159+
path => {
160+
let path = PathBuf::from(path);
161+
if path.is_dir() {
162+
Ok(Self::Prebuilt {
163+
path: PathBuf::from(path),
164+
})
165+
} else {
166+
Err(
167+
"--src must be a path to an existing directory, `in-tree` or `production`"
168+
.to_string(),
169+
)
170+
}
171+
}
172+
}
173+
}
174+
}
175+
176+
#[derive(clap::Parser, Clone, Debug)]
130177
enum SyncCommand {
131178
/// Try to apply changes, but do not send any outgoing API requests.
132179
DryRun,
@@ -451,7 +498,7 @@ fn run() -> Result<(), Error> {
451498
CiOpts::CheckCodeowners => check_codeowners(data)?,
452499
},
453500
Cli::Sync(opts) => {
454-
if let Err(err) = perform_sync(opts) {
501+
if let Err(err) = perform_sync(opts, data) {
455502
// Display shows just the first element of the chain.
456503
error!("failed: {}", err);
457504
for cause in err.chain().skip(1) {
@@ -492,13 +539,19 @@ fn dump_team_members(
492539
Ok(())
493540
}
494541

495-
fn perform_sync(opts: SyncOpts) -> anyhow::Result<()> {
496-
let team_api = if let Some(path) = opts.team_repo {
497-
TeamApi::Checkout(path)
498-
} else if let Some(path) = opts.team_json {
499-
TeamApi::Prebuilt(path)
500-
} else {
501-
TeamApi::Production
542+
fn perform_sync(opts: SyncOpts, data: Data) -> anyhow::Result<()> {
543+
// We pregenerate the directory here in case we need it, to make sure it lives
544+
// long enough.
545+
let source_dir = tempfile::tempdir()?;
546+
547+
let team_api = match opts.source {
548+
DataSource::InTree => {
549+
// Render the current data to a temporary directory
550+
static_api::Generator::new(source_dir.path(), &data)?.generate()?;
551+
TeamApi::Prebuilt(source_dir.path().to_path_buf())
552+
}
553+
DataSource::Prebuilt { path } => TeamApi::Prebuilt(path),
554+
DataSource::Production => TeamApi::Production,
502555
};
503556

504557
let mut services = opts.services;

sync-team/src/team_api.rs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
use crate::utils::ResponseExt;
2-
use log::{debug, info, trace};
2+
use log::{debug, trace};
33
use std::borrow::Cow;
44
use std::path::PathBuf;
5-
use std::process::Command;
65

76
/// Determines how do we get access to the ground-truth data from `rust-lang/team`.
87
pub enum TeamApi {
98
/// Access the live data from the published production REST API.
109
Production,
11-
/// Build the JSON data from a checkout of `rust-lang/team`.
12-
Checkout(PathBuf),
1310
/// Directly access a directory with prebuilt JSON data.
1411
Prebuilt(PathBuf),
1512
}
@@ -62,28 +59,6 @@ impl TeamApi {
6259
.error_for_status()?
6360
.json_annotated()?)
6461
}
65-
TeamApi::Checkout(path) => {
66-
let dest = tempfile::tempdir()?;
67-
info!(
68-
"generating the content of the Team API from {}",
69-
path.display()
70-
);
71-
let status = Command::new("cargo")
72-
.arg("run")
73-
.arg("--")
74-
.arg("static-api")
75-
.arg(dest.path())
76-
.env("RUST_LOG", "rust_team=warn")
77-
.current_dir(path)
78-
.status()?;
79-
if status.success() {
80-
info!("contents of the Team API generated successfully");
81-
let contents = std::fs::read(dest.path().join("v1").join(url))?;
82-
Ok(serde_json::from_slice(&contents)?)
83-
} else {
84-
anyhow::bail!("failed to generate the contents of the Team API");
85-
}
86-
}
8762
TeamApi::Prebuilt(directory) => {
8863
let contents = std::fs::read(directory.join("v1").join(url))?;
8964
Ok(serde_json::from_slice(&contents)?)

0 commit comments

Comments
 (0)