Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b76204f
Allow non-default branch for remote registries
PaulDance May 3, 2021
dc0d9d2
Add documentation to `Config::get_registry_branch`
PaulDance May 3, 2021
7c49c65
Add dedicated test support for index alternative branches
PaulDance May 4, 2021
f1b50ce
Implement unit tests for `Config::get_registry_branch`
PaulDance May 4, 2021
dbcae3c
Implement integration tests for index alternative branches
PaulDance May 5, 2021
6cd88ab
Fix package test support for alternative branches
PaulDance May 5, 2021
b571143
Fix an alt-registry-test's error output
PaulDance May 5, 2021
ad5393f
Better error message matching
PaulDance May 5, 2021
bcfe84d
Remove wrongly committed debugging
PaulDance May 5, 2021
3a7f544
Fix alternative registries' tests
PaulDance May 5, 2021
e4628eb
Fix some bugs related to normal registries
PaulDance May 5, 2021
12801a4
Fix the last bugs
PaulDance May 5, 2021
76dc0af
Missed reformat
PaulDance May 5, 2021
5262800
Additional cleanup after test publication
PaulDance May 5, 2021
b2d3b0b
Rename a config unit test
PaulDance May 6, 2021
274aec4
Hide alternative branches behind an unstable CLI option
PaulDance May 6, 2021
bff9689
Move alternative branch retrieval out of RemoteRegistry
PaulDance May 6, 2021
b7825cf
Reintroduce CLI unstable option gate
PaulDance May 6, 2021
da129d4
Fix test support for alternative branches
PaulDance May 7, 2021
128020b
Adapt alternative-branch tests to the feature
PaulDance May 7, 2021
554897b
Fix the alt_registry::no_api_alt_branch test
PaulDance May 7, 2021
eba17b0
Fix alt_registry::registries_index_alt_branch_relative_url
PaulDance May 7, 2021
e4d3a9d
Add another test for relative alternative registries
PaulDance May 7, 2021
f47ac9b
Improve registry test support performance a tad
PaulDance May 7, 2021
9ecdb18
Add unstable documentation for alternative branches
PaulDance May 7, 2021
1d0a9df
Merge branch 'master' into remote-index-branch
PaulDance May 7, 2021
7914e13
Merge branch 'master' into remote-index-branch
PaulDance May 10, 2021
bd14a23
Fix a small typo in features module
PaulDance May 21, 2021
b6aef31
Rename feature
PaulDance May 21, 2021
1635536
Fix documentation for `Config::get_registry_branch`
PaulDance May 21, 2021
3eb8020
Move alt-branch's git ref to SourceKind
PaulDance Feb 15, 2022
1113077
Merge remote-tracking branch 'upstream/master' into remote-index-branch
PaulDance Feb 15, 2022
375cef4
Fix tests
PaulDance Feb 15, 2022
e3b4bc3
Reformat registry module
PaulDance Feb 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions crates/cargo-test-support/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ use std::sync::Once;
use url::Url;

#[must_use]
pub struct RepoBuilder {
pub struct RepoBuilder<'br> {
repo: git2::Repository,
files: Vec<PathBuf>,
branches: Vec<&'br str>,
}

pub struct Repository(git2::Repository);
Expand All @@ -59,33 +60,40 @@ pub fn repo(p: &Path) -> RepoBuilder {
RepoBuilder::init(p)
}

impl RepoBuilder {
pub fn init(p: &Path) -> RepoBuilder {
impl<'br> RepoBuilder<'br> {
pub fn init(p: &Path) -> Self {
t!(fs::create_dir_all(p.parent().unwrap()));
let repo = init(p);
RepoBuilder {
repo,
files: Vec::new(),
branches: Vec::new(),
}
}

/// Add a file to the repository.
pub fn file(self, path: &str, contents: &str) -> RepoBuilder {
pub fn file(self, path: &str, contents: &str) -> Self {
let mut me = self.nocommit_file(path, contents);
me.files.push(PathBuf::from(path));
me
}

/// Add a file that will be left in the working directory, but not added
/// to the repository.
pub fn nocommit_file(self, path: &str, contents: &str) -> RepoBuilder {
pub fn nocommit_file(self, path: &str, contents: &str) -> Self {
let dst = self.repo.workdir().unwrap().join(path);
t!(fs::create_dir_all(dst.parent().unwrap()));
t!(fs::write(&dst, contents));
self
}

/// Create the repository and commit the new files.
/// Add a branch to the repository pointing at the first commit.
pub fn branch(mut self, name: &'br str) -> Self {
self.branches.push(name);
self
}

/// Create the repository, commit the new files and create the new branches.
pub fn build(self) -> Repository {
{
let mut index = t!(self.repo.index());
Expand All @@ -96,10 +104,17 @@ impl RepoBuilder {
let id = t!(index.write_tree());
let tree = t!(self.repo.find_tree(id));
let sig = t!(self.repo.signature());
t!(self
.repo
.commit(Some("HEAD"), &sig, &sig, "Initial commit", &tree, &[]));
let head_id =
t!(self
.repo
.commit(Some("HEAD"), &sig, &sig, "Initial commit", &tree, &[]));
let head_commit = t!(self.repo.find_commit(head_id));

for branch in self.branches.iter().copied() {
t!(self.repo.branch(branch, &head_commit, false));
}
}

let RepoBuilder { repo, .. } = self;
Repository(repo)
}
Expand Down
118 changes: 107 additions & 11 deletions crates/cargo-test-support/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ pub fn alt_registry_path() -> PathBuf {
pub fn alt_registry_url() -> Url {
generate_url("alternative-registry")
}
/// The name of the alternative registry's alternative index branch.
pub const ALT_REG_IDX_ALT_BR: &str = "alternative-branch";
/// Gets the alternative-registry version of `dl_path`.
pub fn alt_dl_path() -> PathBuf {
generate_path("alt_dl")
Expand Down Expand Up @@ -78,6 +80,9 @@ pub struct RegistryBuilder {
replace_crates_io: bool,
/// If `true`, configures a registry named "alternative".
alternative: bool,
/// If `true` and [`alternative`] is also, configures a registry named
/// "alternative" with the "alternative-branch" index branch.
alternative_branch: bool,
/// If set, sets the API url for the "alternative" registry.
/// This defaults to a directory on the filesystem.
alt_api_url: Option<String>,
Expand All @@ -90,6 +95,7 @@ impl RegistryBuilder {
RegistryBuilder {
replace_crates_io: true,
alternative: false,
alternative_branch: false,
alt_api_url: None,
add_tokens: true,
}
Expand All @@ -109,6 +115,14 @@ impl RegistryBuilder {
self
}

/// Sets whether or not to initialize the "alternative" registry's index
/// onto the "alternative-branch" branch if said registry is set.
/// Default is `false`.
pub fn alternative_branch(&mut self, alt_br: bool) -> &mut Self {
self.alternative_branch = alt_br;
self
}

/// Sets the API url for the "alternative" registry.
/// Defaults to a path on the filesystem ([`alt_api_path`]).
pub fn alternative_api_url(&mut self, url: &str) -> &mut Self {
Expand Down Expand Up @@ -152,14 +166,18 @@ impl RegistryBuilder {
}
if self.alternative {
write!(
config,
&mut config,
"
[registries.alternative]
index = '{}'
",
alt_registry_url()
)
.unwrap();

if self.alternative_branch {
write!(&mut config, "branch = '{}'\n", ALT_REG_IDX_ALT_BR).unwrap()
}
}
t!(fs::write(&config_path, config));

Expand All @@ -178,7 +196,13 @@ impl RegistryBuilder {
}

if self.replace_crates_io {
init_registry(registry_path(), dl_url().into(), api_url(), api_path());
init_registry(
registry_path(),
dl_url().into(),
api_url(),
api_path(),
false,
);
}

if self.alternative {
Expand All @@ -189,6 +213,7 @@ impl RegistryBuilder {
.as_ref()
.map_or_else(alt_api_url, |url| Url::parse(url).expect("valid url")),
alt_api_path(),
self.alternative_branch,
);
}
}
Expand Down Expand Up @@ -316,6 +341,7 @@ pub struct Package {
features: FeatureMap,
local: bool,
alternative: bool,
alternative_branch: bool,
invalid_json: bool,
proc_macro: bool,
links: Option<String>,
Expand Down Expand Up @@ -367,15 +393,36 @@ pub fn alt_init() {
RegistryBuilder::new().alternative(true).build();
}

/// Creates a new on-disk registry.
pub fn init_registry(registry_path: PathBuf, dl_url: String, api_url: Url, api_path: PathBuf) {
// Initialize a new registry.
repo(&registry_path)
.file(
"config.json",
&format!(r#"{{"dl":"{}","api":"{}"}}"#, dl_url, api_url),
)
/// Variant of `alt_init` that also initializes the alternative registry index'
/// alternative branch.
pub fn alt_br_init() {
RegistryBuilder::new()
.alternative(true)
.alternative_branch(true)
.build();
}

/// Creates a new on-disk registry. If `alt_br` is `true`, then an alternative
/// index branch is created pointing at the first commit.
pub fn init_registry(
registry_path: PathBuf,
dl_url: String,
api_url: Url,
api_path: PathBuf,
alt_br: bool,
) {
// Initialize a new registry.
let rb = repo(&registry_path).file(
"config.json",
&format!(r#"{{"dl":"{}","api":"{}"}}"#, dl_url, api_url),
);

if alt_br {
rb.branch(ALT_REG_IDX_ALT_BR)
} else {
rb
}
.build();
fs::create_dir_all(api_path.join("api/v1/crates")).unwrap();
}

Expand All @@ -393,6 +440,7 @@ impl Package {
features: BTreeMap::new(),
local: false,
alternative: false,
alternative_branch: false,
invalid_json: false,
proc_macro: false,
links: None,
Expand Down Expand Up @@ -424,6 +472,20 @@ impl Package {
self
}

/// Call with `true` to register a publication in an "alternative registry"
/// index' alternative branch.
///
/// [`alternative()`] must be set to use this non-default branch.
/// The name of the alternative branch is called "alternative-branch".
///
/// See `src/doc/src/reference/registries.md` for more details on
/// alternative registries. See `alt_registry.rs` for the tests that use
/// this.
pub fn alternative_branch(&mut self, alt_br: bool) -> &mut Package {
self.alternative_branch = alt_br;
self
}

/// Adds a file to the package.
pub fn file(&mut self, name: &str, contents: &str) -> &mut Package {
self.file_with_mode(name, DEFAULT_MODE, contents)
Expand Down Expand Up @@ -647,7 +709,29 @@ impl Package {

// Add the new file to the index.
if !self.local {
// Record the publication on the alternative branch if configured.
let branch_refname: &str = &format!(
"refs/heads/{}",
if self.alternative && self.alternative_branch {
ALT_REG_IDX_ALT_BR
} else {
"master"
}
);
let repo = t!(git2::Repository::open(&registry_path));

// Switch branch only if not on the correct one to save a bit of time.
if t!(repo.head()).name().unwrap() != branch_refname {
t!(repo.set_head(branch_refname));
// Reset from HEAD in order to properly switch to the desired branch.
t!(repo.reset(
&t!(t!(repo.head()).peel(git2::ObjectType::Any)),
git2::ResetType::Mixed,
None
));
}

// Write to the index and create a tree.
let mut index = t!(repo.index());
t!(index.add_path(Path::new(&file)));
t!(index.write());
Expand All @@ -656,7 +740,7 @@ impl Package {
// Commit this change.
let tree = t!(repo.find_tree(id));
let sig = t!(repo.signature());
let parent = t!(repo.refname_to_id("refs/heads/master"));
let parent = t!(repo.refname_to_id(branch_refname));
let parent = t!(repo.find_commit(parent));
t!(repo.commit(
Some("HEAD"),
Expand All @@ -666,6 +750,18 @@ impl Package {
&tree,
&[&parent]
));

// Put the HEAD back in order to reposition the default branch: the
// current repository acts as a remote for client indices which
// use `refs/remotes/origin/HEAD` to determine the default branch.
if branch_refname != "refs/heads/master" {
t!(repo.set_head("refs/heads/master"));
t!(repo.reset(
&t!(t!(repo.head()).peel(git2::ObjectType::Any)),
git2::ResetType::Hard,
None
));
}
}

cksum
Expand Down
4 changes: 3 additions & 1 deletion src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ unstable_cli_options!(
print_im_a_teapot: bool= (HIDDEN),

// All other unstable features.
// Please keep this list lexiographically ordered.
// Please keep this list lexicographically ordered.
advanced_env: bool = (HIDDEN),
avoid_dev_deps: bool = ("Avoid installing dev-dependencies if possible"),
binary_dep_depinfo: bool = ("Track changes to dependency artifacts"),
Expand All @@ -647,6 +647,7 @@ unstable_cli_options!(
multitarget: bool = ("Allow passing multiple `--target` flags to the cargo subcommand selected"),
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
registry_branches: bool = ("Enable the `branch` key for alternative registries in `.cargo/config.toml` files"),
host_config: bool = ("Enable the [host] section in the .cargo/config.toml file"),
target_applies_to_host: bool = ("Enable the `target-applies-to-host` key in the .cargo/config.toml file"),
rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"),
Expand Down Expand Up @@ -884,6 +885,7 @@ impl CliUnstable {
}
}
"skip-rustdoc-fingerprint" => self.skip_rustdoc_fingerprint = parse_empty(k, v)?,
"registry-branches" => self.registry_branches = parse_empty(k, v)?,
"compile-progress" => stabilized_warn(k, "1.30", STABILIZED_COMPILE_PROGRESS),
"offline" => stabilized_err(k, "1.36", STABILIZED_OFFLINE)?,
"cache-messages" => stabilized_warn(k, "1.40", STABILIZED_CACHE_MESSAGES),
Expand Down
Loading