polyhorn_cli/android/tasks/
generate_source_tree.rs1use super::{AndroidContext, AndroidError};
2use crate::core::{Manager, Task};
3use crate::template::SourceTree;
4
5pub struct GenerateSourceTree;
8
9impl Task for GenerateSourceTree {
10 type Context = AndroidContext;
11 type Error = AndroidError;
12
13 fn verb(&self) -> &str {
14 "Generating"
15 }
16
17 fn message(&self) -> &str {
18 "source tree"
19 }
20
21 fn detail(&self) -> &str {
22 "for Android"
23 }
24
25 fn run(
26 &self,
27 context: AndroidContext,
28 manager: &mut Manager,
29 ) -> Result<AndroidContext, AndroidError> {
30 let package_dir = context.config.spec.app.android.package.replace(".", "/");
31
32 let mut tree = SourceTree::new();
33
34 macro_rules! template {
35 ($tree:ident, $path:literal) => {
36 tree.template(
37 $path,
38 include_str!(concat!(
39 env!("CARGO_MANIFEST_DIR"),
40 "/android/template/",
41 $path,
42 )),
43 );
44 };
45 }
46
47 macro_rules! copy {
48 ($tree:ident, $path:literal) => {
49 tree.copy(
50 $path,
51 include_bytes!(concat!(
52 env!("CARGO_MANIFEST_DIR"),
53 "/android/template/",
54 $path,
55 )),
56 );
57 };
58 }
59
60 tree.template(
61 &format!("app/src/main/java/{}/MainActivity.java", package_dir),
62 include_str!(concat!(
63 env!("CARGO_MANIFEST_DIR"),
64 "/android/template/",
65 "app/src/main/java/com/example/myapplication/MainActivity.java"
66 )),
67 );
68
69 copy!(tree, "build.gradle");
70 copy!(tree, "gradle.properties");
71 copy!(tree, "gradlew");
72 copy!(tree, "gradlew.bat");
73 template!(tree, "settings.gradle");
74 template!(tree, "app/build.gradle");
75 template!(tree, "app/src/main/AndroidManifest.xml");
76 copy!(tree, "app/src/main/res/drawable/ic_launcher_background.xml");
77 copy!(
78 tree,
79 "app/src/main/res/drawable-v24/ic_launcher_foreground.xml"
80 );
81 copy!(tree, "app/src/main/res/layout/activity_main.xml");
82 copy!(tree, "app/src/main/res/layout/content_main.xml");
83 template!(tree, "app/src/main/res/menu/menu_main.xml");
84 copy!(
85 tree,
86 "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml"
87 );
88 copy!(tree, "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml");
89 copy!(tree, "app/src/main/res/mipmap-hdpi/ic_launcher_round.png");
90 copy!(tree, "app/src/main/res/mipmap-hdpi/ic_launcher.png");
91 copy!(tree, "app/src/main/res/mipmap-mdpi/ic_launcher_round.png");
92 copy!(tree, "app/src/main/res/mipmap-mdpi/ic_launcher.png");
93 copy!(tree, "app/src/main/res/mipmap-xhdpi/ic_launcher_round.png");
94 copy!(tree, "app/src/main/res/mipmap-xhdpi/ic_launcher.png");
95 copy!(tree, "app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png");
96 copy!(tree, "app/src/main/res/mipmap-xxhdpi/ic_launcher.png");
97 copy!(
98 tree,
99 "app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png"
100 );
101 copy!(tree, "app/src/main/res/mipmap-xxxhdpi/ic_launcher.png");
102 copy!(tree, "app/src/main/res/values/colors.xml");
103 copy!(tree, "app/src/main/res/values/dimens.xml");
104 copy!(tree, "app/src/main/res/values/strings.xml");
105 copy!(tree, "app/src/main/res/values/themes.xml");
106 copy!(tree, "app/src/main/res/values-night/themes.xml");
107 copy!(tree, "app/proguard-rules.pro");
108 copy!(tree, "gradle/wrapper/gradle-wrapper.jar");
109 copy!(tree, "gradle/wrapper/gradle-wrapper.properties");
110
111 let bar = manager.progress_bar(tree.len());
112
113 let mut destination_path = context.config.target_dir.clone();
114 destination_path.push("polyhorn-android");
115
116 for result in tree.generate(&context.config.spec, &destination_path) {
117 bar.inc(1);
118
119 match result {
120 Ok(_) => {}
121 Err(error) => {
122 eprintln!("Encountered an error: {:#?}", error);
123 std::process::abort();
124 }
125 }
126 }
127
128 #[cfg(unix)]
129 {
130 use std::fs::File;
131 use std::os::unix::fs::PermissionsExt;
132
133 let mut gradlew_path = destination_path.clone();
134 gradlew_path.push("gradlew");
135 let gradlew = File::open(gradlew_path).unwrap();
136 let mut permissions = gradlew.metadata().unwrap().permissions();
137 permissions.set_mode(0o744);
138 gradlew.set_permissions(permissions).unwrap();
139 }
140
141 bar.finish_and_clear();
142
143 Ok(context)
144 }
145}