aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format/config/section.go
blob: 07f72f35af2c0ec2cee8eb4a207d85f1b7739898 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package config

import (
	"fmt"
	"strings"
)

// Section is the representation of a section inside git configuration files.
// Each Section contains Options that are used by both the Git plumbing
// and the porcelains.
// Sections can be further divided into subsections. To begin a subsection
// put its name in double quotes, separated by space from the section name,
// in the section header, like in the example below:
//
//     [section "subsection"]
//
// All the other lines (and the remainder of the line after the section header)
// are recognized as option variables, in the form "name = value" (or just name,
// which is a short-hand to say that the variable is the boolean "true").
// The variable names are case-insensitive, allow only alphanumeric characters
// and -, and must start with an alphabetic character:
//
//     [section "subsection1"]
//         option1 = value1
//         option2
//     [section "subsection2"]
//         option3 = value2
//
type Section struct {
	Name        string
	Options     Options
	Subsections Subsections
}

type Subsection struct {
	Name    string
	Options Options
}

type Sections []*Section

func (s Sections) GoString() string {
	var strs []string
	for _, ss := range s {
		strs = append(strs, fmt.Sprintf("%#v", ss))
	}

	return strings.Join(strs, ", ")
}

type Subsections []*Subsection

func (s Subsections) GoString() string {
	var strs []string
	for _, ss := range s {
		strs = append(strs, fmt.Sprintf("%#v", ss))
	}

	return strings.Join(strs, ", ")
}

// IsName checks if the name provided is equals to the Section name, case insensitive.
func (s *Section) IsName(name string) bool {
	return strings.EqualFold(s.Name, name)
}

// Subsection returns a Subsection from the specified Section. If the
// Subsection does not exists, new one is created and added to Section.
func (s *Section) Subsection(name string) *Subsection {
	for i := len(s.Subsections) - 1; i >= 0; i-- {
		ss := s.Subsections[i]
		if ss.IsName(name) {
			return ss
		}
	}

	ss := &Subsection{Name: name}
	s.Subsections = append(s.Subsections, ss)
	return ss
}

// HasSubsection checks if the Section has a Subsection with the specified name.
func (s *Section) HasSubsection(name string) bool {
	for _, ss := range s.Subsections {
		if ss.IsName(name) {
			return true
		}
	}

	return false
}

// RemoveSubsection removes a subsection from a Section.
func (s *Section) RemoveSubsection(name string) *Section {
	result := Subsections{}
	for _, s := range s.Subsections {
		if !s.IsName(name) {
			result = append(result, s)
		}
	}

	s.Subsections = result
	return s
}

// Option return 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)
}

// OptionAll returns all possible values for an option with the specified key.
// If the option does not exists, an empty slice will be returned.
func (s *Section) OptionAll(key string) []string {
	return s.Options.GetAll(key)
}

// HasOption checks if the Section has an Option with the given key.
func (s *Section) HasOption(key string) bool {
	return s.Options.Has(key)
}

// AddOption adds a new Option to the Section. The updated Section is returned.
func (s *Section) AddOption(key string, value string) *Section {
	s.Options = s.Options.withAddedOption(key, value)
	return s
}

// SetOption adds a new Option to the Section. If the option already exists, is replaced.
// The updated Section is returned.
func (s *Section) SetOption(key string, value string) *Section {
	s.Options = s.Options.withSettedOption(key, value)
	return s
}

// Remove an option with the specified key. The updated Section is returned.
func (s *Section) RemoveOption(key string) *Section {
	s.Options = s.Options.withoutOption(key)
	return s
}

// IsName checks if the name of the subsection is exactly the specified name.
func (s *Subsection) IsName(name string) bool {
	return s.Name == name
}

// Option returns an option with the specified key. If the option does not exists,
// empty spring will be returned.
func (s *Subsection) Option(key string) string {
	return s.Options.Get(key)
}

// OptionAll returns all possible values for an option with the specified key.
// If the option does not exists, an empty slice will be returned.
func (s *Subsection) OptionAll(key string) []string {
	return s.Options.GetAll(key)
}

// HasOption checks if the Subsection has an Option with the given key.
func (s *Subsection) HasOption(key string) bool {
	return s.Options.Has(key)
}

// AddOption adds a new Option to the Subsection. The updated Subsection is returned.
func (s *Subsection) AddOption(key string, value string) *Subsection {
	s.Options = s.Options.withAddedOption(key, value)
	return s
}

// SetOption adds a new Option to the Subsection. If the option already exists, is replaced.
// The updated Subsection is returned.
func (s *Subsection) SetOption(key string, value ...string) *Subsection {
	s.Options = s.Options.withSettedOption(key, value...)
	return s
}

// RemoveOption removes the option with the specified key. The updated Subsection is returned.
func (s *Subsection) RemoveOption(key string) *Subsection {
	s.Options = s.Options.withoutOption(key)
	return s
}