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
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use anyhow::Result;
use askama::Template;
use pathdiff::diff_paths;
use crate::configuration_file::ConfigurationFile;
use crate::monorepo_manifest::MonorepoManifest;
use crate::package_manifest::PackageManifest;
#[derive(Template)]
#[template(path = "makefile")]
struct MakefileTemplate<'a> {
root: &'a str,
output_file: &'a str,
package_directory: &'a str,
scoped_package_name: &'a str,
unscoped_package_name: &'a str,
internal_dependency_package_json_filenames_inclusive: &'a Vec<String>,
create_pack_target: &'a bool,
npm_pack_archive_dependencies: &'a HashMap<String, String>,
internal_npm_dependencies_exclusive: &'a Vec<&'a str>,
}
pub fn make_dependency_makefile(opts: crate::opts::MakeDepend) -> Result<()> {
let lerna_manifest = MonorepoManifest::from_directory(&opts.root)?;
let package_manifest = PackageManifest::from_directory(&opts.root, &opts.package_directory)?;
let package_manifest_by_package_name = lerna_manifest.package_manifests_by_package_name()?;
let internal_dependencies_exclusive = package_manifest
.transitive_internal_dependency_package_names_exclusive(&package_manifest_by_package_name);
let internal_dependency_package_json_filenames_inclusive: Vec<PathBuf> = {
let mut dependency_dirs = internal_dependencies_exclusive
.iter()
.map(|internal_dependency| (*internal_dependency).path())
.collect::<Vec<_>>();
dependency_dirs.push(package_manifest.path());
dependency_dirs
};
let npm_pack_archive_dependencies = &internal_dependencies_exclusive
.iter()
.map(|dependency| {
let target_directory = package_manifest
.directory()
.join(".internal-npm-dependencies");
let target = target_directory
.join(dependency.npm_pack_file_basename())
.to_str()
.expect("npm pack filename is not UTF-8 encodable")
.to_owned();
let source_package_directory = dependency.directory();
let source = diff_paths(source_package_directory, target_directory)
.expect("No relative path to source package")
.to_str()
.expect("Source package path is not UTF-8 encodable")
.to_owned();
(target, source)
})
.collect();
let makefile_contents = MakefileTemplate {
root: opts
.root
.to_str()
.expect("Monorepo root is not UTF_8 encodable"),
output_file: opts
.output_file
.to_str()
.expect("Output file is not UTF-8 encodable"),
package_directory: package_manifest
.directory()
.to_str()
.expect("Package directory is not UTF-8 encodable"),
scoped_package_name: &package_manifest.contents.name,
unscoped_package_name: package_manifest.unscoped_package_name(),
internal_dependency_package_json_filenames_inclusive:
&internal_dependency_package_json_filenames_inclusive
.iter()
.map(|internal_dependency| {
internal_dependency
.to_str()
.expect("Internal package directory is not UTF-8 encodable")
.to_owned()
})
.collect(),
create_pack_target: &opts.create_pack_target,
npm_pack_archive_dependencies,
internal_npm_dependencies_exclusive: &npm_pack_archive_dependencies
.keys()
.map(|string| string.as_str())
.collect::<Vec<_>>(),
}
.render()
.expect("Unable to render makefile template");
fs::write(
opts.package_directory.join(opts.output_file),
makefile_contents,
)
.expect("Unable to write makefile");
Ok(())
}