{{ message }}
Refactor Linguist::Repository to isolate Rugged usage #7094
Merged
Conversation
Add interfaces representing a generic "Repository" and "Diff", containing functions currently handled by the Rugged repository instance in 'Linguist::Repository'. Inheriting from these interfaces will allow for alternative implementations of the functions used to traverse and analyze a repository, e.g. using a different API for Git storage or a different SCM altogether. For now, the interfaces are unused. Signed-off-by: Victoria Dye <vdye@github.com>
Add Rugged implementations of the 'Repository', 'Diff', and 'Diff::Delta' interfaces matching existing usage in 'Linguist::Repository' & 'Linguist::LazyBlob'. In a subsequent commit, this will allow us to substitute an instance of the 'Repository' interface for what is currently direct usage of a 'Rugged::Repository'. Signed-off-by: Victoria Dye <vdye@github.com>
Change the 'repository' argument to 'Linguist::Repository' && 'Linguist::LazyBlob' from a 'Rugged::Repository' to an instance of 'Linguist::Source::Repository'. This will allow users of Linguist to easily configure and use a custom repository interface. There are two methods that don't have a clear or useful parallel in a generic repository interface and are more specific to Rugged: 'read_index' and 'current_tree'. For both of these methods, raise a 'NotImplementedError' if any repository instance that's not a 'RuggedRepository' calls them, and return the legacy value for ones that are 'RuggedRepository'. Also for backward-compatibility purposes, users can still initialize a 'Linguist::Repository' or 'Linguist::LazyBlob' with a 'Rugged::Repository'; it will be wrapped in the 'Linguist::Source::RuggedRepository' in the initialization method. Finally, update 'test_repository.rb' to test both a 'RuggedRepository' instance and a mocked always-empty repository. Signed-off-by: Victoria Dye <vdye@github.com>
Add a 'method_missing' implementation to 'RuggedRepository' to delegate all unmatched methods to the internal Rugged objects of each. This is done for backward-compatibility purposes; users of Linguist can access the 'repository' member of 'Linguist::Repository', so they may rely on interacting directly with the 'Rugged::Repository'. The 'method_missing' delegate ensures that those interactions will generally continue to work (the main exception being explicit type checking performed on 'Linguist::Repository.repository'). Signed-off-by: Victoria Dye <vdye@github.com>
lildude
approved these changes
Nov 25, 2024
This file contains hidden or 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
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.

Description
The goal of this change is to add flexibility to how repository data is accessed by
Linguist::Repository&Linguist::LazyBlob, allowing users to easily configure an alternative toRugged.Internally,
Linguist::RepositoryandLinguist::LazyBlobuse Rugged to read Git repository data, including diff, attribute, and blob information. While this works for most repositories, it has limits:The approach taken here is to replace the
Rugged::Repositoryinstance in theLinguist::Repositorywith a newLinguist::Source::Repositoryinstance. The "source" repository contains functions wrapping what were previously Rugged operations (diff, attribute lookup, etc.). Users can then write their custom implementations of those functions and pass theirLinguist::Source::RepositoryintoLinguist::Repositoryto use them seamlessly.This isn't intended to be a breaking change, so there are a few extra things done to avoid compatibility issues with existing usage:
Rugged::Repositoryis passed in as the first argument to either theLinguist::RepositoryorLazyBlobinitializer, it is wrapped in aLinguist::Source::RuggedRepositoryinternally.GIT_ATTR_OPTS&GIT_ATTR_FLAGSare Rugged-specific so they're moved toRuggedRepository, but theLazyBlobconstants are not removed and instead point to theirRuggedRepositorycounterparts.current_treeandread_indexdon't make sense for non-Rugged repos (the former returns a Rugged tree instance, the latter is specific to how Rugged needs to look up attributes). They raiseNotImplementedErrorwith a message referencing deprecation only if called on a non-Rugged repository instance; otherwise they behave the same way as before.method_missingimplementation is added toLinguist::RuggedRepositoryto delegate any unmatched method calls to the internalRugged::Repositoryinstance (in case users are callingLinguist::Repository.repositorydirectly).The only possible compatibility issue I can imagine is if a user does some kind of type check on
Linguist::Repository.repository(previously it was aRugged::Repository, now it'll be aLinguist::Source::RuggedRepository). That seems highly unlikely, though, and should be a simple fix if needed.The commits on this branch are organized to be atomic and incrementally reviewable:
Linguist::Source:RepositoryandLinguist::Source::Diffinterfaces, with all methods raisingNotImplementedErrorto ensure they are overridden by a subclass implementation.Linguist::Source::Repositorymatching existing usage incompute_statsandLinguist::LazyBlob.Linguist::Repositoryto use aLinguist::Source::Repositoryinstead of aRugged::Repositoryto read repository content.method_missingimplementation toRuggedRepository.Checklist:
I am adding a new extension to a language.
I am adding a new language.
#RRGGBBI am fixing a misclassified language
I am changing the source of a syntax highlighting grammar
I am updating a grammar submodule
I am adding new or changing current functionality
I am changing the color associated with a language