Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

formats/config: Added encoder/decoder for git config files. #97

Merged
merged 14 commits into from
Oct 26, 2016
Merged

formats/config: Added encoder/decoder for git config files. #97

merged 14 commits into from
Oct 26, 2016

Conversation

smola
Copy link
Collaborator

@smola smola commented Oct 25, 2016

No description provided.

return true
})

err = decode(c, config, fset, file, src)
Copy link
Contributor

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)

Copy link
Collaborator Author

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-- {
Copy link
Contributor

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 ?

Copy link
Contributor

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?

Copy link
Collaborator Author

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).

Copy link
Contributor

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 {
Copy link
Contributor

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?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Right.

Copy link
Contributor

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 {
Copy link
Contributor

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...

Copy link
Collaborator Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍

}
}
}
panic("never reached")
Copy link
Contributor

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?

Copy link
Collaborator Author

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"]
Copy link
Contributor

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?

Copy link
Collaborator Author

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"]
Copy link
Contributor

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?

Copy link
Collaborator Author

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 == "" {
Copy link
Contributor

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 ""?

Copy link
Collaborator Author

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
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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
Copy link
Contributor

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?

Copy link
Collaborator Author

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 (;. #).

Copy link
Contributor

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
Copy link
Contributor

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

Copy link
Collaborator Author

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 {
Copy link
Contributor

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

Copy link
Contributor

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-- {
Copy link
Contributor

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?

Copy link
Contributor

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
Copy link
Contributor

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

Copy link
Collaborator Author

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 {
}
Copy link
Contributor

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@mcuadros mcuadros merged commit cb29a2c into src-d:master Oct 26, 2016
@smola smola deleted the ini branch October 28, 2016 09:05
mcuadros pushed a commit that referenced this pull request Jan 31, 2017
* 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.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants