diff options
Diffstat (limited to 'plumbing/format/config')
-rw-r--r-- | plumbing/format/config/encoder.go | 17 | ||||
-rw-r--r-- | plumbing/format/config/fixtures_test.go | 35 | ||||
-rw-r--r-- | plumbing/format/config/format.go | 53 | ||||
-rw-r--r-- | plumbing/format/config/section.go | 2 |
4 files changed, 100 insertions, 7 deletions
diff --git a/plumbing/format/config/encoder.go b/plumbing/format/config/encoder.go index 4eac896..de069ae 100644 --- a/plumbing/format/config/encoder.go +++ b/plumbing/format/config/encoder.go @@ -11,6 +11,10 @@ type Encoder struct { w io.Writer } +var ( + subsectionReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`) + valueReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`, "\n", `\n`, "\t", `\t`, "\b", `\b`) +) // NewEncoder returns a new encoder that writes to w. func NewEncoder(w io.Writer) *Encoder { return &Encoder{w} @@ -48,8 +52,7 @@ func (e *Encoder) encodeSection(s *Section) error { } func (e *Encoder) encodeSubsection(sectionName string, s *Subsection) error { - //TODO: escape - if err := e.printf("[%s \"%s\"]\n", sectionName, s.Name); err != nil { + if err := e.printf("[%s \"%s\"]\n", sectionName, subsectionReplacer.Replace(s.Name)); err != nil { return err } @@ -58,12 +61,14 @@ func (e *Encoder) encodeSubsection(sectionName string, s *Subsection) error { func (e *Encoder) encodeOptions(opts Options) error { for _, o := range opts { - pattern := "\t%s = %s\n" - if strings.Contains(o.Value, "\\") { - pattern = "\t%s = %q\n" + var value string + if strings.ContainsAny(o.Value, "#;\"\t\n\\") || strings.HasPrefix(o.Value, " ") || strings.HasSuffix(o.Value, " ") { + value = `"`+valueReplacer.Replace(o.Value)+`"` + } else { + value = o.Value } - if err := e.printf(pattern, o.Key, o.Value); err != nil { + if err := e.printf("\t%s = %s\n", o.Key, value); err != nil { return err } } diff --git a/plumbing/format/config/fixtures_test.go b/plumbing/format/config/fixtures_test.go index f3533df..2fa7840 100644 --- a/plumbing/format/config/fixtures_test.go +++ b/plumbing/format/config/fixtures_test.go @@ -43,6 +43,41 @@ var fixtures = []*Fixture{ Config: New().AddOption("core", "", "repositoryformatversion", "0"), }, { + Raw: `[section] + option1 = "has # hash" + option2 = "has \" quote" + option3 = "has \\ backslash" + option4 = "has ; semicolon" + option5 = "has \n line-feed" + option6 = "has \t tab" + option7 = " has leading spaces" + option8 = "has trailing spaces " + option9 = has no special characters + option10 = has unusual ` + "\x01\x7f\xc8\x80 characters\n", + Text: `[section] + option1 = "has # hash" + option2 = "has \" quote" + option3 = "has \\ backslash" + option4 = "has ; semicolon" + option5 = "has \n line-feed" + option6 = "has \t tab" + option7 = " has leading spaces" + option8 = "has trailing spaces " + option9 = has no special characters + option10 = has unusual ` + "\x01\x7f\xc8\x80 characters\n", + Config: New(). + AddOption("section", "", "option1", `has # hash`). + AddOption("section", "", "option2", `has " quote`). + AddOption("section", "", "option3", `has \ backslash`). + AddOption("section", "", "option4", `has ; semicolon`). + AddOption("section", "", "option5", "has \n line-feed"). + AddOption("section", "", "option6", "has \t tab"). + AddOption("section", "", "option7", ` has leading spaces`). + AddOption("section", "", "option8", `has trailing spaces `). + AddOption("section", "", "option9", `has no special characters`). + AddOption("section", "", "option10", "has unusual \x01\x7f\u0200 characters"), + }, + { Raw: ` [sect1] opt1 = value1 diff --git a/plumbing/format/config/format.go b/plumbing/format/config/format.go new file mode 100644 index 0000000..4873ea9 --- /dev/null +++ b/plumbing/format/config/format.go @@ -0,0 +1,53 @@ +package config + +// RepositoryFormatVersion represents the repository format version, +// as per defined at: +// +// https://git-scm.com/docs/repository-version +type RepositoryFormatVersion string + +const ( + // Version_0 is the format defined by the initial version of git, + // including but not limited to the format of the repository + // directory, the repository configuration file, and the object + // and ref storage. + // + // Specifying the complete behavior of git is beyond the scope + // of this document. + Version_0 = "0" + + // Version_1 is identical to version 0, with the following exceptions: + // + // 1. When reading the core.repositoryformatversion variable, a git + // implementation which supports version 1 MUST also read any + // configuration keys found in the extensions section of the + // configuration file. + // + // 2. If a version-1 repository specifies any extensions.* keys that + // the running git has not implemented, the operation MUST NOT proceed. + // Similarly, if the value of any known key is not understood by the + // implementation, the operation MUST NOT proceed. + // + // Note that if no extensions are specified in the config file, then + // core.repositoryformatversion SHOULD be set to 0 (setting it to 1 provides + // no benefit, and makes the repository incompatible with older + // implementations of git). + Version_1 = "1" + + // DefaultRepositoryFormatVersion holds the default repository format version. + DefaultRepositoryFormatVersion = Version_0 +) + +// ObjectFormat defines the object format. +type ObjectFormat string + +const ( + // SHA1 represents the object format used for SHA1. + SHA1 ObjectFormat = "sha1" + + // SHA256 represents the object format used for SHA256. + SHA256 ObjectFormat = "sha256" + + // DefaultObjectFormat holds the default object format. + DefaultObjectFormat = SHA1 +) diff --git a/plumbing/format/config/section.go b/plumbing/format/config/section.go index 07f72f3..4625ac5 100644 --- a/plumbing/format/config/section.go +++ b/plumbing/format/config/section.go @@ -103,7 +103,7 @@ func (s *Section) RemoveSubsection(name string) *Section { return s } -// Option return the value for the specified key. Empty string is returned if +// Option returns the value for the specified key. Empty string is returned if // key does not exists. func (s *Section) Option(key string) string { return s.Options.Get(key) |