-
Notifications
You must be signed in to change notification settings - Fork 13
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 Branch Selection for coffee_install()
#242
Conversation
This function will come in handy when we want to restore the state of a repository on disk after upgrading a plugin Signed-off-by: Tarek <[email protected]>
This commit adds an optional parameter to coffee_install() method that makes it possible to specify a branch when installing a plugin. The logic is: - get information about current status before switching (repoisitory branch and plugin git head) - switch to the branch - restore old information and rollback A function git_upgrade_with_git_head was implemented to handle checking out using a specfic git_head we are using the repository git head to save current status and roll back to it since it's safer than using just the branch (we fetch origin so maybe the branch was updated. we want to be back to the same commit) also, cmd, coffee_plugin and coffee httpd were upgraded to pass the branch value Signed-off-by: Tarek <[email protected]>
Since we now may have separate git heads for plugin and repository, we print the git HEAD of the plugin to the user Signed-off-by: Tarek <[email protected]>
Signed-off-by: Tarek <[email protected]>
✅ Deploy Preview for coffee-docs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
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 that this implementation is a little bit too complex for what we need to do
/// return the git head of the repository. | ||
fn git_head(&self) -> Option<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.
does not make sense to have this inside the repository trait
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.
good point. I will update it
/// return the git head of the repository. | ||
fn git_head(&self) -> Option<String> { | ||
self.git_head.clone() | ||
} |
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.
Move this as a struct method and not an a trait implementation
// if the branch is specified, we need to save current git_head | ||
// and checkout the branch | ||
let current_git_head = repo.git_head(); | ||
let current_plugin_commit = plugin.commit.clone(); | ||
if let Some(branch) = branch.clone() { | ||
log::debug!("checking out branch: {branch}"); | ||
if current_git_head.is_none() { | ||
return Err(error!("unable to get the current git head")); | ||
} | ||
let updated_status = | ||
git_upgrade_with_branch(repo.url().path_string.as_str(), &branch, verbose) | ||
.await?; | ||
log::debug!("updated status: {:?}", updated_status); | ||
|
||
let repository = git2::Repository::open(repo.url().path_string.as_str()) | ||
.map_err(|err| error!("{}", err.message()))?; | ||
|
||
// get commit id after the checkout | ||
let commit = commit_id!(repository); | ||
log::debug!("commit id after the checkout: {commit}"); | ||
plugin.commit = Some(commit); | ||
} |
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.
IMHO to much code for just sh!("git checkout {branch}")
?
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 can see some potential issues with simply using git checkout {branch}
:
- If the branch is new (not fetched yet), we need to
git fetch origin
first.- To make sure we are returning to the expected state after switching back, we need the repository's Git HEAD, not just the current branch. This is because the branch might have been updated remotely (when we ran
git fetch origin
), and we want to go back to the exact commit the user was on. - We need to verify that the repository's Git HEAD information exists (introduced in a previous PR as an Option to be backward compatible)
- To make sure we are returning to the expected state after switching back, we need the repository's Git HEAD, not just the current branch. This is because the branch might have been updated remotely (when we ran
- The plugin's
commit
field is updated during installation and then reverted afterward. Otherwise, we have false information.
Do you think that any of these steps is redundant?
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.
my point is that we can do all with just a couple of git command, with your solution I do not see any fetch anywhere too and we need to make sure that your code is correct, otherwise we will have the same problem that we had with the upgrade logic
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.
git_upgrade_with_branch()
does git fetch origin
|
||
if branch.is_some() { | ||
// we can safely unwrap here because we have checked it before | ||
let current_git_head = current_git_head.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.
the safety comment start with // SAFETY: ...
if branch.is_some() { | ||
// we can safely unwrap here because we have checked it before | ||
let current_git_head = current_git_head.unwrap(); | ||
log::debug!("checking out to git head: {current_git_head}"); | ||
// rollback to the previous git head | ||
let updated_status = git_upgrade_with_git_head( | ||
repo.url().path_string.as_str(), | ||
¤t_git_head, | ||
verbose, | ||
) | ||
.await?; | ||
log::debug!("updated status: {:?}", updated_status); | ||
|
||
plugin.commit = current_plugin_commit; | ||
} |
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.
wow this install method is starting to be 2 pages long?
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 agree!
We can keep coffee install
for just installing and configuring plugins and introduce coffee upgrade --plugin <plugin_name> --branch <branch_name>
for upgrades and branch switching
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.
No, my point is that the code that we are writing the code of the install is not good at all. Please see some of my PR that I am refactoring it.
In addition, both install and upgrade command will run the same logic and with your code we should duplicate the checkout logic. This is error prone
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.
No, my point is that the code that we are writing the code of the install is not good at all.
Ok. how do you think I can make it better? I explained why we need the extra code in install()
in this conversation #242 (comment).
Do you think that any of these steps is redundant or should be implemented in another way?
In addition, both install and upgrade command will run the same logic and with your code we should duplicate the checkout logic. This is error prone
They will have the same logic because they will do very similar tasks. The function git_upgrade_with_commit()
will be reused in coffee upgrade --plugin <plugin_name>
.
We can start with implementing coffee upgrade --plugin <plugin_name>
and then use it directly from coffee install --branch <branch_name>
. This way we don't duplicate code
@@ -25,7 +25,7 @@ pub async fn clone_recursive_fix(repo: git2::Repository, url: &URL) -> Result<() | |||
Ok(()) | |||
} | |||
|
|||
pub async fn git_upgrade( | |||
pub async fn git_upgrade_with_branch( |
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.
why changing the name here?
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.
because I added another function that uses the git commit to upgrade
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 do not see the point of changing the name, due that there is no git upgrade command in git
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.
Moreover, git uses always a branch there is never a without_branch
cases
|
||
let (local_commit, _) = get_repo_info!(repo); | ||
|
||
let mut cmd = format!("git fetch origin\n"); |
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 mut cmd = "git fetch origin\n";
format!
is not needed
pub async fn git_upgrade_with_git_head( | ||
path: &str, | ||
git_head: &str, | ||
verbose: bool, | ||
) -> Result<UpgradeStatus, CoffeeError> { | ||
use tokio::process::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.
idk if this is a good idea, the checkout is just git checkout <branch-name>
Why we need to use all this code?
@@ -22,6 +22,7 @@ pub fn show_list(coffee_list: Result<CoffeeList, CoffeeError>) -> Result<(), Cof | |||
term::format::bold(String::from("Language")), | |||
term::format::bold(String::from("Name")), | |||
term::format::bold(String::from("Enabled")), | |||
term::format::bold(String::from("Git HEAD")), |
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.
a user need also a git PHD to understand what is a git HEAD? Idk if this is necessary.
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.
We already print the git HEAD to the user with coffee remote list
If we add the possibility to manage the branch for the plugin in separation from the repository, I think we have to print it in coffee list
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.
Please call it commit
there is no meaning to complicate a simple things with big words.
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.
Sure. Do you want me to rename "Git HEAD" to "commit" in coffee remote list
output too?
#### Specifying a branch for installation | ||
|
||
To install a plugin from a specific branch, you simply need to run. | ||
|
||
```bash | ||
coffee install <plugin_name> --branch <branch_name> | ||
``` | ||
|
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.
we should not document every single command possibility otherwise our documentation will be always uncompleted
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.
Right. I can remove this section
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.
but we should came up with a way to document optional parameters
Closing in favor of #248 |
Description
Add branch selection for
coffee_install
and display plugin git HEAD incoffee list
.Fixes #205
Changes
Repository::git_head()
to retrieve the repository's git HEAD.branch
parameter tocoffee_install()
for branch selection during installation.git_upgrade_with_git_head()
for checkout using a specific git HEAD.cmd
,coffee_plugin
, andcoffee httpd
to pass the branch value.coffee list
output to display the git HEAD of plugins.Testing