JuliaLang / juliaup

Julia installer and version multiplexer
MIT License
975 stars 82 forks source link

Clean up codebase #313

Open SaadiSave opened 2 years ago

SaadiSave commented 2 years ago

[Enhancement]

Would you be open to cleaning up this codebase and making it more idiomatic? I can submit a PR to help.

darleybarreto commented 2 years ago

I think it would be great. Perhaps you could make a single PR, but making independent commits so it would be better to review (one by one).

SaadiSave commented 2 years ago

Okay, I'll begin as soon as possible. Will you be committing to main or merging any PRs soon? I'd like to reduce merge conflicts, so I'll start with the latest possible commit.

simeonschaub commented 2 years ago

I'd like to merge #197 first before we start refactoring parts of the code base. @davidanthoff would you have time next week to take a quick look at that together?

davidanthoff commented 2 years ago

In general I think this is great, but I would hold off for a while. We have Juliacon coming up, we still have pending PRs that I want to merge plus a list of a couple of very high priority things I'd like to get in before Juliacon, and that will certainly take up all the bandwidth I have in July.

Also, could you describe a bit more what you have in mind? In general, very small and targeted PRs would work best.

SaadiSave commented 2 years ago

Firstly, but I think that the way modules are structured is rather unidiomatic and makes the code hard to read. For example:

use juliaup::{
    command_selfchannel::run_command_selfchannel,
    command_selfuninstall::run_command_selfuninstall,
    command_config_backgroundselfupdate::run_command_config_backgroundselfupdate,
    command_config_startupselfupdate::run_command_config_startupselfupdate,
    command_config_modifypath::run_command_config_modifypath,
};

The code is not fully utilising the module system, and this looks like the naming conventions used in C, which has header hell and no module system, so you have to prefix everything. That's not needed in Rust.

So, this import could be simplified to:

use juliaup::command::{
    self_channel,
    self_uninstall,
    config::{
        background_self_update,
        startup_self_update,
        modify_path,
    },
};

You can immediately perceive the difference in readability.

And then, while using it:

// example
self_channel::run();

Second, the code is not formatted properly, with snippets like this:

fn get_juliaup_home_path() -> Result<PathBuf> {
    let entry_sep = if std::env::consts::OS == "windows" {';'} else {':'};

    let path = match std::env::var("JULIA_DEPOT_PATH") {
        Ok(val) => {
            let path = PathBuf::from(val.to_string().split(entry_sep).next().unwrap()); // We can unwrap here because even when we split an empty string we should get a first element.

            if !path.is_absolute() {
                bail!("The `JULIA_DEPOT_PATH` environment variable contains a value that resolves to an an invalid path `{}`.", path.display());
            };

            path.join("juliaup")
        }
        Err(_) => {
    let path = dirs::home_dir()
        .ok_or(anyhow!(
            "Could not determine the path of the user home directory."
        ))?
        .join(".julia")
        .join("juliaup");

            if !path.is_absolute() {
                bail!(
                    "The system returned an invalid home directory path `{}`.",
                    path.display()
                );
            };

            path
        }
    };

    Ok(path)
}

This is the simplest to fix: a simple cargo fmt would do the trick. Plus, formatting checks should probably be added to CI.

Next, and this is rather subjective, but commands should probably be structs containing all that a command needs, and then a simple trait to run it:

pub trait Command {
    type Error;

    fn run(self) -> anyhow::Result<Self::Error>;
}

Which would be used like so:

use juliaup::command::{self, Command};

fn any() {
    command::Add::new(/* params */).run();
}

Lastly, linting with cargo clippy would also be rather helpful in catching unidiomatic code (use it in CI too).

I understand that these are massive changes, so take your time to debate them. I believe that these changes will make the codebase far more approachable.

SaadiSave commented 2 years ago

Possible refactored module tree: image

As text:

crate juliaup_skeleton
├── mod command: pub
│   ├── struct Add: pub
│   ├── struct Api: pub
│   ├── trait Command: pub
│   ├── struct Default: pub
│   ├── struct Gc: pub
│   ├── struct InitialSetup: pub
│   ├── struct Link: pub
│   ├── struct List: pub
│   ├── struct Remove: pub
│   ├── struct SelfChannel: pub
│   ├── struct SelfUninstall: pub
│   ├── struct SelfUpdate: pub
│   ├── struct Status: pub
│   ├── struct Update: pub
│   └── mod config: pub
│       ├── struct BackgroundSelfUpdate: pub
│       ├── struct ModifyPath: pub
│       ├── struct StartupSelfUpdate: pub
│       └── struct Symlinks: pub
├── mod global_paths: pub
│   ├── struct GlobalPaths: pub
│   └── fn get_paths: pub
├── mod utils: pub
│   ├── fn get_arch: pub
│   ├── fn get_bin_dir: pub
│   ├── fn get_juliaserver_base_url: pub
│   └── fn parse_versionstring: pub
└── mod version_db: pub
    ├── struct Channel: pub
    ├── struct Version: pub
    ├── struct VersionDB: pub
    └── fn load: pub
SaadiSave commented 2 years ago

@davidanthoff, what is your opinion on this proposal?

davidanthoff commented 2 years ago

I need to think a bit about it, right now I'm too busy getting things ready for Juliacon. I'll engage once Juliacon is over.

SaadiSave commented 2 years ago

Okay. Meanwhile, I will begin planning the PRs.

uncomfyhalomacro commented 2 years ago

whats the state of this currently @SaadiSave and @davidanthoff ?

SaadiSave commented 2 years ago

@uncomfyhalomacro I have finished planning the PRs.

SaadiSave commented 2 years ago

@davidanthoff do I have the green light?

uncomfyhalomacro commented 2 years ago

@SaadiSave I guess open the PRs. They usually are lost from multiple issues hanging around.

SaadiSave commented 2 years ago

@SaadiSave I guess open the PRs. They usually are lost from multiple issues hanging around.

Okay, I shall open the first PR shortly

uncomfyhalomacro commented 1 year ago

sorry for the sudden bump @davidanthoff. can @SaadiSave contribute on this one? he was very excited to do this.

SaadiSave commented 1 year ago

@uncomfyhalomacro thanks for the encouragement, but I currently have some personal problems to deal with. And uni exams are coming. I won't be able to contribute until March. I still am just as excited, but I simply don't have the time right now. Nevertheless, I shall try my best to get in a few small PRs by the end of this year.

davidanthoff commented 1 year ago

My view on this is that generally we should do this, but probably better to do it at a point where things calm down in terms of churn. Right now I'm trying to get everything finished for a release that we can call the official installer for Julia, and so there is a fair bit happening on the code.

uncomfyhalomacro commented 1 year ago

okay. we are happy to contribute and help when that time comes. :heart:

SaadiSave commented 1 year ago

My view on this is that generally we should do this, but probably better to do it at a point where things calm down in terms of churn. Right now I'm trying to get everything finished for a release that we can call the official installer for Julia, and so there is a fair bit happening on the code.

Is there perhaps a checklist of things left to do before the installer is considered to be MVP for an official installer?

uncomfyhalomacro commented 1 year ago

My view on this is that generally we should do this, but probably better to do it at a point where things calm down in terms of churn. Right now I'm trying to get everything finished for a release that we can call the official installer for Julia, and so there is a fair bit happening on the code.

Is there perhaps a checklist of things left to do before the installer is considered to be MVP for an official installer?

Same question. bump

uncomfyhalomacro commented 1 year ago

Hello. @davidanthoff I am planning to start contributing to this by moving around some things. But I also need your approval for doing this PR as JuliaCon is coming close now and I know you will be busy. Would it be okay to see a checklist of sorts so I can open small PRs so that it won't be giving you a large diff and so others can review.

SaadiSave commented 1 year ago

@uncomfyhalomacro what kind of improvements do you have in mind that could be done incrementally? The original proposal (https://github.com/JuliaLang/juliaup/issues/313#issuecomment-1181725350) involved restructuring the entire module tree, and I don't see how it could be done incrementally.

uncomfyhalomacro commented 1 year ago

@uncomfyhalomacro what kind of improvements do you have in mind that could be done incrementally? The original proposal (#313 (comment)) involved restructuring the entire module tree, and I don't see how it could be done incrementally.

I haven't thought of that yet. If we follow that proposal, yeah it would be a big PR. It seems I intend to follow your proposal too. So no small PRs then. 🤧

SaadiSave commented 1 year ago

I haven't thought of that yet. If we follow that proposal, yeah it would be a big PR. It seems I intend to follow your proposal too. So no small PRs then. 🤧

@uncomfyhalomacro perhaps we could start by running pedantic clippy on one module at a time? It will be much less ambitious than the original plan, but it would still appreciably improve code quality.

uncomfyhalomacro commented 1 year ago

Sure. I will do that during my weekends.

davidanthoff commented 1 year ago

While I'm still in favor of this in general eventually, can we hold off for now? This will just create extra work at the moment, and I'm trying to get some important features/bug fixes in that I think have a much higher priority.

SaadiSave commented 1 year ago

trying to get some important features/bug fixes in that I think have a much higher priority.

Is there a priority list? Perhaps we can help. I tried checking the issues but there are no labels for prioritisation.

davidanthoff commented 1 year ago

Probably this https://github.com/JuliaLang/juliaup/milestone/7.

uncomfyhalomacro commented 1 year ago

Sure. I will try to help with providing features or bugfixes before this then. 😄

SaadiSave commented 5 months ago

@davidanthoff

I believe that reworking the architecture of juliaup would fix many of the pending issues. Since juliaup is the official installer for julia now (at least, it appears to be recommended by default at https://julialang.org/downloads/), should we begin?