diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/internal/modsdir/manifest.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/internal/modsdir/manifest.go | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/internal/modsdir/manifest.go b/vendor/github.com/hashicorp/terraform/internal/modsdir/manifest.go new file mode 100644 index 0000000..36f6c03 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/internal/modsdir/manifest.go | |||
@@ -0,0 +1,138 @@ | |||
1 | package modsdir | ||
2 | |||
3 | import ( | ||
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. | ||
19 | type 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. | ||
48 | type Manifest map[string]Record | ||
49 | |||
50 | func (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. | ||
57 | type manifestSnapshotFile struct { | ||
58 | Records []Record `json:"Modules"` | ||
59 | } | ||
60 | |||
61 | func 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 | |||
95 | func 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 | |||
107 | func (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 | |||
130 | func (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 | } | ||