-
-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add draft of proposed new library API. #600
Draft
obi1kenobi
wants to merge
2
commits into
main
Choose a base branch
from
proposed_new_lib_api
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct CheckGroup { | ||
/// All the checks we should run. | ||
checks: Vec<CrateCheck>, | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct CrateCheck { | ||
/// The version we are interested in semver-checking. | ||
current_version: CrateVersion, | ||
|
||
/// The version we are comparing the current version against. | ||
baseline_version: CrateVersion, | ||
|
||
/// Optionally, override what kind of release this is and therefore which lints we check. | ||
/// | ||
/// If `None`, we'll determine the appropriate lints based on the version numbers | ||
/// of the current and baseline crate versions. | ||
assume_release_type: Option<ReleaseType> | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct CrateVersion { | ||
/// The name of the crate we're checking. | ||
crate_name: String, | ||
|
||
/// Where are we getting the source code for this crate version from? | ||
source: Source, | ||
|
||
/// Which group of features to enable: all features, default features, no features, | ||
/// or use our own heuristic that aims to select all intended-to-be-public features. | ||
/// | ||
/// TODO: move `FeaturesGroup` out of `rustdoc_gen.rs` and make it `pub` and `#[non_exhaustive]` | ||
features_group: FeaturesGroup, | ||
|
||
/// Additional features to enable, on top of the ones selected by `features_group`. | ||
extra_features: Vec<String>, | ||
|
||
/// What to do if the specified version has no library target, only binary targets. | ||
/// | ||
/// In this situation, there's no API to semver-check since this version | ||
/// cannot be used as a lib dependency, regardless of which APIs are declared `pub`. | ||
if_package_has_no_library_target: OnUnexpectedOutcome, | ||
|
||
/// What to do if a requested feature does not exist. | ||
if_feature_does_not_exist: OnUnexpectedOutcome, | ||
|
||
/// What to do if we failed to generate or parse rustdoc. | ||
/// | ||
/// For example, if the package fails to compile with the current Rust version and rustflags. | ||
if_failed_to_get_rustdoc: OnUnexpectedOutcome, | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub enum Source { | ||
/// Load the crate's data from local source code. | ||
ManifestPath(ManifestPath), | ||
|
||
/// Load the crate's data from a specific git revision in a local repo. | ||
ManifestGitRevision(ManifestGitRevision), | ||
|
||
/// Load the crate's data from a specific version on crates.io. | ||
ExactRegistryVersion(ExactRegistryVersion), | ||
|
||
/// Load the crate's data by selecting a version from crates.io based on specific requirements. | ||
PredicateRegistryVersion(PredicateRegistryVersion), | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct ManifestPath { | ||
/// The `Cargo.toml` of the workspace containing the crate to check, | ||
/// or the crate's own `Cargo.toml` if the crate isn't part of a workspace. | ||
root_manifest: std::path::PathBuf, | ||
|
||
/// If we failed to open, read, or parse the root manifest file at the specified path. | ||
if_failed_to_read_root_manifest: OnUnexpectedOutcome, | ||
|
||
/// If we opened the manifest but did not find the specified package inside it. | ||
if_failed_to_find_package: OnUnexpectedOutcome, | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct ManifestGitRevision { | ||
/// Path to the repository's root directory. | ||
repo: std::path::PathBuf, | ||
|
||
/// The git revision we should check out and use for semver-checking. | ||
rev: String, | ||
|
||
/// Path (relative to the repo root) to the `Cargo.toml` of the workspace | ||
/// containing the crate to check, or to the crate's own `Cargo.toml` | ||
/// if the crate isn't part of a workspace. | ||
root_manifest: std::path::PathBuf, | ||
|
||
/// If we failed to use the git repo and check out the revision. | ||
/// For example, if the repo path is incorrect or the specified revision doesn't exist. | ||
if_failed_to_check_out_rev: OnUnexpectedOutcome, | ||
|
||
/// If we failed to open, read, or parse the root manifest file at the specified path. | ||
if_failed_to_read_root_manifest: OnUnexpectedOutcome, | ||
|
||
/// If we opened the manifest but did not find the specified package inside it. | ||
/// For example, perhaps the package does not yet exist at the specified revision. | ||
if_failed_to_find_package: OnUnexpectedOutcome, | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct ExactRegistryVersion { | ||
/// The crate version to check. | ||
version: semver::Version, | ||
|
||
/// If we aren't able to use the registry, for example due to a connection error. | ||
if_failed_to_use_registry: OnUnexpectedOutcome, | ||
|
||
/// If we connected to the registry but could not find the specified package. | ||
if_failed_to_find_package: OnUnexpectedOutcome, | ||
|
||
/// If the registry knows about the package, but does not have the specified version. | ||
if_failed_to_find_package_version: OnUnexpectedOutcome, | ||
|
||
/// If the registry has the specified version but it is not usable for semver-checking: | ||
/// for example, if it has been yanked (we won't be able to generate rustdoc for it). | ||
if_version_is_unusable: OnUnexpectedOutcome, | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct PredicateRegistryVersion { | ||
/// The way to select the version. | ||
predicate: VersionPredicate, | ||
|
||
/// Whether to consider pre-release versions or not. | ||
/// | ||
/// Note that breaking changes are always allowed between pre-releases, | ||
/// and between a pre-release and a corresponding normal release. | ||
allow_prereleases: bool, | ||
|
||
/// Whether we should automatically ignore yanked releases. | ||
ignore_yanked: bool, | ||
|
||
/// If we aren't able to use the registry, for example due to a connection error. | ||
if_failed_to_use_registry: OnUnexpectedOutcome, | ||
|
||
/// If we connected to the registry but could not find the specified package. | ||
if_failed_to_find_package: OnUnexpectedOutcome, | ||
|
||
/// If the registry knows about the package, but none of its versions match our requirements. | ||
if_no_matching_version: OnUnexpectedOutcome, | ||
|
||
/// If a version matched our requirements, but it is not usable for semver-checking: | ||
/// for example, if it has been yanked (we won't be able to generate rustdoc for it). | ||
if_version_is_unusable: OnUnexpectedOutcome, | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub enum VersionPredicate { | ||
/// Strictly less than the specified version. | ||
LessThan(semver::Version), | ||
|
||
/// Less than or equal than the specified version. | ||
LessThanOrEqual(semver::Version), | ||
|
||
/// The largest version number available. | ||
HighestAvailable, | ||
|
||
/// The last release ordered by release date. | ||
MostRecentlyPublished. | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub enum OnUnexpectedOutcome { | ||
/// Stop running checks and return an error. | ||
FailStop, | ||
|
||
/// Log an error but continue with other checks. | ||
LogAndContinue, | ||
|
||
/// Continue with other checks as if nothing happened. | ||
/// Do not print anything to stderr. | ||
ContinueSilently, | ||
} | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative to this design would be to model the internals of
cargo semver-checks
as a state machine that a binary or other consumer needs to manually advance. That is a bit more work to integrate but gives you greater flexibility. In other words, the library part would only offer building blocks that you can compose together with your own policy.For example, if said state machine yields an event like:
We would also need APIs like:
Upon encountering a
WorkspaceCrateDiscovered
event a user could then e.g. decide whether or not to continue checking the crate for semver-violations based on thepublish
field.