feat(build): simplify some internal tooling.
This commit is contained in:
parent
791459e39a
commit
1915fa5175
14 changed files with 140 additions and 121 deletions
|
|
@ -10,9 +10,13 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/arduino/go-paths-helper"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Default Apparmor magic directory: /etc/apparmor.d/.
|
||||||
|
var MagicRoot = paths.New("/etc/apparmor.d")
|
||||||
|
|
||||||
// AppArmorProfiles represents a full set of apparmor profiles
|
// AppArmorProfiles represents a full set of apparmor profiles
|
||||||
type AppArmorProfiles map[string]*AppArmorProfile
|
type AppArmorProfiles map[string]*AppArmorProfile
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,12 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/arduino/go-paths-helper"
|
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
regVariablesDef = regexp.MustCompile(`@{(.*)}\s*[+=]+\s*(.*)`)
|
regVariablesDef = regexp.MustCompile(`@{(.*)}\s*[+=]+\s*(.*)`)
|
||||||
regVariablesRef = regexp.MustCompile(`@{([^{}]+)}`)
|
regVariablesRef = regexp.MustCompile(`@{([^{}]+)}`)
|
||||||
|
|
||||||
// Default Apparmor magic directory: /etc/apparmor.d/.
|
|
||||||
MagicRoot = paths.New("/etc/apparmor.d")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Variable struct {
|
type Variable struct {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
regDev = util.ToRegexRepl([]string{
|
regDev = util.ToRegexRepl([]string{
|
||||||
|
`Cx`, `cx`,
|
||||||
`PUx`, `pux`,
|
`PUx`, `pux`,
|
||||||
`Px`, `px`,
|
`Px`, `px`,
|
||||||
`Ux`, `ux`,
|
`Ux`, `ux`,
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,9 @@ package cfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
|
||||||
|
|
||||||
// Filter out comments from a text configuration file
|
"github.com/roddhjav/apparmor.d/pkg/util"
|
||||||
func filterComment(line string) (string, bool) {
|
)
|
||||||
if strings.HasPrefix(line, "#") || line == "" {
|
|
||||||
return "", true
|
|
||||||
}
|
|
||||||
if strings.Contains(line, "#") {
|
|
||||||
line = strings.Split(line, "#")[0]
|
|
||||||
line = strings.TrimSpace(line)
|
|
||||||
if line == "" {
|
|
||||||
return "", true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return line, false
|
|
||||||
}
|
|
||||||
|
|
||||||
type Flagger struct{}
|
type Flagger struct{}
|
||||||
|
|
||||||
|
|
@ -32,12 +19,8 @@ func (f Flagger) Read(name string) map[string][]string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
lines, _ := path.ReadFileAsLines()
|
lines := util.MustReadFileAsLines(path)
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
line, next := filterComment(line)
|
|
||||||
if next {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
manifest := strings.Split(line, " ")
|
manifest := strings.Split(line, " ")
|
||||||
profile := manifest[0]
|
profile := manifest[0]
|
||||||
flags := []string{}
|
flags := []string{}
|
||||||
|
|
@ -52,21 +35,11 @@ func (f Flagger) Read(name string) map[string][]string {
|
||||||
type Ignorer struct{}
|
type Ignorer struct{}
|
||||||
|
|
||||||
func (i Ignorer) Read(name string) []string {
|
func (i Ignorer) Read(name string) []string {
|
||||||
res := []string{}
|
|
||||||
path := IgnoreDir.Join(name + ".ignore")
|
path := IgnoreDir.Join(name + ".ignore")
|
||||||
if !path.Exist() {
|
if !path.Exist() {
|
||||||
return res
|
return []string{}
|
||||||
}
|
}
|
||||||
|
return util.MustReadFileAsLines(path)
|
||||||
lines, _ := path.ReadFileAsLines()
|
|
||||||
for _, line := range lines {
|
|
||||||
line, next := filterComment(line)
|
|
||||||
if next {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
res = append(res, line)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Overwriter struct {
|
type Overwriter struct {
|
||||||
|
|
@ -75,19 +48,11 @@ type Overwriter struct {
|
||||||
|
|
||||||
// Get the list of upstream profiles to overwrite from dist/overwrite
|
// Get the list of upstream profiles to overwrite from dist/overwrite
|
||||||
func (o Overwriter) Get() []string {
|
func (o Overwriter) Get() []string {
|
||||||
res := []string{}
|
path := DistDir.Join("overwrite")
|
||||||
lines, err := DistDir.Join("overwrite").ReadFileAsLines()
|
if !path.Exist() {
|
||||||
if err != nil {
|
return []string{}
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
for _, line := range lines {
|
return util.MustReadFileAsLines(path)
|
||||||
line, next := filterComment(line)
|
|
||||||
if next {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
res = append(res, line)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overwrite upstream profile for APT: rename our profile & hide upstream
|
// Overwrite upstream profile for APT: rename our profile & hide upstream
|
||||||
|
|
|
||||||
|
|
@ -11,51 +11,6 @@ import (
|
||||||
"github.com/arduino/go-paths-helper"
|
"github.com/arduino/go-paths-helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_filterComment(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
line string
|
|
||||||
wantLine string
|
|
||||||
wantNext bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "comment",
|
|
||||||
line: "# comment",
|
|
||||||
wantLine: "",
|
|
||||||
wantNext: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "comment with space",
|
|
||||||
line: " # comment",
|
|
||||||
wantLine: "",
|
|
||||||
wantNext: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "no comment",
|
|
||||||
line: "no comment",
|
|
||||||
wantLine: "no comment",
|
|
||||||
wantNext: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "no comment # comment",
|
|
||||||
line: "no comment # comment",
|
|
||||||
wantLine: "no comment",
|
|
||||||
wantNext: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
gotLine, gotNext := filterComment(tt.line)
|
|
||||||
if gotLine != tt.wantLine {
|
|
||||||
t.Errorf("filterComment() got = %v, want %v", gotLine, tt.wantLine)
|
|
||||||
}
|
|
||||||
if gotNext != tt.wantNext {
|
|
||||||
t.Errorf("filterComment() got1 = %v, want %v", gotNext, tt.wantNext)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFlagger_Read(t *testing.T) {
|
func TestFlagger_Read(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ import (
|
||||||
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
|
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Define the directive keyword globally
|
|
||||||
const Keyword = "#aa:"
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// Define the directive keyword globally
|
||||||
|
Keyword = "#aa:"
|
||||||
|
|
||||||
// Build the profiles with the following directive applied
|
// Build the profiles with the following directive applied
|
||||||
Directives = map[string]Directive{}
|
Directives = map[string]Directive{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/roddhjav/apparmor.d/pkg/aa"
|
"github.com/roddhjav/apparmor.d/pkg/aa"
|
||||||
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
|
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
|
||||||
|
"github.com/roddhjav/apparmor.d/pkg/util"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ func init() {
|
||||||
Base: cfg.Base{
|
Base: cfg.Base{
|
||||||
Keyword: "exec",
|
Keyword: "exec",
|
||||||
Msg: "Exec directive applied",
|
Msg: "Exec directive applied",
|
||||||
Help: `#aa:exec [P|U|p|u|PU|pu|] profiles...`,
|
Help: Keyword + `exec [P|U|p|u|PU|pu|] profiles...`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -37,12 +38,7 @@ func (d Exec) Apply(opt *Option, profile string) string {
|
||||||
|
|
||||||
p := &aa.AppArmorProfile{}
|
p := &aa.AppArmorProfile{}
|
||||||
for name := range opt.ArgMap {
|
for name := range opt.ArgMap {
|
||||||
content, err := cfg.RootApparmord.Join(name).ReadFile()
|
profiletoTransition := util.MustReadFile(cfg.RootApparmord.Join(name))
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
profiletoTransition := string(content)
|
|
||||||
|
|
||||||
dstProfile := aa.DefaultTunables()
|
dstProfile := aa.DefaultTunables()
|
||||||
dstProfile.ParseVariables(profiletoTransition)
|
dstProfile.ParseVariables(profiletoTransition)
|
||||||
for _, variable := range dstProfile.Variables {
|
for _, variable := range dstProfile.Variables {
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,14 @@ func init() {
|
||||||
Base: cfg.Base{
|
Base: cfg.Base{
|
||||||
Keyword: "only",
|
Keyword: "only",
|
||||||
Msg: "Only directive applied",
|
Msg: "Only directive applied",
|
||||||
Help: `#aa:only filters...`,
|
Help: Keyword + `only filters...`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
RegisterDirective(&FilterExclude{
|
RegisterDirective(&FilterExclude{
|
||||||
Base: cfg.Base{
|
Base: cfg.Base{
|
||||||
Keyword: "exclude",
|
Keyword: "exclude",
|
||||||
Msg: "Exclude directive applied",
|
Msg: "Exclude directive applied",
|
||||||
Help: `#aa:exclude filters...`,
|
Help: Keyword + `exclude filters...`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ func init() {
|
||||||
Base: cfg.Base{
|
Base: cfg.Base{
|
||||||
Keyword: "stack",
|
Keyword: "stack",
|
||||||
Msg: "Stack directive applied",
|
Msg: "Stack directive applied",
|
||||||
Help: `#aa:stack profiles...`,
|
Help: Keyword + `stack profiles...`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -41,12 +41,7 @@ func init() {
|
||||||
func (s Stack) Apply(opt *Option, profile string) string {
|
func (s Stack) Apply(opt *Option, profile string) string {
|
||||||
res := ""
|
res := ""
|
||||||
for name := range opt.ArgMap {
|
for name := range opt.ArgMap {
|
||||||
tmp, err := cfg.RootApparmord.Join(name).ReadFile()
|
stackedProfile := util.MustReadFile(cfg.RootApparmord.Join(name))
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
stackedProfile := string(tmp)
|
|
||||||
|
|
||||||
m := regRules.FindStringSubmatch(stackedProfile)
|
m := regRules.FindStringSubmatch(stackedProfile)
|
||||||
if len(m) < 2 {
|
if len(m) < 2 {
|
||||||
panic(fmt.Sprintf("No profile found in %s", name))
|
panic(fmt.Sprintf("No profile found in %s", name))
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
|
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
|
||||||
"github.com/roddhjav/apparmor.d/pkg/prebuild/directive"
|
"github.com/roddhjav/apparmor.d/pkg/prebuild/directive"
|
||||||
"github.com/roddhjav/apparmor.d/pkg/prebuild/prepare"
|
"github.com/roddhjav/apparmor.d/pkg/prebuild/prepare"
|
||||||
|
"github.com/roddhjav/apparmor.d/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -65,11 +66,10 @@ func Build() error {
|
||||||
if !file.Exist() {
|
if !file.Exist() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
content, err := file.ReadFile()
|
profile, err := util.ReadFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
profile := string(content)
|
|
||||||
for _, b := range builder.Builds {
|
for _, b := range builder.Builds {
|
||||||
profile = b.Apply(profile)
|
profile = b.Apply(profile)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
|
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
|
||||||
|
"github.com/roddhjav/apparmor.d/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -43,13 +44,13 @@ func (p SetFlags) Apply() ([]string, error) {
|
||||||
// Overwrite profile flags
|
// Overwrite profile flags
|
||||||
if len(flags) > 0 {
|
if len(flags) > 0 {
|
||||||
flagsStr := " flags=(" + strings.Join(flags, ",") + ") {"
|
flagsStr := " flags=(" + strings.Join(flags, ",") + ") {"
|
||||||
content, err := file.ReadFile()
|
out, err := util.ReadFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all flags definition, then set manifest' flags
|
// Remove all flags definition, then set manifest' flags
|
||||||
out := regFlags.ReplaceAllLiteralString(string(content), "")
|
out = regFlags.ReplaceAllLiteralString(out, "")
|
||||||
out = regProfileHeader.ReplaceAllLiteralString(out, flagsStr)
|
out = regProfileHeader.ReplaceAllLiteralString(out, flagsStr)
|
||||||
if err := file.WriteFile([]byte(out)); err != nil {
|
if err := file.WriteFile([]byte(out)); err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,11 @@ func (p FullSystemPolicy) Apply() ([]string, error) {
|
||||||
|
|
||||||
// Set systemd profile name
|
// Set systemd profile name
|
||||||
path := cfg.RootApparmord.Join("tunables/multiarch.d/system")
|
path := cfg.RootApparmord.Join("tunables/multiarch.d/system")
|
||||||
content, err := path.ReadFile()
|
out, err := util.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
out := strings.Replace(string(content), "@{p_systemd}=unconfined", "@{p_systemd}=systemd", -1)
|
out = strings.Replace(out, "@{p_systemd}=unconfined", "@{p_systemd}=systemd", -1)
|
||||||
out = strings.Replace(out, "@{p_systemd_user}=unconfined", "@{p_systemd_user}=systemd-user", -1)
|
out = strings.Replace(out, "@{p_systemd_user}=unconfined", "@{p_systemd_user}=systemd-user", -1)
|
||||||
if err := path.WriteFile([]byte(out)); err != nil {
|
if err := path.WriteFile([]byte(out)); err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
|
|
@ -47,11 +47,10 @@ func (p FullSystemPolicy) Apply() ([]string, error) {
|
||||||
|
|
||||||
// Fix conflicting x modifiers in abstractions - FIXME: Temporary solution
|
// Fix conflicting x modifiers in abstractions - FIXME: Temporary solution
|
||||||
path = cfg.RootApparmord.Join("abstractions/gstreamer")
|
path = cfg.RootApparmord.Join("abstractions/gstreamer")
|
||||||
content, err = path.ReadFile()
|
out, err = util.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
out = string(content)
|
|
||||||
regFixConflictX := util.ToRegexRepl([]string{`.*gst-plugin-scanner.*`, ``})
|
regFixConflictX := util.ToRegexRepl([]string{`.*gst-plugin-scanner.*`, ``})
|
||||||
out = regFixConflictX.Replace(out)
|
out = regFixConflictX.Replace(out)
|
||||||
if err := path.WriteFile([]byte(out)); err != nil {
|
if err := path.WriteFile([]byte(out)); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,20 @@ package util
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/arduino/go-paths-helper"
|
"github.com/arduino/go-paths-helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Comment = `#`
|
||||||
|
regFilter = ToRegexRepl([]string{
|
||||||
|
`\s*` + Comment + `.*`, ``,
|
||||||
|
`(?m)^(?:[\t\s]*(?:\r?\n|\r))+`, ``,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
type RegexReplList []RegexRepl
|
type RegexReplList []RegexRepl
|
||||||
|
|
||||||
type RegexRepl struct {
|
type RegexRepl struct {
|
||||||
|
|
@ -40,7 +50,7 @@ func (rr RegexReplList) Replace(str string) string {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeHexInString decode and replace all hex value in a given string constitued of "key=value".
|
// DecodeHexInString decode and replace all hex value in a given string of "key=value" format.
|
||||||
func DecodeHexInString(str string) string {
|
func DecodeHexInString(str string) string {
|
||||||
toDecode := []string{"name", "comm", "profile"}
|
toDecode := []string{"name", "comm", "profile"}
|
||||||
for _, name := range toDecode {
|
for _, name := range toDecode {
|
||||||
|
|
@ -94,3 +104,37 @@ func CopyTo(src *paths.Path, dst *paths.Path) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter out comments and empty line from a string
|
||||||
|
func Filter(src string) string {
|
||||||
|
return regFilter.Replace(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadFile read a file and return its content as a string.
|
||||||
|
func ReadFile(path *paths.Path) (string, error) {
|
||||||
|
content, err := path.ReadFile()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(content), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustReadFile read a file and return its content as a string. Panic if an error occurs.
|
||||||
|
func MustReadFile(path *paths.Path) string {
|
||||||
|
content, err := path.ReadFile()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return string(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustReadFileAsLines read a file and return its content as a slice of string.
|
||||||
|
// It panics if an error occurs and filter out comments and empty lines.
|
||||||
|
func MustReadFileAsLines(path *paths.Path) []string {
|
||||||
|
res := strings.Split(Filter(MustReadFile(path)), "\n")
|
||||||
|
if slices.Contains(res, "") {
|
||||||
|
idx := slices.Index(res, "")
|
||||||
|
res = slices.Delete(res, idx, idx+1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,3 +151,66 @@ func TestCopyTo(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Filter(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
src string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "comment",
|
||||||
|
src: "# comment",
|
||||||
|
want: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "comment with space",
|
||||||
|
src: " # comment",
|
||||||
|
want: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no comment",
|
||||||
|
src: "no comment",
|
||||||
|
want: "no comment",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no comment # comment",
|
||||||
|
src: "no comment # comment",
|
||||||
|
want: "no comment",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
src: `
|
||||||
|
|
||||||
|
`,
|
||||||
|
want: ``,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "main",
|
||||||
|
src: `
|
||||||
|
# Common profile flags definition for all distributions
|
||||||
|
# File format: one profile by line using the format: '<profile> <flags>'
|
||||||
|
|
||||||
|
bwrap attach_disconnected,mediate_deleted,complain
|
||||||
|
bwrap-app attach_disconnected,complain
|
||||||
|
|
||||||
|
akonadi_akonotes_resource complain # Dev
|
||||||
|
gnome-disks complain
|
||||||
|
|
||||||
|
`,
|
||||||
|
want: `bwrap attach_disconnected,mediate_deleted,complain
|
||||||
|
bwrap-app attach_disconnected,complain
|
||||||
|
akonadi_akonotes_resource complain
|
||||||
|
gnome-disks complain
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
gotLine := Filter(tt.src)
|
||||||
|
if gotLine != tt.want {
|
||||||
|
t.Errorf("FilterComment() got = |%v|, want |%v|", gotLine, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue