Skip to content

Commit

Permalink
snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed May 10, 2020
1 parent b25c62c commit cb64d07
Show file tree
Hide file tree
Showing 17 changed files with 355 additions and 34 deletions.
7 changes: 4 additions & 3 deletions internal/generate-assets/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ func init() {
{{- end }}
}`))

output = flag.String("o", "/dev/stdout", "output")
tags = flag.String("tags", "", "tags")
output = flag.String("o", "/dev/stdout", "output")
trimPrefix = flag.String("trimprefix", "", "trim prefix")
tags = flag.String("tags", "", "tags")
)

func printMultiLineString(s []byte) string {
Expand All @@ -49,7 +50,7 @@ func run() error {
assets := make(map[string][]byte)
for _, arg := range flag.Args() {
var err error
assets[arg], err = ioutil.ReadFile(arg)
assets[strings.TrimPrefix(arg, *trimPrefix)], err = ioutil.ReadFile(arg)
if err != nil {
return err
}
Expand Down
104 changes: 87 additions & 17 deletions v2/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"io"
"os"
"os/user"
"path/filepath"
"regexp"
"runtime"
"sort"
"strings"
"text/template"
"unicode"
Expand Down Expand Up @@ -35,22 +37,26 @@ type templateConfig struct {

// A Config represents a configuration.
type Config struct {
configFile string
err error
fs vfs.FS
system chezmoi.System
SourceDir string
DestDir string
Umask permValue
DryRun bool
Follow bool
Remove bool
Verbose bool
Color string
Debug bool
SourceVCS sourceVCSConfig
Data map[string]interface{}
Template templateConfig
configFile string
err error
fs vfs.FS
system chezmoi.System
SourceDir string
DestDir string
Umask permValue
DryRun bool
Follow bool
Remove bool
Verbose bool
Color string
Output string // FIXME
Debug bool
SourceVCS sourceVCSConfig
Data map[string]interface{}
Template templateConfig

data dataCmdConfig

scriptStateBucket []byte
Stdin io.Reader
Stdout io.Writer
Expand Down Expand Up @@ -87,6 +93,9 @@ func newConfig(options ...configOption) *Config {
funcs: sprig.TxtFuncMap(),
Options: chezmoi.DefaultTemplateOptions,
},
data: dataCmdConfig{
Format: "json",
},
scriptStateBucket: []byte("script"),
Stdin: os.Stdin,
Stdout: os.Stdout,
Expand Down Expand Up @@ -116,6 +125,40 @@ func (c *Config) ensureNoError(cmd *cobra.Command, args []string) error {
return nil
}

func (c *Config) ensureSourceDirectory() error {
info, err := c.fs.Stat(c.SourceDir)
switch {
case err == nil && info.IsDir():
if chezmoi.POSIXFileModes && info.Mode()&0o77 != 0 {
return c.system.Chmod(c.SourceDir, 0o700&^os.FileMode(c.Umask))
}
return nil
case os.IsNotExist(err):
if err := vfs.MkdirAll(c.system, filepath.Dir(c.SourceDir), 0o777&^os.FileMode(c.Umask)); err != nil {
return err
}
return c.system.Mkdir(c.SourceDir, 0o700&^os.FileMode(c.Umask))
case err == nil:
return fmt.Errorf("%s: not a directory", c.SourceDir)
default:
return err
}
}

func (c *Config) getData() (map[string]interface{}, error) {
defaultData, err := c.getDefaultData()
if err != nil {
return nil, err
}
data := map[string]interface{}{
"chezmoi": defaultData,
}
for key, value := range c.Data {
data[key] = value
}
return data, nil
}

func (c *Config) getDefaultData() (map[string]interface{}, error) {
data := map[string]interface{}{
"arch": runtime.GOARCH,
Expand Down Expand Up @@ -177,7 +220,7 @@ func (c *Config) getDefaultData() (map[string]interface{}, error) {
return data, nil
}

func (c *Config) getEditor() (string, []string) {
func getEditor() (string, []string) {
editor := os.Getenv("VISUAL")
if editor == "" {
editor = os.Getenv("EDITOR")
Expand All @@ -189,6 +232,14 @@ func (c *Config) getEditor() (string, []string) {
return components[0], components[1:]
}

func getSerializationFormat(name string) (chezmoi.SerializationFormat, error) {
serializationFormat, ok := chezmoi.SerializationFormats[strings.ToLower(name)]
if !ok {
return nil, fmt.Errorf("unknown serialization format: %s", name)
}
return serializationFormat, nil
}

// isWellKnownAbbreviation returns true if word is a well known abbreviation.
func isWellKnownAbbreviation(word string) bool {
_, ok := wellKnownAbbreviations[word]
Expand All @@ -201,6 +252,25 @@ func panicOnError(err error) {
}
}

func serializationFormatNamesStr() string {
names := make([]string, 0, len(chezmoi.SerializationFormats))
for name := range chezmoi.SerializationFormats {
names = append(names, strings.ToLower(name))
}
sort.Strings(names)
switch len(names) {
case 0:
return ""
case 1:
return names[0]
case 2:
return names[0] + " or " + names[1]
default:
names[len(names)-1] = "or " + names[len(names)-1]
return strings.Join(names, ", ")
}
}

// titilize returns s, titilized.
func titilize(s string) string {
if s == "" {
Expand Down
43 changes: 43 additions & 0 deletions v2/cmd/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cmd

import (
"github.com/spf13/cobra"
)

type dataCmdConfig struct {
Format string
}

var dataCmd = &cobra.Command{
Use: "data",
Args: cobra.NoArgs,
Short: "Print the template data",
Long: mustGetLongHelp("data"),
Example: getExample("data"),
PreRunE: config.ensureNoError,
RunE: config.runDataCmd,
}

func init() {
rootCmd.AddCommand(dataCmd)

persistentFlags := dataCmd.PersistentFlags()
persistentFlags.StringVarP(&config.data.Format, "format", "f", config.data.Format, "format ("+serializationFormatNamesStr()+")")
}

func (c *Config) runDataCmd(cmd *cobra.Command, args []string) error {
serializationFormat, err := getSerializationFormat(c.data.Format)
if err != nil {
return err
}
data, err := c.getData()
if err != nil {
return err
}
serializedData, err := serializationFormat.Serialize(data)
if err != nil {
return err
}
_, err = c.Stdout.Write(serializedData)
return err
}
2 changes: 1 addition & 1 deletion v2/internal/chezmoi/chezmoi.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

// Configuration constants.
const (
posixFileModes = runtime.GOOS != "windows"
POSIXFileModes = runtime.GOOS != "windows"
pathSeparator = '/'
pathSeparatorStr = string(pathSeparator)
ignorePrefix = "."
Expand Down
8 changes: 2 additions & 6 deletions v2/internal/chezmoi/datasystem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,8 @@ func TestDataSystem(t *testing.T) {
actualData := dataSystem.Data()
assert.Equal(t, expectedData, actualData)

for _, serializationFormat := range []SerializationFormat{
JSONSerializationFormat,
TOMLSerializationFormat,
YAMLSerializationFormat,
} {
t.Run(serializationFormat.Name(), func(t *testing.T) {
for name, serializationFormat := range SerializationFormats {
t.Run(name, func(t *testing.T) {
expectedSerializedData, err := serializationFormat.Serialize(expectedData)
require.NoError(t, err)
actualSerializedData, err := serializationFormat.Serialize(actualData)
Expand Down
2 changes: 1 addition & 1 deletion v2/internal/chezmoi/encryptiontool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func testEncryptionToolEncryptFile(t *testing.T, et EncryptionTool) {
defer func() {
assert.NoError(t, os.RemoveAll(tempFile.Name()))
}()
if posixFileModes {
if POSIXFileModes {
require.NoError(t, tempFile.Chmod(0o600))
}
_, err = tempFile.Write(expectedPlaintext)
Expand Down
2 changes: 1 addition & 1 deletion v2/internal/chezmoi/gpgencryptiontool.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (t *GPGEncryptionTool) Encrypt(plaintext []byte) (ciphertext []byte, err er
err = multierr.Append(err, os.RemoveAll(tempFile.Name()))
}()

if posixFileModes {
if POSIXFileModes {
if err = tempFile.Chmod(0o600); err != nil {
return
}
Expand Down
2 changes: 1 addition & 1 deletion v2/internal/chezmoi/gpgencryptiontool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestGPGEncryptionTool(t *testing.T) {
assert.NoError(t, os.RemoveAll(tempDir))
}()

if posixFileModes {
if POSIXFileModes {
require.NoError(t, os.Chmod(tempDir, 0o700))
}

Expand Down
4 changes: 4 additions & 0 deletions v2/internal/chezmoi/jsonserializationformat.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ func (jsonSerializationFormat) Deserialize(data []byte) (interface{}, error) {
}
return result, nil
}

func init() {
SerializationFormats[JSONSerializationFormat.Name()] = JSONSerializationFormat
}
6 changes: 3 additions & 3 deletions v2/internal/chezmoi/realsystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func NewRealSystem(fs vfs.FS, persistentState PersistentState) *RealSystem {

// Chmod implements System.Glob.
func (s *RealSystem) Chmod(name string, mode os.FileMode) error {
if !posixFileModes {
if !POSIXFileModes {
return nil
}
return s.FS.Chmod(name, mode)
Expand Down Expand Up @@ -78,7 +78,7 @@ func (s *RealSystem) RunScript(scriptname string, data []byte) (err error) {

// Make the script private before writing it in case it contains any
// secrets.
if posixFileModes {
if POSIXFileModes {
if err = f.Chmod(0o700); err != nil {
return
}
Expand Down Expand Up @@ -129,7 +129,7 @@ func WriteFile(fs vfs.FS, filename string, data []byte, perm os.FileMode) (err e
// Set permissions after truncation but before writing any data, in case the
// file contained private data before, but before writing the new contents,
// in case the contents contain private data after.
if posixFileModes {
if POSIXFileModes {
if err = f.Chmod(perm); err != nil {
return
}
Expand Down
3 changes: 3 additions & 0 deletions v2/internal/chezmoi/serializationformat.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ type SerializationFormat interface {
Name() string
Serialize(data interface{}) ([]byte, error)
}

// SerializationFormats is a map of all SerializationFormats by name.
var SerializationFormats = make(map[string]SerializationFormat)
13 changes: 13 additions & 0 deletions v2/internal/chezmoi/serializationformat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package chezmoi

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestSerializationFormats(t *testing.T) {
assert.Contains(t, SerializationFormats, "json")
assert.Contains(t, SerializationFormats, "toml")
assert.Contains(t, SerializationFormats, "yaml")
}
2 changes: 1 addition & 1 deletion v2/internal/chezmoi/targetstateentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func (t *TargetStateFile) Equal(destStateEntry DestStateEntry) (bool, error) {
log.Printf("other is a %T, not a *DestStateFile\n", destStateEntry)
return false, nil
}
if posixFileModes && destStateFile.perm != t.perm {
if POSIXFileModes && destStateFile.perm != t.perm {
log.Printf("other has perm %o, want %o", destStateFile.perm, t.perm)
return false, nil
}
Expand Down
4 changes: 4 additions & 0 deletions v2/internal/chezmoi/tomlserializationformat.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ func (tomlSerializationFormat) Deserialize(data []byte) (interface{}, error) {
}
return result, nil
}

func init() {
SerializationFormats[TOMLSerializationFormat.Name()] = TOMLSerializationFormat
}
4 changes: 4 additions & 0 deletions v2/internal/chezmoi/yamlserializationformat.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ func (yamlSerializationFormat) Deserialize(data []byte) (interface{}, error) {
}
return result, nil
}

func init() {
SerializationFormats[YAMLSerializationFormat.Name()] = YAMLSerializationFormat
}
Loading

0 comments on commit cb64d07

Please sign in to comment.