aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format/config/section.go
blob: 4a17e3b21bdfc5f95bd8dccdd29a41623785577c (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
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.ToLower(s.Name) == strings.ToLower(name)
}

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

// 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
}

// 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
}

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

// 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
}