Skip to content

Commit d49fdbb

Browse files
committed
new_run
1 parent b622ffe commit d49fdbb

File tree

10 files changed

+60
-129
lines changed

10 files changed

+60
-129
lines changed

Cargo.lock

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

lib/api_run/src/run.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,16 @@ async fn post_inner(
6565
.await?
6666
};
6767

68-
if let Some(auth_user) = auth_user.as_ref() {
69-
query_project.try_allowed(&context.rbac, auth_user, Permission::Create)?;
70-
} else if !query_project.is_unclaimed(conn_lock!(context))? {
71-
return Err(unauthorized_error(format!(
72-
"This project ({}) has already been claimed.",
73-
query_project.slug
74-
)));
68+
// If a project is unclaimed, don't check permissions
69+
if !query_project.is_unclaimed(conn_lock!(context))? {
70+
if let Some(auth_user) = auth_user.as_ref() {
71+
query_project.try_allowed(&context.rbac, auth_user, Permission::Create)?;
72+
} else {
73+
return Err(unauthorized_error(format!(
74+
"This project ({}) has already been claimed.",
75+
query_project.slug
76+
)));
77+
}
7578
}
7679
QueryReport::create(
7780
log,

lib/bencher_context/src/client/mod.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ const ROOT: &str = "root";
1414
#[allow(clippy::multiple_inherent_impl)]
1515
impl RunContext {
1616
pub fn current() -> Self {
17-
get_context()
17+
let mut context = RunContext::default();
18+
git_context(&mut context);
19+
platform_context(&mut context);
20+
context
1821
}
1922

2023
fn insert(&mut self, path: &str, value: String) -> Option<String> {
@@ -30,13 +33,6 @@ impl From<RunContext> for HashMap<String, String> {
3033
}
3134
}
3235

33-
pub fn get_context() -> RunContext {
34-
let mut context = RunContext::default();
35-
git_context(&mut context);
36-
platform_context(&mut context);
37-
context
38-
}
39-
4036
fn git_context(context: &mut RunContext) {
4137
let Some(repo) = find_repo() else {
4238
return;

services/cli/Cargo.toml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@ publish = false
88

99
[features]
1010
default = ["plus"]
11-
plus = [
12-
"bencher_client/plus",
13-
"bencher_comment/plus",
14-
"bencher_json/plus"
15-
]
11+
plus = ["bencher_client/plus", "bencher_comment/plus", "bencher_json/plus"]
1612

1713
[build-dependencies]
1814
bencher_context = { workspace = true, features = ["client"] }
@@ -26,7 +22,6 @@ bencher_json = { workspace = true, features = ["client", "table"] }
2622
camino.workspace = true
2723
chrono = { workspace = true, features = ["clock"] }
2824
clap = { workspace = true, features = ["env"] }
29-
gix = { workspace = true, features = ["revision"] }
3025
literally.workspace = true
3126
octocrab.workspace = true
3227
progenitor-client.workspace = true

services/cli/src/bencher/sub/run/branch.rs

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
use bencher_json::{project::branch::BRANCH_MAIN_STR, GitHash, NameId};
1+
use bencher_json::{GitHash, NameId};
22

3-
use crate::{
4-
bencher::sub::project::branch::start_point::StartPoint,
5-
parser::run::{CliRunBranch, CliRunHash},
6-
};
3+
use crate::{bencher::sub::project::branch::start_point::StartPoint, parser::run::CliRunBranch};
74

85
#[allow(clippy::struct_field_names)]
96
#[derive(Debug, Clone)]
107
pub struct Branch {
11-
branch: NameId,
8+
branch: Option<NameId>,
129
hash: Option<GitHash>,
1310
start_point: StartPoint,
1411
}
@@ -33,8 +30,6 @@ impl TryFrom<CliRunBranch> for Branch {
3330
start_point_reset,
3431
deprecated: _,
3532
} = run_branch;
36-
let branch = try_branch(branch)?;
37-
let hash = map_hash(hash);
3833
let start_point = map_start_point(
3934
start_point,
4035
start_point_hash,
@@ -50,47 +45,6 @@ impl TryFrom<CliRunBranch> for Branch {
5045
}
5146
}
5247

53-
fn try_branch(branch: Option<NameId>) -> Result<NameId, BranchError> {
54-
if let Some(branch) = branch {
55-
Ok(branch)
56-
} else if let Some(branch) = find_branch() {
57-
Ok(branch)
58-
} else {
59-
BRANCH_MAIN_STR.parse().map_err(BranchError::ParseBranch)
60-
}
61-
}
62-
63-
fn find_branch() -> Option<NameId> {
64-
if let Some(repo) = find_repo() {
65-
if let Ok(Some(branch)) = repo.head_name() {
66-
return branch.shorten().to_string().parse().ok();
67-
}
68-
}
69-
None
70-
}
71-
72-
fn map_hash(CliRunHash { hash, no_hash }: CliRunHash) -> Option<GitHash> {
73-
if let Some(hash) = hash {
74-
return Some(hash);
75-
} else if no_hash {
76-
return None;
77-
}
78-
let repo = find_repo()?;
79-
let head_id = repo.head_id().ok()?;
80-
let head_object = head_id.object().ok()?;
81-
Some(head_object.id.into())
82-
}
83-
84-
pub fn find_repo() -> Option<gix::Repository> {
85-
let current_dir = std::env::current_dir().ok()?;
86-
for directory in current_dir.ancestors() {
87-
if let Ok(repo) = gix::open(directory) {
88-
return Some(repo);
89-
}
90-
}
91-
None
92-
}
93-
9448
#[allow(clippy::needless_pass_by_value)]
9549
fn map_start_point(
9650
start_point: Vec<String>,
@@ -115,13 +69,13 @@ fn map_start_point(
11569

11670
impl From<Branch>
11771
for (
118-
bencher_client::types::NameId,
72+
Option<bencher_client::types::NameId>,
11973
Option<bencher_client::types::GitHash>,
12074
Option<bencher_client::types::JsonUpdateStartPoint>,
12175
)
12276
{
12377
fn from(branch: Branch) -> Self {
124-
let name = branch.branch.into();
78+
let name = branch.branch.map(Into::into);
12579
let hash = branch.hash.map(Into::into);
12680
let start_point = branch.start_point.into();
12781
(name, hash, start_point)

services/cli/src/bencher/sub/run/mod.rs

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::{future::Future, pin::Pin};
22

3-
use bencher_client::types::{Adapter, JsonAverage, JsonFold, JsonNewReport, JsonReportSettings};
3+
use bencher_client::types::{Adapter, JsonAverage, JsonFold, JsonNewRun, JsonReportSettings};
44
use bencher_comment::ReportComment;
5-
use bencher_json::{DateTime, JsonReport, NameId, ResourceId};
5+
use bencher_json::{DateTime, JsonReport, NameId, ResourceId, RunContext};
66

77
use crate::{
8-
bencher::backend::AuthBackend,
8+
bencher::backend::PubBackend,
99
cli_eprintln_quietable, cli_println, cli_println_quietable,
1010
parser::run::{CliRun, CliRunOutput},
1111
CliError,
@@ -32,9 +32,9 @@ use super::project::report::Thresholds;
3232
#[derive(Debug)]
3333
#[allow(clippy::struct_excessive_bools)]
3434
pub struct Run {
35-
project: ResourceId,
35+
project: Option<ResourceId>,
3636
branch: Branch,
37-
testbed: NameId,
37+
testbed: Option<NameId>,
3838
adapter: Adapter,
3939
sub_adapter: SubAdapter,
4040
average: Option<JsonAverage>,
@@ -50,7 +50,7 @@ pub struct Run {
5050
runner: Runner,
5151
#[allow(clippy::struct_field_names)]
5252
dry_run: bool,
53-
backend: AuthBackend,
53+
backend: PubBackend,
5454
}
5555

5656
impl TryFrom<CliRun> for Run {
@@ -76,9 +76,9 @@ impl TryFrom<CliRun> for Run {
7676
backend,
7777
} = run;
7878
Ok(Self {
79-
project,
79+
project: project.map(Into::into),
8080
branch: branch.try_into().map_err(RunError::Branch)?,
81-
testbed,
81+
testbed: testbed.map(Into::into),
8282
adapter: adapter.into(),
8383
sub_adapter: (&cmd).into(),
8484
average: average.map(Into::into),
@@ -93,7 +93,7 @@ impl TryFrom<CliRun> for Run {
9393
ci: ci.try_into().map_err(RunError::Ci)?,
9494
runner: cmd.try_into()?,
9595
dry_run,
96-
backend: AuthBackend::try_from(backend)?.log(false),
96+
backend: PubBackend::try_from(backend)?.log(false),
9797
})
9898
}
9999
}
@@ -119,23 +119,23 @@ impl Run {
119119
ci.safety_check(self.log)?;
120120
}
121121

122-
let Some(json_new_report) = self.generate_report().await? else {
122+
let Some(json_new_run) = self.generate_report().await? else {
123123
return Ok(());
124124
};
125125

126126
cli_println_quietable!(self.log, "\nBencher New Report:");
127127
cli_println_quietable!(
128128
self.log,
129129
"{}",
130-
serde_json::to_string_pretty(&json_new_report).map_err(RunError::SerializeReport)?
130+
serde_json::to_string_pretty(&json_new_run).map_err(RunError::SerializeReport)?
131131
);
132132

133133
// If performing a dry run, don't actually send the report
134134
if self.dry_run {
135135
return Ok(());
136136
}
137137

138-
let sender = report_sender(self.project.clone(), json_new_report);
138+
let sender = run_sender(json_new_run);
139139
let json_report: JsonReport = self
140140
.backend
141141
.send_with(sender)
@@ -152,7 +152,7 @@ impl Run {
152152
}
153153
}
154154

155-
async fn generate_report(&self) -> Result<Option<JsonNewReport>, RunError> {
155+
async fn generate_report(&self) -> Result<Option<JsonNewRun>, RunError> {
156156
let start_time = DateTime::now();
157157
let mut results = Vec::with_capacity(self.iter);
158158
for _ in 0..self.iter {
@@ -184,11 +184,12 @@ impl Run {
184184
};
185185

186186
let (branch, hash, start_point) = self.branch.clone().into();
187-
Ok(Some(JsonNewReport {
187+
Ok(Some(JsonNewRun {
188+
project: self.project.clone().map(Into::into),
188189
branch,
189190
hash,
190191
start_point,
191-
testbed: self.testbed.clone().into(),
192+
testbed: self.testbed.clone().map(Into::into),
192193
thresholds: self.thresholds.clone().into(),
193194
start_time: start_time.into(),
194195
end_time: end_time.into(),
@@ -198,8 +199,7 @@ impl Run {
198199
average: self.average,
199200
fold: self.fold,
200201
}),
201-
// TODO add context when we move over to JsonNewRun
202-
// context: Some(RunContext::current().into()),
202+
context: Some(RunContext::current().into()),
203203
}))
204204
}
205205

@@ -242,20 +242,11 @@ type ReportResult = Pin<
242242
> + Send,
243243
>,
244244
>;
245-
fn report_sender(
246-
project: ResourceId,
247-
json_new_report: JsonNewReport,
245+
fn run_sender(
246+
json_new_run: JsonNewRun,
248247
) -> Box<dyn Fn(bencher_client::Client) -> ReportResult + Send> {
249248
Box::new(move |client: bencher_client::Client| {
250-
let project = project.clone();
251-
let json_new_report = json_new_report.clone();
252-
Box::pin(async move {
253-
client
254-
.proj_report_post()
255-
.project(project.clone())
256-
.body(json_new_report.clone())
257-
.send()
258-
.await
259-
})
249+
let json_new_run = json_new_run.clone();
250+
Box::pin(async move { client.run_post().body(json_new_run.clone()).send().await })
260251
})
261252
}

services/cli/src/parser/run.rs

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use bencher_json::{
2-
project::testbed::TESTBED_LOCALHOST_STR, DateTime, GitHash, NameId, ResourceId,
3-
};
1+
use bencher_json::{DateTime, GitHash, NameId, ResourceId};
42
use camino::Utf8PathBuf;
53
use clap::{ArgGroup, Args, Parser, ValueEnum};
64

@@ -15,15 +13,15 @@ use super::project::report::{
1513
pub struct CliRun {
1614
/// Project slug or UUID
1715
#[clap(long, env = "BENCHER_PROJECT")]
18-
pub project: ResourceId,
16+
pub project: Option<ResourceId>,
1917

2018
#[clap(flatten)]
2119
pub branch: CliRunBranch,
2220

2321
/// Testbed name, slug, or UUID.
2422
/// If a name or slug is provided, the testbed will be created if it does not exist.
25-
#[clap(long, env = "BENCHER_TESTBED", default_value = TESTBED_LOCALHOST_STR)]
26-
pub testbed: NameId,
23+
#[clap(long, env = "BENCHER_TESTBED")]
24+
pub testbed: Option<NameId>,
2725

2826
/// Benchmark harness adapter
2927
#[clap(value_enum, long, env = "BENCHER_ADAPTER", default_value = "magic")]
@@ -83,8 +81,9 @@ pub struct CliRunBranch {
8381
#[clap(long, env = "BENCHER_BRANCH", alias = "if-branch")]
8482
pub branch: Option<NameId>,
8583

86-
#[clap(flatten)]
87-
pub hash: CliRunHash,
84+
/// `git` commit hash (default HEAD)
85+
#[clap(long)]
86+
pub hash: Option<GitHash>,
8887

8988
/// Use the specified branch name, slug, or UUID as the start point for `branch`.
9089
/// If `branch` already exists and the start point is different, a new branch will be created.
@@ -115,26 +114,16 @@ pub struct CliRunBranch {
115114
pub start_point_reset: bool,
116115

117116
/// Deprecated: Do not use. This will soon be removed.
118-
#[clap(long, hide = true, alias = "else-branch", alias = "endif-branch")]
117+
#[clap(
118+
long,
119+
hide = true,
120+
alias = "else-branch",
121+
alias = "endif-branch",
122+
alias = "no-hash"
123+
)]
119124
pub deprecated: bool,
120125
}
121126

122-
#[derive(Args, Debug)]
123-
#[clap(group(
124-
ArgGroup::new("run_hash")
125-
.multiple(false)
126-
.args(&["hash", "no_hash"]),
127-
))]
128-
pub struct CliRunHash {
129-
/// `git` commit hash (default HEAD)
130-
#[clap(long)]
131-
pub hash: Option<GitHash>,
132-
133-
/// Do not try to find a `git` commit hash
134-
#[clap(long)]
135-
pub no_hash: bool,
136-
}
137-
138127
#[derive(Args, Debug)]
139128
pub struct CliRunCommand {
140129
/// Track the build time of the benchmark command

services/console/src/chunks/docs-reference/changelog/en/changelog.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## Pending `v0.5.0`
2+
- Allow `bencher run` to create a project if it does not exist for both authenticated and anonymous users
3+
14
## `v0.4.37`
25
- Add dimension search in Threshold creation UI
36
- Add Threshold list to Branch, Testbed, and Measure pages in Console UI

0 commit comments

Comments
 (0)