8000 Feature: user config attrs by cap10morgan · Pull Request #23 · go-git/go-git · GitHub
[go: up one dir, main page]

Skip to content

Feature: user config attrs #23

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

Closed

Conversation

cap10morgan
Copy link
Contributor
@cap10morgan cap10morgan commented Apr 7, 2020

This builds on my earlier PR #20 to add top-level config attrs User, Author, and Committer. These work a little differently from the others by necessity because they are scoped (i.e. they can appear in local, global, and/or system config files). So this also demonstrates one way in which we could add more such scoped values to the top-level config.

These new config attributes store ScopedStrings and (in the case of User.UseConfigOnly) a ScopedBool. These have Value() and Set(scope, val) methods. Value gets the effective value that git would use based on the config scope precedence and Set allows setting values w/ their scopes so we have that to keep track of.

I think ultimately this and #20 point towards a bigger config overhaul for a v6+ release that is centered around interfaces rather than structs. So, for example, calling a method like cfg.User.Name() could look up the effective name value from inside the scoped config data structures rather than having to copy values back and forth from the raw / merged backing data and the top-level config struct.

< 8000 div class="pr-review-reactions ">
@mcuadros
Copy link
Member
mcuadros commented Apr 7, 2020

Can you please rebase?

@cap10morgan cap10morgan force-pushed the feature/user-config-attrs branch from ad56a0e to b538daf Compare April 7, 2020 21:22
@cap10morgan
Copy link
Contributor Author

Can you please rebase?

Done.

Copy link
Member
@mcuadros mcuadros left a comment

Choose a reason for hiding this comment

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

I believe that the Config struct should have only scalar types and not the ScopedString, this should be only for the internal package.

When we call Repository.Config should return Config with the values merged from all the scopes from system to repository. And ideally, create a new method called Repository.ConfigWithOptions where we can provide the context (ConfigOptions)

What do you think?

@@ -53,6 +104,29 @@ type Config struct {
Window uint
}

User struct {
Name ScopedString
Copy link
Member

Choose a reason for hiding this comment

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

Why we use ScopedStrings, instead of just load the config using the priority? Global, User, Project?

Copy link
Contributor Author
@cap10morgan cap10morgan Apr 23, 2020

Choose a reason for hiding this comment

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

The primary reason is that we need to remember the scope for when / if we write the config back out to the underlying files. We need to know where each value came from (even if someone changed it).

I think we're either going to have to overhaul the Config stuff to not allow editing scoped values in the high-level structs or keep track of this scope information somewhere else.

Copy link
Member

Choose a reason for hiding this comment

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

I see but I rather not exposing this complex API. If we need to write back the config, we should request a clean copy of the Repository one (without any merge), and save this. It will be very complex and error-prone, allow persist a config from a different context.

Copy link
Contributor Author
@cap10morgan cap10morgan Apr 23, 2020

Choose a reason for hiding this comment

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

The API on the scoped attrs is .Value() and .Set(), which doesn't seem so complex. Would it help if this were consistent across all top-level config attrs? That would be a breaking change but if we made them private struct members we could then expose their names as getter methods (and Set[Attr] for setters) so the migration would be fairly simple for users (i.e. just adding () after the attr names everywhere).

Currently there's nothing preventing writing configs because it's all based around public struct members. With un-scoped attrs, you set arbitrary struct members and then call SetConfig and suddenly your local .git/config file contains the merged result of your system, global, and local configs. I think we would need some kind of breaking change to prevent that or this library is going to mess up peoples' configs in a way that will be a ticking time bomb for them (i.e. everything will seem normal until their repo hangs onto some global or system config param they change and assume applies everywhere).

So it sounds like you're proposing some kind of new top-level, merged, read-only config. And if you want to be able to make changes to it, you have to request a specific scope's config which will be written back to that scope's corresponding file. This will be a breaking change, is that OK? Am I understanding your proposal correctly?

Copy link
Member

Choose a reason for hiding this comment

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

Here is some things that are important: Repository.Config MUST return the repository config. Since it's a method from the repository and the goal is to operate with it. Storer.SetConfig MUST not write config.Config structs with merged information.

About how to identify the config, ideally is have a MergedConfig or something but since we can't change the Config to an interface, it should be done for v6. So meanwhile we can add config.Config.Context for example.

Regarding reading the merged context, we can add config.ReadConfig(context) config.Config, as a helper for the people that wants access to this configuration. We must remember that the config merge is a very porcelain feature, so it's good to have it optional and explicit.

Internally Repository.Commit my use the new config.ReadConfig to read the config if a new flag called something like CommitOpts.UseGlobalConfig is true (by default false)

In this way, we have something that doesn't break the API or introduce unexpected behaviors. And we introduce an important feature requested by many users.

Thanks for your efforts and sorry for not being clear, but this library is a big codebase, and is hard to have it on top of the mind.

Copy link
Member

Choose a reason for hiding this comment

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

@cap10morgan are you planning to work on this soon? if not, I will take the task, I want to release a new version and I want to include this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I probably won't get to it soon. I'm no longer working on the project that needed this, so harder to prioritize spending work hours on it. Let me know if I can help with the effort in any other ways, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0