-
Notifications
You must be signed in to change notification settings - Fork 142
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
download refactor + support single installations #62
Conversation
Testing this again and trying random commands to check for weird unhappy paths, currently this doesn't know how to handle: fuelup install forc forc@0.14.5 Going to validate this by allowing only 1 of the same names to exist in a single command |
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.
Great stuff @binggh, looking really good! Just a couple small suggestions.
The forc@1.2.3
syntax looks nice too. Did rustup
set precedent for that? Or did you come up with it?
src/commands/install.rs
Outdated
pub fn parse_component(component: &str) -> Result<(String, Option<String>)> { | ||
if component.contains('@') { | ||
let filtered = component.split('@').collect::<Vec<&str>>(); | ||
let semver_regex = Regex::new(r"^[v]?\d+\.\d+\.\d+$").unwrap(); |
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.
Perhaps rather than introducing regex
, we could use the semver
crate? E.g. semver::Version::parse(version)
? I'm thinking it might be a little more light-weight / easier to read for non-regex magicians.
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.
you're right, this would definitely be alot more legible and would help with #64 as well (since we're checking versions), seems like it also handles validation which is everything we need for this
src/download.rs
Outdated
release_url: match name { | ||
"forc" => SWAY_RELEASE_DOWNLOAD_URL.to_string(), | ||
"fuel-core" => FUEL_CORE_RELEASE_DOWNLOAD_URL.to_string(), | ||
"fuelup" => FUELUP_RELEASE_DOWNLOAD_URL.to_string(), |
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.
I think it might be worth moving these component names into constants as they're used in quite a few places and it might help to avoid typos, e.g.
pub mod component {
pub const FORC: &str = "forc";
pub const FUEL_CORE: &str = "fuel-core";
pub const FUELUP: &str = "fuelup";
}
// ...
match name {
component::FORC => SWAY_RELEASE_DOWNLOAD_URL.to_string(),
// etc
Nope - I'm not sure if |
I'm wondering if we should just store the version within edit: shouldn't take too long to rewrite this so I shall |
Rewrote versioning to take |
Forgot to address this but I did update the behaviour by not executing the command at all if a duplicate input was given: $ fuelup install forc@0.14.5 forc
Error: Invalid command due to duplicate input: forc |
$ rustup component add --help
...
OPTIONS:
--target <target>
--toolchain <toolchain> Toolchain name, such as 'stable', 'nightly', or '1.8.0'. For more information see
`rustup help toolchain` |
Yup! The intention was always to go towards something like that (sorry I didn't make it clear) - working on supporting toolchains (
As for the toolchain-based experience that we'd like to pursue, since we do not have version sets bundling What would, however, the developer experience look like for adding to custom toolchains? For example rustup's method of custom toolchains seems to involve manually building and linking local builds, but we already have an answer here, which is to do fuelup toolchain new my-toolchain
fuelup default my-toolchain
fuelup component add forc@0.14.5 # adds forc v0.14.5 to my-toolchain Apologies for this verbal vomit but I just had this stream of ideas that I had to puke out. Let me know if I'm mistaken about the approach we're going for here. |
Just to clarify: I don't think |
Yup ^ sorry, that's what I meant, selecting a compatible version of |
Perhaps this is an indicator that we should define toolchains within
Hmmmmm 🤔 In retrospect, it's probably a wise choice from By allowing and encouraging users to build custom toolchains from arbitrary components with untested version combinations, I can foresee users frequently encountering strange compile/runtime errors as a result of incompatibilities between different sets of versions. We should likely only encourage usage of the set of toolchains we can actually test (i.e. If we take this "components-first" approach to toolchain building, I think we should avoid encouraging (or potentially even exposing) its usage, and emphasize that it is only really intended for use by developers of Sway, advanced use cases, and that for the most part it is an implementation detail of how Rather than letting the fact that we don't yet have well defined toolchains out of the box encourage a components-first approach, I think we should instead take this as a hint that we should prioritise defining our toolchains first (at least just In general, I'm much less sure that we should consider exposing custom toolchains as a feature unless we can think of a really good use-case that our Feel free to let me know if you think I'm not considering something properly here @binggh! Curious to get your thoughts on this. |
I think you raised up very good points that I didn't consider before so I stand corrected. Especially the point that supporting custom toolchains from the get go will probably create more problems for us than if we simply defined our toolchains first, and at least assure devs that these toolchains have been tested and let it be known that custom toolchains are experimental in nature and should only be for advanced users. If this is the case then I should work on #63 first, and at least support this command: Then I think we have to come to an agreement on how #66 will work <- this is something that's not totally clear to me yet, and in hindsight, was actually the main reason why I was contemplating what I wrote above, which is that it's probably not an easy problem to define which With that said, I would still like to work from this PR if it's fine - it contains pretty useful refactoring to |
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.
With that said, I would still like to work from this PR if it's fine - it contains pretty useful refactoring to download.rs that is reusable to tackle #63
Keeping the refactor sounds good! That said, I wonder if we should at least remove the publicly facing @<version>
handling for now, or perhaps split it into a separate branch pending further consideration?
src/download.rs
Outdated
let handle = ureq::builder().user_agent("fuelup").build(); | ||
let resp = handle.get(github_api_url).call()?; | ||
|
||
let mut data = Vec::new(); | ||
resp.into_reader().read_to_end(&mut data)?; | ||
|
||
let response: LatestReleaseApiResponse = serde_json::from_str(&String::from_utf8_lossy(&data))?; | ||
Ok(response.tag_name) | ||
|
||
let version = Version::parse(&response.tag_name[1..response.tag_name.len()])?; |
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.
let version = Version::parse(&response.tag_name[1..response.tag_name.len()])?; | |
// Given a semver version with preceding 'v' (e.g. `v1.2.3`), take the slice after 'v' (e.g. `1.2.3`). | |
let version_str = &response.tag_name['v'.len()..]; | |
let version = Version::parse(version_str)?; |
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.
Yep, this sounds good, i'll remove all the changes related to specific versioning from this PR for now, and we'll just merge changes related to the refactor
Removed version parsing from the install command - shouldn't be able to do
The command name probably needs changing eg. it should be |
src/commands/install.rs
Outdated
}; | ||
|
||
#[derive(Debug, Parser)] | ||
pub struct InstallCommand {} | ||
#[clap(override_usage = "\ | ||
fuelup install <COMPONENT>[@<VERSION>] ...")] |
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.
Woops I think we want to remove this override too?
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.
Thanks for the catch!
Closes #60
Synopsis
This PR contains the following changes:
Refactor
download.rs
, change is mainly centered aroundDownloadCfg
which is a representation of a configuration which allows you to specify aname
andversion
to download a component.Allows you to now specify names to install binaries and also at specific versions (examples below):
To install all (including fuelup at the end):
To install a specific component (latest version is fetched by default):
To install 2 different components:
To install 2 different components, 1 with a different version:
You can specify versions by starting with 'v' as well:
Some unhappy paths worth testing, starting with installing invalid components:
Wrong versioning (Note that these are also covered under tests):
Note: to install a specific version the syntax strictly follows the format
<name>@<version>
by using regex parsing, where version follows the<major>.<minor>.<patch>
notation