-
Notifications
You must be signed in to change notification settings - Fork 534
formats/config: Added encoder/decoder for git config files. #97
Conversation
Portions of code taken from: https://github.com/go-gcfg/gcfg/blob/5b9f94ee80b2331c3982477bd84be8edd857df33/read.go
return true | ||
}) | ||
|
||
err = decode(c, config, fset, file, src) |
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.
simply return decode(c, config, fset, file, src)
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. Thanks.
} | ||
|
||
func (c *Config) Section(name string) *Section { | ||
for i := len(c.Sections) - 1; i >= 0; i-- { |
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 not you prefer range
? Is there any special meaning iterating in reverse order ?
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 it has to do with disambiguating sections with the same name to the one that was appended last?, is name supposed to be an unique id?
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.
When we have multiple options with the same key, the standard git config behaviour for Get is that the last value wins. So we iterate in reverse order and return the first value.
For Sections/Subsections we do the same. Although this will probably have to be changed in the future if we want to handle merging of repeated sections. At the moment, we do not require such functionality, but we'll have to handle this when we want to work with git config files in the wild (at the moment, we just want to get/set/delete remotes for our storage backend).
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.
👍
return "" | ||
} | ||
|
||
func (s *Config) AddOption(section string, subsection string, key string, value string) *Config { |
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 this method returns its receiver to be chainable?
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.
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.
👍
return s.AddOption(key, value) | ||
} | ||
|
||
func (s *Subsection) SetOption(key string, value string) *Subsection { |
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.
there is a lot of duplicated code here.
Would it be possible to avoid it by embedding subsection into section or something along those lines...
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 moved duplicated code to a separate function.
I'd like to avoid embedding at the moment, since this keeps the API easier when using no constructors. Unless we move everything to methods and make the values opaque.
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.
👍
} | ||
} | ||
} | ||
panic("never reached") |
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.
This function is 150 lines long.
Can we slipt it without impairing its legibility?
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.
Removed. It was a copy of an internal gcfg function that we needed to modify. This is now in our own gcfg fork: https://github.com/src-d/gcfg
`, | ||
Text: `[sect1] | ||
opt1 = value1 | ||
[sect1 "subsect1"] |
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.
That's the expected format?
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.
Yeah, tabs at the left are preserved when using `, and I need no tabs at the left.
Text: `[sect1] | ||
opt1 = value1 | ||
opt1 = value1b | ||
[sect1 "subsect1"] |
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.
That's the expected format?
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.
Same here.
// section and subsection. | ||
// If subsection is empty, then it's taken as no subsection. | ||
func (s *Config) SetOption(section string, subsection string, key string, value string) *Config { | ||
if subsection == "" { |
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.
This is similar to what happen with flush-pkt in the past, that we should pass a constant instead of making the user aware of the specific value. How about a NoSection
constant with the value of ""?
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.
Done.
Options Options | ||
} | ||
|
||
type Sections []*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.
Options
, Sections
and Subsections
are currently slices. Willl it make sense to use maps instead, given that we are somewhat assuming names will be unique ids?
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.
There might be multiple sections with the same name. It's up to us to offer convenience methods in the future that hide this for common use case, but the structure needs to preserve this.
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.
👍
Config *Config | ||
} | ||
|
||
type Comment 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.
This is weird, did you forgot to add some methods to this type? otherwise, why can we use the string type instead of Comment?
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.
Yep. It's still missing comment handling code such as returning comment without comment symbols (;. #).
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.
ok 👍
@@ -0,0 +1,147 @@ | |||
// Package config implements decoding, encoding and |
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 package doc description usually is filled in a doc.go
and we copy the reference there: https://github.com/src-d/go-git/blob/master/formats/idxfile/doc.go
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.
Done.
return s | ||
} | ||
|
||
func (s *Section) Subsection(name string) *Subsection { |
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.
Can you comment the public methods
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.
👍
} | ||
|
||
func (s *Section) SetOption(key string, value string) *Section { | ||
for i := len(s.Options) - 1; i >= 0; i-- { |
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 code from SubSction.SetOption, is exactly the same? Maybe we can find another abstraction to avoid having duplicate code?
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.
To me, subsection is a section that has no children.
That's why I think we can remove subsection and put children (subsections) as a reference to itself ([]*Section
). As a result it will be defined fully recursive and there will be no repetition.
@@ -0,0 +1,103 @@ | |||
package config_test |
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 prefer not having _test packages, and using the same package
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.
Done.
func Test(t *testing.T) { TestingT(t) } | ||
|
||
type CommonSuite struct { | ||
} |
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.
In the same link of the open brace
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.
Done.
* WIP: Add config format parser. * add decoder based on gcfg. Portions of code taken from: https://github.com/go-gcfg/gcfg/blob/5b9f94ee80b2331c3982477bd84be8edd857df33/read.go * add git config encoder and config methods. * use format/config in storage/filesystem for read * use format/config in storage/filesystem to write * formats/config: improve docs. * formats/config: improve tests. * formats/config: use our fork of gcfg; improve api. * formats/config: improve api. * storage/filesystem: fix gofmt * formats/config: use NoSubsection constant. * formats/config: add doc.go * formats/config: requested sytle changes. * formats/config: do not use *_test packages.
No description provided.