]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/hashicorp/terraform/internal/modsdir/manifest.go
Merge branch 'fix_read_test' of github.com:alexandreFre/terraform-provider-statuscake
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / internal / modsdir / manifest.go
CommitLineData
107c1cdb
ND
1package modsdir
2
3import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "io/ioutil"
8 "log"
9 "os"
10 "path/filepath"
11
12 version "github.com/hashicorp/go-version"
13
14 "github.com/hashicorp/terraform/addrs"
15)
16
17// Record represents some metadata about an installed module, as part
18// of a ModuleManifest.
19type Record struct {
20 // Key is a unique identifier for this particular module, based on its
21 // position within the static module tree.
22 Key string `json:"Key"`
23
24 // SourceAddr is the source address given for this module in configuration.
25 // This is used only to detect if the source was changed in configuration
26 // since the module was last installed, which means that the installer
27 // must re-install it.
28 SourceAddr string `json:"Source"`
29
30 // Version is the exact version of the module, which results from parsing
31 // VersionStr. nil for un-versioned modules.
32 Version *version.Version `json:"-"`
33
34 // VersionStr is the version specifier string. This is used only for
35 // serialization in snapshots and should not be accessed or updated
36 // by any other codepaths; use "Version" instead.
37 VersionStr string `json:"Version,omitempty"`
38
39 // Dir is the path to the local directory where the module is installed.
40 Dir string `json:"Dir"`
41}
42
43// Manifest is a map used to keep track of the filesystem locations
44// and other metadata about installed modules.
45//
46// The configuration loader refers to this, while the module installer updates
47// it to reflect any changes to the installed modules.
48type Manifest map[string]Record
49
50func (m Manifest) ModuleKey(path addrs.Module) string {
51 return path.String()
52}
53
54// manifestSnapshotFile is an internal struct used only to assist in our JSON
55// serialization of manifest snapshots. It should not be used for any other
56// purpose.
57type manifestSnapshotFile struct {
58 Records []Record `json:"Modules"`
59}
60
61func ReadManifestSnapshot(r io.Reader) (Manifest, error) {
62 src, err := ioutil.ReadAll(r)
63 if err != nil {
64 return nil, err
65 }
66
67 if len(src) == 0 {
68 // This should never happen, but we'll tolerate it as if it were
69 // a valid empty JSON object.
70 return make(Manifest), nil
71 }
72
73 var read manifestSnapshotFile
74 err = json.Unmarshal(src, &read)
75
76 new := make(Manifest)
77 for _, record := range read.Records {
78 if record.VersionStr != "" {
79 record.Version, err = version.NewVersion(record.VersionStr)
80 if err != nil {
81 return nil, fmt.Errorf("invalid version %q for %s: %s", record.VersionStr, record.Key, err)
82 }
83 }
84 if _, exists := new[record.Key]; exists {
85 // This should never happen in any valid file, so we'll catch it
86 // and report it to avoid confusing/undefined behavior if the
87 // snapshot file was edited incorrectly outside of Terraform.
88 return nil, fmt.Errorf("snapshot file contains two records for path %s", record.Key)
89 }
90 new[record.Key] = record
91 }
92 return new, nil
93}
94
95func ReadManifestSnapshotForDir(dir string) (Manifest, error) {
96 fn := filepath.Join(dir, ManifestSnapshotFilename)
97 r, err := os.Open(fn)
98 if err != nil {
99 if os.IsNotExist(err) {
100 return make(Manifest), nil // missing file is okay and treated as empty
101 }
102 return nil, err
103 }
104 return ReadManifestSnapshot(r)
105}
106
107func (m Manifest) WriteSnapshot(w io.Writer) error {
108 var write manifestSnapshotFile
109
110 for _, record := range m {
111 // Make sure VersionStr is in sync with Version, since we encourage
112 // callers to manipulate Version and ignore VersionStr.
113 if record.Version != nil {
114 record.VersionStr = record.Version.String()
115 } else {
116 record.VersionStr = ""
117 }
118 write.Records = append(write.Records, record)
119 }
120
121 src, err := json.Marshal(write)
122 if err != nil {
123 return err
124 }
125
126 _, err = w.Write(src)
127 return err
128}
129
130func (m Manifest) WriteSnapshotToDir(dir string) error {
131 fn := filepath.Join(dir, ManifestSnapshotFilename)
132 log.Printf("[TRACE] modsdir: writing modules manifest to %s", fn)
133 w, err := os.Create(fn)
134 if err != nil {
135 return err
136 }
137 return m.WriteSnapshot(w)
138}