Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial commit supporting 0.11.0-dev #22

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ require (
github.com/cbroglie/mustache v1.3.1
github.com/nlepage/go-tarfs v1.1.0
github.com/sirupsen/logrus v1.8.1
golang.org/x/exp v0.0.0-20220706164943-b4a6d9510983
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)
14 changes: 8 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nlepage/go-tarfs v1.1.0 h1:bsACOiZMB/zFjYG/sE01070i9Fl26MnRpw0L6WuyfVs=
github.com/nlepage/go-tarfs v1.1.0/go.mod h1:IhxRcLhLkawBetnwu/JNuoPkq/6cclAllhgEa6SmzS8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -20,12 +20,14 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/exp v0.0.0-20220706164943-b4a6d9510983 h1:sUweFwmLOje8KNfXAVqGGAsmgJ/F8jJ6wBLJDt4BTKY=
golang.org/x/exp v0.0.0-20220706164943-b4a6d9510983/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/sirupsen/logrus"
)

//go:embed schemes/*.yaml
//go:embed schemes/*/*.yaml
var schemesFS embed.FS

var (
Expand Down
204 changes: 143 additions & 61 deletions scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,36 @@ import (
yaml "gopkg.in/yaml.v3"
)

var bases = []string{
"00", "01", "02", "03", "04", "05", "06", "07",
"08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
var base16Bases = []string{
"base00", "base01", "base02", "base03", "base04", "base05", "base06", "base07",
"base08", "base09", "base0A", "base0B", "base0C", "base0D", "base0E", "base0F",
}

type scheme struct {
Slug string `yaml:"-"`
var base24Bases = []string{
"base10", "base11", "base12", "base13", "base14", "base15", "base16", "base17",
}

Scheme string `yaml:"scheme"`
Author string `yaml:"author"`
Description string `yaml:"description"`
// legacyScheme contains only the fields which are different between a base16
// scheme and our universal scheme format.
type legacyScheme struct {
Scheme string `yaml:"scheme"`

// Colors will hold all the "base*" variables.
Colors map[string]color `yaml:",inline"`
}

func schemeFromFile(schemesFS fs.FS, fileName string) (*scheme, bool) {
ret := &scheme{}
type universalScheme struct {
Slug string `yaml:"-"`

Name string `yaml:"name"`
Author string `yaml:"author"`
System string `yaml:"system"`
Description string `yaml:"description"`
Palette map[string]color `yaml:"palette"`
}

func schemeFromFile(schemesFS fs.FS, fileName string) (*universalScheme, bool) {
ret := &universalScheme{}

logger := log.WithField("file", fileName)

Expand All @@ -47,9 +59,60 @@ func schemeFromFile(schemesFS fs.FS, fileName string) (*scheme, bool) {
return nil, false
}

// If there's no scheme system defined, we assume this is either a base16 or
// base24 style scheme, so we need to parse it again as the legacy format
// and convert it.
if ret.System == "" {
var legacy legacyScheme
err = yaml.Unmarshal(data, &legacy)
if err != nil {
logger.Error(err)
return nil, false
}

// The name was previously called "scheme".
ret.Name = legacy.Scheme

var missingColors []string

for _, baseKey := range base16Bases {
if val, ok := legacy.Colors[baseKey]; ok {
ret.Palette[baseKey] = val
} else {
missingColors = append(missingColors, baseKey)
}
}

// At this point we've checked all of the original 16 bases (which are
// included in both base16 and base24), so if we don't have all 16
// colors, it's an error.
if len(ret.Palette) != 16 {
logger.Errorf("Missing colors from base16 pallete: %s", strings.Join(missingColors, ", "))
return nil, false
}

for _, baseKey := range base24Bases {
if val, ok := legacy.Colors[baseKey]; ok {
ret.Palette[baseKey] = val
} else {
missingColors = append(missingColors, baseKey)
}
}

// Infer the palette based on how many colors we ended up with.
if len(ret.Palette) == 16 {
ret.System = "base16"
} else if len(ret.Palette) == 24 {
ret.System = "base24"
} else {
logger.Errorf("Missing colors from base24 pallete: %s", strings.Join(missingColors, ", "))
return nil, false
}
}

// Now that we have the data, we can sanitize it
ok := true
if ret.Scheme == "" {
if ret.Name == "" {
logger.Error("Scheme name cannot be empty")
ok = false
}
Expand All @@ -60,98 +123,117 @@ func schemeFromFile(schemesFS fs.FS, fileName string) (*scheme, bool) {
logger.Warn("Scheme author should not be empty")
}

if len(bases) != len(ret.Colors) {
logger.Error("Wrong number of colors in scheme")
ok = false
}

// Sanitize any fields which were added later
if ret.Description == "" {
ret.Description = ret.Scheme
ret.Description = ret.Name
}

// Now that we've got all that out of the way, we can start
// processing stuff.

// Take the last path component and chop off .yaml
ret.Slug = filepath.Base(strings.TrimSuffix(fileName, ".yaml"))

for _, base := range bases {
baseKey := "base" + base
if _, innerOk := ret.Colors[baseKey]; !innerOk {
logger.Errorf("Scheme missing %q", baseKey)
ok = false
continue
}
}

return ret, ok
}

func (s *scheme) mustacheContext() map[string]interface{} {
func (s *universalScheme) mustacheContext() map[string]interface{} {
ret := map[string]interface{}{
"scheme-name": s.Scheme,
"scheme-author": s.Author,
"scheme-slug": s.Slug,
"scheme-description": s.Description,

// Any extensions on the spec should go here
"scheme-name": s.Name,
"scheme-author": s.Author,
"scheme-slug": s.Slug,
"scheme-system": s.System,
"scheme-description": s.Description,
"scheme-slug-underscored": strings.Replace(s.Slug, "-", "_", -1),
}

for _, base := range bases {
baseKey := "base" + base
baseVal := s.Colors[baseKey]

for colorKey, colorVal := range s.Palette {
// Note that we only lowercase the output of this to match the reference
// repo.
ret[baseKey+"-hex"] = fmt.Sprintf("%02x%02x%02x", baseVal.R, baseVal.G, baseVal.B)
ret[baseKey+"-hex-bgr"] = fmt.Sprintf("%02x%02x%02x", baseVal.B, baseVal.G, baseVal.R)

ret[baseKey+"-rgb-r"] = baseVal.R
ret[baseKey+"-rgb-g"] = baseVal.G
ret[baseKey+"-rgb-b"] = baseVal.B
ret[baseKey+"-dec-r"] = float32(baseVal.R) / 255
ret[baseKey+"-dec-g"] = float32(baseVal.G) / 255
ret[baseKey+"-dec-b"] = float32(baseVal.B) / 255
ret[baseKey+"-hex-r"] = fmt.Sprintf("%02x", baseVal.R)
ret[baseKey+"-hex-g"] = fmt.Sprintf("%02x", baseVal.G)
ret[baseKey+"-hex-b"] = fmt.Sprintf("%02x", baseVal.B)
ret[colorKey+"-hex"] = fmt.Sprintf("%02x%02x%02x", colorVal.R, colorVal.G, colorVal.B)
ret[colorKey+"-hex-bgr"] = fmt.Sprintf("%02x%02x%02x", colorVal.B, colorVal.G, colorVal.R)

ret[colorKey+"-rgb-r"] = colorVal.R
ret[colorKey+"-rgb-g"] = colorVal.G
ret[colorKey+"-rgb-b"] = colorVal.B
ret[colorKey+"-dec-r"] = float32(colorVal.R) / 255
ret[colorKey+"-dec-g"] = float32(colorVal.G) / 255
ret[colorKey+"-dec-b"] = float32(colorVal.B) / 255
ret[colorKey+"-hex-r"] = fmt.Sprintf("%02x", colorVal.R)
ret[colorKey+"-hex-g"] = fmt.Sprintf("%02x", colorVal.G)
ret[colorKey+"-hex-b"] = fmt.Sprintf("%02x", colorVal.B)
}

return ret
}

func loadSchemes(schemesFS fs.FS) ([]*scheme, bool) {
schemes := make(map[string]*scheme)
func loadSchemes(schemesFS fs.FS) ([]*universalScheme, bool) {
schemes := make(map[string]map[string]*universalScheme)

// Pre-create some of our special cases to make it easier later
schemes["base16"] = make(map[string]*universalScheme)
schemes["base17"] = make(map[string]*universalScheme)

schemePaths, err := fs.Glob(schemesFS, "*.yaml")
if err != nil {
log.Error(err)
return nil, false
}

additionalSchemePaths, err := fs.Glob(schemesFS, "*/*.yaml")
if err != nil {
log.Error(err)
return nil, false
}

schemePaths = append(schemePaths, additionalSchemePaths...)

for _, schemePath := range schemePaths {
scheme, ok := schemeFromFile(schemesFS, schemePath)
if !ok {
log.Errorf("Failed to load scheme")
return nil, false
}

// XXX: this should never happen because it's now a single schemes dir,
// but we include this check just in case someone messed something up.
if _, ok := schemes[scheme.Slug]; ok {
if _, ok := schemes[scheme.System]; !ok {
schemes[scheme.System] = make(map[string]*universalScheme)
}

if _, ok := schemes[scheme.System][scheme.Slug]; ok {
log.WithField("scheme", scheme.Slug).Warnf("Conflicting scheme")
}

log.Debugf("Found scheme %q", scheme.Slug)

schemes[scheme.Slug] = scheme
schemes[scheme.System][scheme.Slug] = scheme
}

// Copy all base17 schemes to base16 which are missing
for _, scheme := range schemes["base17"] {
if _, ok := schemes["base16"][scheme.Slug]; ok {
continue
}

// Copy the scheme and update the "system"
var newScheme universalScheme = *scheme
newScheme.System = "base16"
schemes["base16"][scheme.Slug] = &newScheme
}

ret := []*scheme{}
for _, scheme := range schemes {
ret = append(ret, scheme)
// Copy all base16 schemes to base17 which are missing
for _, scheme := range schemes["base16"] {
if _, ok := schemes["base17"][scheme.Slug]; ok {
continue
}

// Copy the scheme and update the "system"
var newScheme universalScheme = *scheme
newScheme.System = "base17"
schemes["base17"][scheme.Slug] = &newScheme
}

var ret []*universalScheme
for _, system := range schemes {
for _, scheme := range system {
ret = append(ret, scheme)
}
}

return ret, true
Expand Down
2 changes: 1 addition & 1 deletion schemes
Loading