1// Copyright 2018 The CUE Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package cmd 16 17import ( 18 "github.com/spf13/cobra" 19 20 "cuelang.org/go/cue/ast" 21 "cuelang.org/go/cue/build" 22 "cuelang.org/go/cue/errors" 23 "cuelang.org/go/cue/format" 24 "cuelang.org/go/cue/load" 25 "cuelang.org/go/cue/token" 26 "cuelang.org/go/internal/encoding" 27 "cuelang.org/go/tools/fix" 28) 29 30func newFmtCmd(c *Command) *cobra.Command { 31 cmd := &cobra.Command{ 32 Use: "fmt [-s] [inputs]", 33 Short: "formats CUE configuration files", 34 Long: `Fmt formats the given files or the files for the given packages in place 35`, 36 RunE: mkRunE(c, func(cmd *Command, args []string) error { 37 plan, err := newBuildPlan(cmd, args, &config{loadCfg: &load.Config{ 38 Tests: true, 39 Tools: true, 40 AllCUEFiles: true, 41 Package: "*", 42 }}) 43 exitOnErr(cmd, err, true) 44 45 builds := loadFromArgs(cmd, args, plan.cfg.loadCfg) 46 if builds == nil { 47 exitOnErr(cmd, errors.Newf(token.NoPos, "invalid args"), true) 48 } 49 50 opts := []format.Option{} 51 if flagSimplify.Bool(cmd) { 52 opts = append(opts, format.Simplify()) 53 } 54 55 cfg := *plan.encConfig 56 cfg.Format = opts 57 cfg.Force = true 58 59 for _, inst := range builds { 60 if inst.Err != nil { 61 var p *load.PackageError 62 switch { 63 case errors.As(inst.Err, &p): 64 default: 65 exitOnErr(cmd, inst.Err, false) 66 continue 67 } 68 } 69 for _, file := range inst.BuildFiles { 70 files := []*ast.File{} 71 d := encoding.NewDecoder(file, &cfg) 72 defer d.Close() 73 for ; !d.Done(); d.Next() { 74 f := d.File() 75 76 if file.Encoding == build.CUE { 77 f = fix.File(f) 78 } 79 80 files = append(files, f) 81 } 82 83 e, err := encoding.NewEncoder(file, &cfg) 84 exitOnErr(cmd, err, true) 85 86 for _, f := range files { 87 err := e.EncodeFile(f) 88 exitOnErr(cmd, err, false) 89 } 90 e.Close() 91 } 92 } 93 return nil 94 }), 95 } 96 return cmd 97} 98