Skip to content

Commit

Permalink
Convert os-release keys to JSON-like keys
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Jan 15, 2019
1 parent bf690dd commit c1525d8
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 1 deletion.
50 changes: 49 additions & 1 deletion cmd/os_release.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ import (
"os"
"strconv"
"strings"
"unicode"

vfs "github.com/twpayne/go-vfs"
)

var (
wellKnownAbbreviations = map[string]struct{}{
"ANSI": struct{}{},
"CPE": struct{}{},
"URL": struct{}{},
}
)

// getOSRelease returns the operating system identification data as defined by
// https://www.freedesktop.org/software/systemd/man/os-release.html.
func getOSRelease(fs vfs.FS) (map[string]string, error) {
Expand All @@ -22,11 +31,21 @@ func getOSRelease(fs vfs.FS) (map[string]string, error) {
return nil, err
}
defer f.Close()
return parseOSRelease(f)
m, err := parseOSRelease(f)
if err != nil {
return nil, err
}
return upperSnakeCaseToCamelCaseMap(m), nil
}
return nil, os.ErrNotExist
}

// isWellKnownAbbreviation returns true if word is a well known abbreviation.
func isWellKnownAbbreviation(word string) bool {
_, ok := wellKnownAbbreviations[word]
return ok
}

// maybeUnquote removes quotation marks around s.
func maybeUnquote(s string) string {
// Try to unquote.
Expand All @@ -53,3 +72,32 @@ func parseOSRelease(r io.Reader) (map[string]string, error) {
}
return result, s.Err()
}

// titilize returns s, titilized.
func titilize(s string) string {
runes := []rune(s)
return string(append([]rune{unicode.ToTitle(runes[0])}, runes[1:]...))
}

// upperSnakeCaseToCamelCase converts a string in UPPER_SNAKE_CASE to
// camelCase.
func upperSnakeCaseToCamelCase(s string) string {
words := strings.Split(s, "_")
for i, word := range words {
if i == 0 {
words[i] = strings.ToLower(word)
} else if !isWellKnownAbbreviation(word) {
words[i] = titilize(strings.ToLower(word))
}
}
return strings.Join(words, "")
}

// upperSnakeCaseToCamelCaseKeys returns m with all keys converted from UPPER_SNAKE_CASE to camelCase.
func upperSnakeCaseToCamelCaseMap(m map[string]string) map[string]string {
result := make(map[string]string)
for k, v := range m {
result[upperSnakeCaseToCamelCase(k)] = v
}
return result
}
97 changes: 97 additions & 0 deletions cmd/os_release_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,87 @@ import (
"testing"

"github.com/d4l3k/messagediff"
"github.com/twpayne/go-vfs/vfst"
)

func TestGetOSRelease(t *testing.T) {
for _, tc := range []struct {
name string
root map[string]interface{}
want map[string]string
}{
{
name: "fedora",
root: map[string]interface{}{
"/etc/os-release": `NAME=Fedora
VERSION="17 (Beefy Miracle)"
ID=fedora
VERSION_ID=17
PRETTY_NAME="Fedora 17 (Beefy Miracle)"
ANSI_COLOR="0;34"
CPE_NAME="cpe:/o:fedoraproject:fedora:17"
HOME_URL="https://fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"`,
},
want: map[string]string{
"name": "Fedora",
"version": "17 (Beefy Miracle)",
"id": "fedora",
"versionId": "17",
"prettyName": "Fedora 17 (Beefy Miracle)",
"ansiColor": "0;34",
"cpeName": "cpe:/o:fedoraproject:fedora:17",
"homeURL": "https://fedoraproject.org/",
"bugReportURL": "https://bugzilla.redhat.com/",
},
},
{
name: "ubuntu",
root: map[string]interface{}{
"/usr/lib/os-release": `NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic`,
},
want: map[string]string{
"name": "Ubuntu",
"version": "18.04.1 LTS (Bionic Beaver)",
"id": "ubuntu",
"idLike": "debian",
"prettyName": "Ubuntu 18.04.1 LTS",
"versionId": "18.04",
"homeURL": "https://www.ubuntu.com/",
"supportURL": "https://help.ubuntu.com/",
"bugReportURL": "https://bugs.launchpad.net/ubuntu/",
"privacyPolicyURL": "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy",
"versionCodename": "bionic",
"ubuntuCodename": "bionic",
},
},
} {
t.Run(tc.name, func(t *testing.T) {
fs, cleanup, err := vfst.NewTestFS(tc.root)
if err != nil {
t.Fatalf("vfst.NewTestFS(_) == _, _, %v, want _, _, <nil>", err)
}
defer cleanup()
got, gotErr := getOSRelease(fs)
diff, equal := messagediff.PrettyDiff(tc.want, got)
if gotErr != nil || !equal {
t.Errorf("getOSRelease(fs) == %v, %v, want %v, <nil>\n%s", got, gotErr, tc.want, diff)
}
})
}
}

func TestParseOSRelease(t *testing.T) {
for _, tc := range []struct {
s string
Expand Down Expand Up @@ -70,3 +149,21 @@ UBUNTU_CODENAME=bionic`,
}
}
}

func TestUppercaseSnakeToCamelCase(t *testing.T) {
for _, tc := range []struct {
s string
want string
}{
{s: "ID", want: "id"},
{s: "NAME", want: "name"},
{s: "ID_LIKE", want: "idLike"},
{s: "PRETTY_NAME", want: "prettyName"},
{s: "ANSI_COLOR", want: "ansiColor"},
{s: "BUG_REPORT_URL", want: "bugReportURL"},
} {
if got := upperSnakeCaseToCamelCase(tc.s); got != tc.want {
t.Errorf("uppercaseSnakeToCamelCase(%q) == %q, want %q", tc.s, got, tc.want)
}
}
}

0 comments on commit c1525d8

Please sign in to comment.