Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Refactor repository models (repository refactor part 1) - #2008

Closed
jcansdale wants to merge 23 commits into
masterfrom
fixes/2007-refactor-repository-models
Closed

Refactor repository models (repository refactor part 1)#2008
jcansdale wants to merge 23 commits into
masterfrom
fixes/2007-refactor-repository-models

Conversation

@jcansdale

@jcansdalejcansdale commented Oct 23, 2018

Copy link
Copy Markdown
Collaborator

This is the first iteration of refactoring LocalRepositoryModel and GitService (see #2007).

I've focused on moving the code to where is should be, with as few functional changes as possible. There is more to do, but I think this makes sense as a chunk.

  • Replace ILocalRepositoryModel.CurrentBranch property with IGitService.CreateCurrentBranchModel(model) method
  • Move construction of LocalRepositoryModel to GitService.CreateLocalRepositoryModel
  • Move LocalRepositoryModel.GenerateUrl to LinkCommandBase
  • Move LocalReposotoryModel.Refresh to GitService.RefreshCloneUrl (this will be removed in Remove repository responsibilities from TeamExplorerServiceHolder (repository refactor part 2) #2025)
  • Get rid of LocalRepositoryModelFactory (we can use GitService instead)
  • Remove unused LocalRepositoryModel.HeadSha property

The most significant functional change was to replace the LocalRepositoryModel.CurrentBranch property with a GitService.CreateCurrentBranchModel(repositoryModel) method.

This was necessary because the IGitExt.ActiveRepositories property changed event fires before the current branch is actually changed. If we populate LocalRepositoryModel.CurrentBranch when the model is created, CurrentBranch ends up with information about the previous branch.

By deferring creation of the current branch model, we can populate it when the branch has actually changed and only create the branch model when it's actually required (the property change event can fire a lot).

Bugs to fix

Still to do

Now the junk has been removed from LocalReposotoryModel, we can decide how we want the models to look!

@codecov

codecovBot commented Oct 23, 2018

Copy link
Copy Markdown

Codecov Report

Merging #2008 into master will decrease coverage by 1.3%.
The diff coverage is 52.63%.

@@ Coverage Diff @@## master #2008 +/- ##
==========================================
- Coverage 40.67% 39.36% -1.31% 
==========================================
Files 377 410 +33 Lines 16333 17572 +1239 Branches 2253 2422 +169 ==========================================
+ Hits 6643 6918 +275 - Misses 9150 10117 +967 + Partials 540 537 -3
Impacted FilesCoverage Δ
src/GitHub.Exports/Models/BranchModel.cs35.71% <0%> (ø)⬆️
...rc/GitHub.VisualStudio/Commands/OpenLinkCommand.cs0% <0%> (ø)
...rc/GitHub.VisualStudio/Commands/CopyLinkCommand.cs0% <0%> (ø)
...c/GitHub.VisualStudio/Commands/BlameLinkCommand.cs0% <0%> (ø)
src/GitHub.App/Services/PullRequestService.cs35.29% <0%> (ø)⬆️
...eamFoundation.14/Base/TeamExplorerServiceHolder.cs0% <0%> (ø)⬆️
src/GitHub.TeamFoundation.14/RegistryHelper.cs0% <0%> (ø)⬆️
...ndation.14/Services/LocalRepositoryModelFactory.cs0% <0%> (ø)⬆️
...wModels/GitHubPane/PullRequestCreationViewModel.cs97.35% <100%> (+0.03%)⬆️
...nlineReviews/Services/PullRequestSessionManager.cs83.75% <100%> (ø)⬆️
... and 42 more

Move LocalRepositoryModel construction tests to new home.
This property wasn't being used.
We Now only need the CreateLocalRepositoryModel(localPath) overload.
Previously the current branch was being read when CurrentBranch was
fetched. This changes it to be read when the LocalRepositoryModel is
created.
Remove redundant code and usings.
@jcansdalejcansdale changed the title [wip] Refactor repository modelsRefactor repository models (part 1)Oct 24, 2018
@jcansdalejcansdale changed the title Refactor repository models (part 1)[wip] Refactor repository models (part 1)Oct 24, 2018
@jcansdale

Copy link
Copy Markdown
CollaboratorAuthor

I think updating the Checkout ... link state might have broken with this PR. Need to investigate....

image

Comment threadsrc/GitHub.Exports/Services/IGitService.cs Outdated
/// <summary>
/// Gets the repository clone URL.
/// </summary>
public UriString CloneUrl

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future: should these properties be raising change notifications? If so, should other properties also be raising them (CurrentBranch for example).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should aim to get rid of the Refresh command so this model would be immutable after creation.

@@ -85,7 +67,7 @@ protected set
public Octicon Icon

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future: move this out of the model: it's a view model-level reponsibility that only really applies to the repository list in Team Explorer.

Comment threadsrc/GitHub.Exports/Models/BranchModel.cs
Comment threadsrc/GitHub.TeamFoundation.14/Services/LocalRepositoryModelFactory.cs Outdated
{
var repo = ServiceProvider.TryGetService<IGitService>().GetRepository(path);
return new LocalRepositoryModel(repo.Info.WorkingDirectory.TrimEnd('\\'), GitService.GitServiceHelper);
return GitService.GitServiceHelper.CreateLocalRepositoryModel(repo.Info.WorkingDirectory.TrimEnd('\\'));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is TrimEnd needed here? If so, should that logic be put into CreateLocalRepositoryModel?

Previously CurrentBranch was created as the property was read. We now
need a way to refresh it.

@jcansdalejcansdale left a comment

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this logic be part of RepositoryViewModel?

@jcansdalejcansdale left a comment

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this logic be part of RepositoryViewModel?

@jcansdalejcansdale left a comment

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this logic be part of RepositoryViewModel?

It appears VSGitExt.ActiveRepositoriesChanged is fired before the local
repository has actually changed its branch. This means we can't read
the branch information immediately!

@jcansdalejcansdale left a comment

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments about removing CurrentBranch.

Comment threadsrc/GitHub.Exports/Models/ILocalRepositoryModel.cs Outdated
Name = name,
Icon = Octicon.repo
};

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is currently being refreshed before the branch has actually changed. :-(

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is now a CreateCurrentBranchModel command instead of the CurrentBranch property. We'll still need to be careful about calling it too soon.

Remove the ILocalRepositoryModel.CurrentBranch property and explicitly
call IGitService.CreateCurrentBranchModel instead.
Fix all the broken tests.
Convert GetPullRequestForCurrentBranch to return (string owner, int
number). This allows the tuple to be compared directly.
We can now use GitService as a LocalRepositoryMode factory.
@jcansdale
jcansdaleforce-pushed the fixes/2007-refactor-repository-models branch from 3abf4d6 to db41ef9CompareOctober 31, 2018 17:30
@jcansdalejcansdale changed the title [wip] Refactor repository models (part 1)Refactor repository models (part 1)Nov 1, 2018
@jcansdalejcansdale changed the title Refactor repository models (part 1)Refactor repository models (repository refactor part 1)Nov 1, 2018

@grokysgrokys left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! a couple of nits and questions but going to approve anyway.

/// Creates a new branch model for the current branch.
/// </summary>
/// <param name="model">The <see cref="ILocalRepositoryModel" /> to create a current branch model for.</param>
/// <returns>A new branch model.</returns>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be less verbose if it were simply called GetBranch: I'd tend to think of it more as a method to get the state of an ILocalRepositoryModel than a factory method. What do you think?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could change it to GetBranch(string name = "HEAD"). Do you think that would make sense? Otherwise we'd probably need to qualify it with GetHeadBranch or something?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think that would make sense.

else if (newRepositoryPath != null)
{
log.Debug("Fire StatusChanged event when PullRequest changes for ActiveRepository");
log.Debug("Fire StatusChanged event when on a repository and anything changes");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reads a bit yoda-y ;)

@jcansdalejcansdaleNov 2, 2018

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if that's a feature? 😉

I'll change it to:
"Fire StatusChanged event if anything about an active repository has changed"

log.Debug("Fire StatusChanged event when BranchName changes for ActiveRepository");
StatusChanged?.Invoke(this, EventArgs.Empty);
}
else if (newHeadSha != headSha)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So StatusChanged is no longer firing when HEAD changes? Is this because it wasn't working before anyway? (i.e. it was firing before the actual change)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now either a repository change event will be fired when we set ActiveRepository or a StatusChanged will be fired if we think anything about the active repository might have changed (including when the HEAD changed).

This is actually similar to what was happening before because newPullRequest != pullRequest was always returning true (the tuple comparison issue).

I have changed it so that if we're not on a repository, no StatusChanged event will fire.

@jcansdale

Copy link
Copy Markdown
CollaboratorAuthor

Merged as part of #2028.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jcansdale@grokys