Fork of daniellemaywood.uk/gleam — Wasm codegen work
4.6 kB
150 lines
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2021 The Gleam contributors
3
4use camino::Utf8PathBuf;
5
6use gleam_core::{
7 config::PackageConfig,
8 error::{Error, FileIoAction, FileKind},
9 manifest::{Manifest, ManifestPackage, ManifestPackageSource},
10 paths::ProjectPaths,
11};
12
13#[derive(Debug, Clone, Copy)]
14pub enum PackageKind {
15 Dependency,
16 Root,
17}
18
19/// Get the config for a dependency module. Return the config for the current
20/// project if a dependency doesn't have a config file.
21pub fn find_package_config_for_module(
22 mod_path: &str,
23 manifest: &Manifest,
24 project_paths: &ProjectPaths,
25) -> Result<(PackageConfig, PackageKind), Error> {
26 for package in &manifest.packages {
27 // Not a Gleam package
28 if !package.build_tools.contains(&"gleam".into()) {
29 continue;
30 }
31
32 let root = package_root(package, project_paths);
33 let mut module_path = root.join("src").join(mod_path);
34 _ = module_path.set_extension("gleam");
35
36 // This package doesn't have the module we're looking for
37 if !module_path.is_file() {
38 continue;
39 }
40
41 let configuration = read(root.join("gleam.toml"))?;
42 return Ok((configuration, PackageKind::Dependency));
43 }
44
45 Ok((root_config(project_paths)?, PackageKind::Root))
46}
47
48fn package_root(package: &ManifestPackage, project_paths: &ProjectPaths) -> Utf8PathBuf {
49 match &package.source {
50 ManifestPackageSource::Local { path } => project_paths.root().join(path),
51
52 ManifestPackageSource::Hex { .. } | ManifestPackageSource::Git { .. } => {
53 project_paths.build_packages_package(&package.name)
54 }
55 }
56}
57
58pub fn root_config(paths: &ProjectPaths) -> Result<PackageConfig, Error> {
59 read(paths.root_config())
60}
61
62pub fn read(config_path: Utf8PathBuf) -> Result<PackageConfig, Error> {
63 let toml = crate::fs::read(&config_path)?;
64 let config: PackageConfig = toml::from_str(&toml).map_err(|e| Error::FileIo {
65 action: FileIoAction::Parse,
66 kind: FileKind::File,
67 path: config_path,
68 err: Some(e.to_string()),
69 })?;
70 config.check_gleam_compatibility()?;
71 Ok(config)
72}
73
74pub fn ensure_config_exists(paths: &ProjectPaths) -> Result<(), Error> {
75 let path = paths.root_config();
76 if !path.is_file() {
77 return Err(Error::FileIo {
78 action: FileIoAction::Read,
79 kind: FileKind::File,
80 path,
81 err: Some("File not found".into()),
82 });
83 }
84 Ok(())
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90 use gleam_core::manifest::Base16Checksum;
91
92 #[test]
93 fn package_root_hex() {
94 let paths = ProjectPaths::new(Utf8PathBuf::from("/app"));
95 let package = ManifestPackage {
96 name: "the_package".into(),
97 version: hexpm::version::Version::new(1, 0, 0),
98 build_tools: vec!["gleam".into()],
99 otp_app: None,
100 requirements: vec![],
101 source: ManifestPackageSource::Hex {
102 outer_checksum: Base16Checksum(vec![]),
103 },
104 };
105 assert_eq!(
106 package_root(&package, &paths),
107 Utf8PathBuf::from("/app/build/packages/the_package")
108 );
109 }
110
111 #[test]
112 fn package_root_git() {
113 let paths = ProjectPaths::new(Utf8PathBuf::from("/app"));
114 let package = ManifestPackage {
115 name: "the_package".into(),
116 version: hexpm::version::Version::new(1, 0, 0),
117 build_tools: vec!["gleam".into()],
118 otp_app: None,
119 requirements: vec![],
120 source: ManifestPackageSource::Git {
121 repo: "repo".into(),
122 commit: "commit".into(),
123 path: None,
124 },
125 };
126 assert_eq!(
127 package_root(&package, &paths),
128 Utf8PathBuf::from("/app/build/packages/the_package")
129 );
130 }
131
132 #[test]
133 fn package_root_local() {
134 let paths = ProjectPaths::new(Utf8PathBuf::from("/app"));
135 let package = ManifestPackage {
136 name: "the_package".into(),
137 version: hexpm::version::Version::new(1, 0, 0),
138 build_tools: vec!["gleam".into()],
139 otp_app: None,
140 requirements: vec![],
141 source: ManifestPackageSource::Local {
142 path: Utf8PathBuf::from("../wibble"),
143 },
144 };
145 assert_eq!(
146 package_root(&package, &paths),
147 Utf8PathBuf::from("/app/../wibble")
148 );
149 }
150}