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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
use ;
use ;
use Regex;
// TODO Annotate these with custom types so that accidental misuse is impossible
// TODO Add unit tests
// From a given physical address, form the path pointing to the
// out.json file for that resource.
// For virtual addresses
// pub fn build_out_path(prefix: &Path, addr: &Path) -> PathBuf {
// // Start with prefix
// let mut output = prefix.to_path_buf();
// output.push(".outputs");
// // Join the parent portion of `addr`, if it exists
// if let Some(parent) = addr.parent() {
// // Guard against pathological cases like ".." or "." parents
// // by only pushing normal components
// for comp in parent.components() {
// if let Component::Normal(_) = comp {
// output.push(comp)
// }
// }
// }
// let mut new_filename = OsString::new();
// if let Some(fname) = addr.file_name() {
// new_filename.push(fname);
// } else {
// // If there's no file name at all, we'll just use ".out.json"
// // so `new_filename` right now is just "." — that's fine.
// // We'll end up producing something like "./office/east/ec2/us-east-1/.out.json"
// }
// new_filename.push(".out.json");
// output.push(new_filename);
// output
// }
// pub fn unbuild_out_path(prefix: &Path, addr: &Path) -> anyhow::Result<PathBuf> {
// let new_addr = addr
// .strip_prefix(prefix.join(".outputs"))
// .context(format!("unbuild_out_path({:?}, {:?})", prefix, addr))?;
// let Some(parent) = new_addr.parent() else {
// bail!("unbuild_out_path: bad filename {:?}", addr)
// };
// let Some(filename) = new_addr.file_name() else {
// bail!("unbuild_out_path: bad filename {:?}", addr)
// };
// let Some(filename) = filename.to_str() else {
// bail!("unbuild_out_path: bad filename {:?}", addr)
// };
// let Some(new_filename) = filename.strip_suffix(".out.json") else {
// bail!("unbuild_out_path: bad filename {:?}", addr)
// };
// tracing::error!(
// "unbuild_out_path: {:?} / {:?} -> {:?}",
// prefix,
// addr,
// parent.join(new_filename)
// );
// Ok(parent.join(new_filename))
// }
// pub fn load_resource_outputs(prefix: &Path, addr: &impl ResourceAddress) -> anyhow::Result<Option<OutputMapFile>> {
// let addr = addr.to_path_buf();
// let output_path = build_out_path(prefix, &addr);
// if output_path.exists() {
// let file = File::open(&output_path)?;
// let reader = BufReader::new(file);
// let output_map: OutputMapFile = RON.from_reader(reader)?;
// Ok(Some(output_map))
// } else {
// Ok(None)
// }
// }
// pub fn output_phy_to_virt<A: ResourceAddress>(prefix: &Prefix, addr: &A) -> anyhow::Result<Option<A>> {
// let Some(virt_addr) = OutputMapFile::resolve(prefix, &PhysicalAddress(addr.to_path_buf()))? else {
// return Ok(None);
// };
// return Ok(Some(A::from_path(&virt_addr.0)?));
// // let output_path = build_out_path(prefix, &addr.to_path_buf());
// // if output_path.exists() {
// // if output_path.is_symlink() {
// // let Some(parent) = output_path.parent() else {
// // bail!("output_path.parent() returned None!")
// // };
// // let virt_out_path = std::fs::canonicalize(parent.join(&std::fs::read_link(&output_path)?))?;
// // // HACK ALERT HACK ALERT
// // // If we change the assumption that all connectors and commands run from the root of the repository,
// // // or if a connector runs cd for some reason, this will break!
// // // TODO use chwd and repo_root() to ensure that this runs from the root of the repo
// // let virt_out_path = virt_out_path.strip_prefix(std::env::current_dir()?)?;
// // Ok(Some(A::from_path(&unbuild_out_path(prefix, virt_out_path)?)?))
// // } else {
// // Ok(Some(addr.clone()))
// // }
// // } else {
// // Ok(Some(addr.clone()))
// // }
// }
// pub fn get_output_or_bail(output_map: &OutputMapFile, key: &str) -> anyhow::Result<String> {
// let Some(output) = &output_map.get(key) else {
// bail!("Couldn't get output key: {}", key)
// };
// Ok(output.to_string())
// }
// pub fn load_resource_output_key(prefix: &Path, addr: &impl ResourceAddress, key: &str) -> anyhow::Result<Option<String>> {
// let Some(outputs) = load_resource_outputs(prefix, addr)? else {
// return Ok(None);
// };
// Ok(outputs.get(key).cloned())
// }
// Connectors may save time in list() by avoiding fetching
// certain resource types if the subpath argument would filter them out
// from the results anyway. This is a utility function to check this case.
// If the subpath select
// For example:
// subpath_filter("aws/s3/us-east-1", "./") -> true
// subpath_filter("aws/s3/us-east-1", "aws/s3/eu-west-2") -> false
// subpath_filter("aws/s3/us-east-1", "aws/s3/us-east-1/buckets") -> true
// subpath_filter("aws/ecs/*/", "aws/s3/us-east-1/buckets") -> true
// pub fn subpath_filter(check_path: &Path, subpath: &Path) -> bool {
// true
// }