Fork of daniellemaywood.uk/gleam — Wasm codegen work
6.4 kB
212 lines
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2021 The Gleam contributors
3
4use crate::{
5 build::{Mode, Target},
6 manifest::Base16Checksum,
7};
8
9use camino::{Utf8Path, Utf8PathBuf};
10
11pub const ARTEFACT_DIRECTORY_NAME: &str = "_gleam_artefacts";
12
13#[derive(Debug, Clone)]
14pub struct ProjectPaths {
15 root: Utf8PathBuf,
16}
17
18impl ProjectPaths {
19 pub fn new(root: Utf8PathBuf) -> Self {
20 Self { root }
21 }
22
23 pub fn at_filesystem_root() -> Self {
24 let path = if cfg!(target_family = "windows") {
25 r"C:\"
26 } else {
27 "/"
28 };
29
30 Self::new(Utf8PathBuf::from(path))
31 }
32
33 pub fn root(&self) -> &Utf8Path {
34 &self.root
35 }
36
37 pub fn root_config(&self) -> Utf8PathBuf {
38 self.root.join("gleam.toml")
39 }
40
41 pub fn readme(&self) -> Utf8PathBuf {
42 self.root.join("README.md")
43 }
44
45 pub fn manifest(&self) -> Utf8PathBuf {
46 self.root.join("manifest.toml")
47 }
48
49 pub fn src_directory(&self) -> Utf8PathBuf {
50 self.root.join("src")
51 }
52
53 pub fn test_directory(&self) -> Utf8PathBuf {
54 self.root.join("test")
55 }
56
57 pub fn dev_directory(&self) -> Utf8PathBuf {
58 self.root.join("dev")
59 }
60
61 pub fn build_directory(&self) -> Utf8PathBuf {
62 self.root.join("build")
63 }
64
65 pub fn build_packages_directory(&self) -> Utf8PathBuf {
66 self.build_directory().join("packages")
67 }
68
69 pub fn build_git_directory(&self) -> Utf8PathBuf {
70 self.build_directory().join("git")
71 }
72
73 pub fn build_git_repo(&self, name: &str) -> Utf8PathBuf {
74 self.build_git_directory().join(name)
75 }
76
77 pub fn build_packages_toml(&self) -> Utf8PathBuf {
78 self.build_packages_directory().join("packages.toml")
79 }
80
81 pub fn build_packages_package(&self, package_name: &str) -> Utf8PathBuf {
82 self.build_packages_directory().join(package_name)
83 }
84
85 // build_deps_package_config
86 pub fn build_packages_package_config(&self, package_name: &str) -> Utf8PathBuf {
87 self.build_packages_package(package_name).join("gleam.toml")
88 }
89
90 pub fn build_export_hex_tarball(&self, package_name: &str, version: &str) -> Utf8PathBuf {
91 self.build_directory()
92 .join(format!("{package_name}-{version}.tar"))
93 }
94
95 pub fn build_directory_for_mode(&self, mode: Mode) -> Utf8PathBuf {
96 self.build_directory().join(mode.to_string())
97 }
98
99 pub fn erlang_shipment_directory(&self) -> Utf8PathBuf {
100 self.build_directory().join("erlang-shipment")
101 }
102
103 pub fn build_documentation_directory(&self, package: &str) -> Utf8PathBuf {
104 self.build_directory_for_mode(Mode::Dev)
105 .join("docs")
106 .join(package)
107 }
108
109 pub fn build_directory_for_target(&self, mode: Mode, target: Target) -> Utf8PathBuf {
110 let target = match target {
111 Target::Erlang => "erlang",
112 Target::JavaScript => "javascript",
113 Target::Wasm => "wasm",
114 };
115 self.build_directory_for_mode(mode).join(target)
116 }
117
118 /// Note this uses the "application name", not the name of this package.
119 /// This is because in BEAM applications one can specify an application
120 /// name that is not the same as the Hex package name. Ideally we would
121 /// always use the package name, but the BEAM runtime knows nothing
122 /// about packages, only applications, so it will look on the filesystem
123 /// for the application name when loading it.
124 pub fn build_directory_for_package(
125 &self,
126 mode: Mode,
127 target: Target,
128 application_name: &str,
129 ) -> Utf8PathBuf {
130 self.build_directory_for_target(mode, target)
131 .join(application_name)
132 }
133
134 pub fn build_packages_ebins_glob(&self, mode: Mode, target: Target) -> Utf8PathBuf {
135 self.build_directory_for_package(mode, target, "*")
136 .join("ebin")
137 }
138
139 /// A path to a special file that contains the version of gleam
140 /// that last built the artefacts along with build-impacting
141 /// configuration, such as whether to generate source maps. If
142 /// this file does not match the current version of gleam we
143 /// will rebuild from scratch
144 pub fn build_configuration_fingerprint(&self, mode: Mode, target: Target) -> Utf8PathBuf {
145 self.build_directory_for_target(mode, target)
146 .join("fingerprint")
147 }
148
149 /// The path to the source gleam.toml file for a path dependency.
150 pub fn path_dependency_gleam_toml_path(&self, dependency_path: &Utf8Path) -> Utf8PathBuf {
151 self.root().join(dependency_path).join("gleam.toml")
152 }
153
154 pub fn dependency_gleam_toml_fingerprint_path(&self, dependency_name: &str) -> Utf8PathBuf {
155 self.build_packages_directory()
156 .join(format!("{}.config_fingerprint", dependency_name))
157 }
158}
159
160pub fn global_package_cache_package_tarball(checksum: &Base16Checksum) -> Utf8PathBuf {
161 global_packages_cache().join(format!("{}.tar", checksum.base_16_encoded_string()))
162}
163
164pub fn global_hexpm_oauth_credentials_path() -> Utf8PathBuf {
165 global_hexpm_cache().join("credentials.toml")
166}
167
168pub fn global_hexpm_legacy_credentials_path() -> Utf8PathBuf {
169 global_hexpm_cache().join("credentials")
170}
171
172fn global_hexpm_cache() -> Utf8PathBuf {
173 default_global_gleam_cache().join("hex").join("hexpm")
174}
175
176fn global_packages_cache() -> Utf8PathBuf {
177 global_hexpm_cache().join("packages")
178}
179
180pub fn default_global_gleam_cache() -> Utf8PathBuf {
181 Utf8PathBuf::from_path_buf(
182 dirs_next::cache_dir()
183 .expect("Failed to determine user cache directory")
184 .join("gleam"),
185 )
186 .expect("Non Utf8 Path")
187}
188
189pub fn unnest(within: &Utf8Path) -> Utf8PathBuf {
190 let mut path = Utf8PathBuf::new();
191 for _ in within {
192 path = path.join("..");
193 }
194 path
195}
196
197#[test]
198fn paths() {
199 assert!(default_global_gleam_cache().ends_with("gleam"));
200
201 assert!(global_packages_cache().ends_with("hex/hexpm/packages"));
202
203 assert!(
204 global_package_cache_package_tarball(&Base16Checksum(vec![0, 0, 0, 0]))
205 .ends_with("hex/hexpm/packages/00000000.tar")
206 );
207
208 assert!(
209 global_package_cache_package_tarball(&Base16Checksum(vec![0x3A, 0x21, 0xF4]))
210 .ends_with("hex/hexpm/packages/3A21F4.tar")
211 );
212}