github.com/google/yamlfmt@v0.12.2-0.20240514121411-7f77800e2681/engine.go (about) 1 // Copyright 2024 Google LLC 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 15 package yamlfmt 16 17 import ( 18 "fmt" 19 "os" 20 21 "github.com/google/yamlfmt/internal/collections" 22 "github.com/google/yamlfmt/internal/multilinediff" 23 ) 24 25 type Operation int 26 27 const ( 28 OperationFormat Operation = iota 29 OperationLint 30 OperationDry 31 OperationStdin 32 OperationPrintConfig 33 ) 34 35 type Engine interface { 36 FormatContent(content []byte) ([]byte, error) 37 Format(paths []string) (fmt.Stringer, error) 38 Lint(paths []string) (fmt.Stringer, error) 39 DryRun(paths []string) (fmt.Stringer, error) 40 } 41 42 type FormatDiff struct { 43 Original string 44 Formatted string 45 LineSep string 46 } 47 48 func (d *FormatDiff) MultilineDiff() (string, int) { 49 return multilinediff.Diff(d.Original, d.Formatted, d.LineSep) 50 } 51 52 func (d *FormatDiff) Changed() bool { 53 return d.Original != d.Formatted 54 } 55 56 type FileDiff struct { 57 Path string 58 Diff *FormatDiff 59 } 60 61 func (fd *FileDiff) StrOutput() string { 62 diffStr, _ := fd.Diff.MultilineDiff() 63 return fmt.Sprintf("%s:\n%s\n", fd.Path, diffStr) 64 } 65 66 func (fd *FileDiff) StrOutputQuiet() string { 67 return fd.Path + "\n" 68 } 69 70 func (fd *FileDiff) Apply() error { 71 // If there is no diff in the format, there is no need to write the file. 72 if !fd.Diff.Changed() { 73 return nil 74 } 75 return os.WriteFile(fd.Path, []byte(fd.Diff.Formatted), 0644) 76 } 77 78 type FileDiffs map[string]*FileDiff 79 80 func (fds FileDiffs) Add(diff *FileDiff) error { 81 if _, ok := fds[diff.Path]; ok { 82 return fmt.Errorf("a diff for %s already exists", diff.Path) 83 } 84 85 fds[diff.Path] = diff 86 return nil 87 } 88 89 func (fds FileDiffs) StrOutput() string { 90 result := "" 91 for _, fd := range fds { 92 if fd.Diff.Changed() { 93 result += fd.StrOutput() 94 } 95 } 96 return result 97 } 98 99 func (fds FileDiffs) StrOutputQuiet() string { 100 result := "" 101 for _, fd := range fds { 102 if fd.Diff.Changed() { 103 result += fd.StrOutputQuiet() 104 } 105 } 106 return result 107 } 108 109 func (fds FileDiffs) ApplyAll() error { 110 applyErrs := make(collections.Errors, len(fds)) 111 i := 0 112 for _, diff := range fds { 113 applyErrs[i] = diff.Apply() 114 i++ 115 } 116 return applyErrs.Combine() 117 } 118 119 func (fds FileDiffs) ChangedCount() int { 120 changed := 0 121 for _, fd := range fds { 122 if fd.Diff.Changed() { 123 changed++ 124 } 125 } 126 return changed 127 }