-
Notifications
You must be signed in to change notification settings - Fork 131
/
module_manifest.go
124 lines (99 loc) · 3.07 KB
/
module_manifest.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package rootmodule
import (
"encoding/json"
"fmt"
"io/ioutil"
"path/filepath"
"strings"
version "github.com/hashicorp/go-version"
)
func moduleManifestFilePath(dir string) string {
return filepath.Join(
dir,
".terraform",
"modules",
"modules.json")
}
// The following structs were copied from terraform's
// internal/modsdir/manifest.go
// ModuleRecord represents some metadata about an installed module, as part
// of a ModuleManifest.
type ModuleRecord struct {
// Key is a unique identifier for this particular module, based on its
// position within the static module tree.
Key string `json:"Key"`
// SourceAddr is the source address given for this module in configuration.
// This is used only to detect if the source was changed in configuration
// since the module was last installed, which means that the installer
// must re-install it.
SourceAddr string `json:"Source"`
// Version is the exact version of the module, which results from parsing
// VersionStr. nil for un-versioned modules.
Version *version.Version `json:"-"`
// VersionStr is the version specifier string. This is used only for
// serialization in snapshots and should not be accessed or updated
// by any other codepaths; use "Version" instead.
VersionStr string `json:"Version,omitempty"`
// Dir is the path to the local directory where the module is installed.
Dir string `json:"Dir"`
}
func (r *ModuleRecord) UnmarshalJSON(b []byte) error {
type rawRecord ModuleRecord
var record rawRecord
err := json.Unmarshal(b, &record)
if err != nil {
return err
}
if record.VersionStr != "" {
record.Version, err = version.NewVersion(record.VersionStr)
if err != nil {
return fmt.Errorf("invalid version %q for %s: %s", record.VersionStr, record.Key, err)
}
}
// Ensure Windows is using the proper modules path format after
// reading the modules manifest Dir records
record.Dir = filepath.FromSlash(record.Dir)
// Terraform should be persisting clean paths already
// but it doesn't hurt to clean them for sanity
record.Dir = filepath.Clean(record.Dir)
// TODO: Follow symlinks (requires proper test data)
*r = (ModuleRecord)(record)
return nil
}
func (r *ModuleRecord) IsRoot() bool {
return r.Key == ""
}
func (r *ModuleRecord) IsExternal() bool {
modCacheDir := filepath.Join(".terraform", "modules")
if strings.HasPrefix(r.Dir, modCacheDir) {
return true
}
return false
}
// moduleManifest is an internal struct used only to assist in our JSON
// serialization of manifest snapshots. It should not be used for any other
// purpose.
type moduleManifest struct {
rootDir string
Records []ModuleRecord `json:"Modules"`
}
func ParseModuleManifestFromFile(path string) (*moduleManifest, error) {
b, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
mm, err := parseModuleManifest(b)
if err != nil {
return nil, err
}
mm.rootDir = rootModuleDirFromFilePath(path)
return mm, nil
}
func parseModuleManifest(b []byte) (*moduleManifest, error) {
mm := moduleManifest{}
err := json.Unmarshal(b, &mm)
if err != nil {
return nil, err
}
return &mm, nil
}