Skip to content

Commit 1fadb36

Browse files
committed
Merge branch 'dev'
2 parents 42e76c2 + 29a00d6 commit 1fadb36

28 files changed

+606
-3688
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
- Project creation
88
- Select a template to start from, or start from scratch
99
- Select the specific packages you want
10+
- Supports internal packages
11+
- Supports git packages
12+
- Supports local file packages
1013
- Select the files/folders you want from the template
1114
- Can override the template's internal project entirely
1215
- Template creation

src-tauri/src/generate.rs

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{collections::HashMap, path::PathBuf};
22

33
use flate2::{read::GzDecoder, write::GzEncoder};
44

5-
use crate::{app::{self, AppState}, editor::UnityEditorInstall, errors, io_utils, package::MinimalPackage, template::SurfaceTemplate};
5+
use crate::{app::{self, AppState}, editor::UnityEditorInstall, errors, io_utils, package::{self, MinimalPackage}, template::SurfaceTemplate};
66

77
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
88
#[serde(rename_all = "camelCase")]
@@ -39,7 +39,7 @@ pub fn generate_project(app: &tauri::AppHandle, project_info: &ProjectInfoForGen
3939

4040
let package_cache_dir = io_utils::get_cache_appended_dir(app, "new_project_package");
4141
unpack_package_into_cache(&package_cache_dir, &template_info)?;
42-
modify_package_json(&package_cache_dir, &template_info.packages)?;
42+
modify_package_json(&package_cache_dir, &template_info.packages, &package_cache_dir_out)?;
4343

4444
// create project directory
4545
std::fs::create_dir(&package_cache_dir_out)?;
@@ -88,8 +88,10 @@ pub fn generate_project(app: &tauri::AppHandle, project_info: &ProjectInfoForGen
8888
// generate a new template file
8989
pub fn generate_template(app: &tauri::AppHandle, app_state: &tauri::State<AppState>, template_info: &NewTemplateInfo) -> Result<PathBuf, errors::AnyError> {
9090
let package_cache_dir = io_utils::get_cache_appended_dir(app, "new_template_package");
91+
let package_cache_dir_out = io_utils::get_cache_appended_dir(app, "new_template_package_output");
92+
9193
unpack_package_into_cache(&package_cache_dir, &template_info.template)?;
92-
modify_package_json(&package_cache_dir, &template_info.template.packages)?;
94+
modify_package_json(&package_cache_dir, &template_info.template.packages, &package_cache_dir_out)?;
9395

9496
// modify package.json
9597
let package_json_path = package_cache_dir
@@ -115,8 +117,6 @@ pub fn generate_template(app: &tauri::AppHandle, app_state: &tauri::State<AppSta
115117
});
116118
println!("Writing new package.json: {}", package_json_path.display());
117119
std::fs::write(&package_json_path, serde_json::to_string_pretty(&new_package_json)?)?;
118-
119-
let package_cache_dir_out = io_utils::get_cache_appended_dir(app, "new_template_package_output");
120120

121121
// copy contents from package to output
122122
let data_root = PathBuf::from("package");
@@ -217,7 +217,7 @@ fn unpack_package_into_cache(output: &PathBuf, template_info: &TemplateInfoForGe
217217
Ok(())
218218
}
219219

220-
fn modify_package_json(package_cache_dir: &PathBuf, packages: &Vec<MinimalPackage>) -> Result<(), errors::AnyError> {
220+
fn modify_package_json(package_cache_dir: &PathBuf, packages: &Vec<MinimalPackage>, output_path: &PathBuf) -> Result<(), errors::AnyError> {
221221
// modify package.json for dependencies
222222
let packages_dir = package_cache_dir
223223
.join("package")
@@ -235,18 +235,68 @@ fn modify_package_json(package_cache_dir: &PathBuf, packages: &Vec<MinimalPackag
235235
std::fs::remove_file(&packages_lock_json)?;
236236
}
237237

238+
// read any local packages
239+
let local_packages = packages
240+
.iter()
241+
.filter(|x| x._type == package::PackageType::Local)
242+
.collect::<Vec<_>>();
243+
244+
let rest_packages = packages
245+
.iter()
246+
.filter(|x| x._type != package::PackageType::Local)
247+
.collect::<Vec<_>>();
248+
249+
println!("Local packages: {:?}", local_packages);
250+
println!("Rest packages: {:?}", rest_packages);
251+
238252
let manifest_json_contents = std::fs::read_to_string(&manifest_json)?;
239253
let mut manifest_json_contents: HashMap<String, serde_json::Value>
240254
= serde_json::from_str(&manifest_json_contents)?;
241255

242256
let mut dependencies: serde_json::Map<String, serde_json::Value> = serde_json::Map::new();
243257

244258
// override the dependencies
245-
for package in packages.iter() {
259+
for package in rest_packages.iter() {
260+
println!("Rest package: {:?}", package);
246261
let name = package.name.clone();
247262
let version = package.version.clone();
248263
dependencies.insert(name, serde_json::Value::String(version));
249264
}
265+
266+
// local ones now
267+
for package in local_packages.iter() {
268+
println!("Local package: {:?}", package);
269+
// get local path from this project to the json path in name
270+
let package_json_path = std::path::Path::new(&package.name).to_path_buf();
271+
let package_json_path_parent = package_json_path
272+
.parent()
273+
.ok_or(errors::str_error("Failed to get parent"))?;
274+
let relative_path = io_utils::diff_paths(&package_json_path_parent, &output_path.join("Packages"));
275+
276+
let relative_path = match relative_path {
277+
Some(path) => path.to_path_buf(),
278+
None => package_json_path.clone()
279+
};
280+
281+
let json = std::fs::read_to_string(&package_json_path)?;
282+
let json: serde_json::Value = serde_json::from_str(&json)?;
283+
let name = json.as_object()
284+
.ok_or(errors::str_error(&format!("Failed to get json object from {}", package_json_path.display())))?
285+
.get("name")
286+
.ok_or(errors::str_error(&format!("Failed to get name from {}", package_json_path.display())))?
287+
.as_str()
288+
.ok_or(errors::str_error(&format!("Failed to get name from {}", package_json_path.display())))?
289+
.to_string();
290+
291+
let name = name.clone();
292+
let version = format!("file:{}", relative_path
293+
.to_str()
294+
.ok_or(errors::str_error("Failed to get str"))?
295+
.replace("\\", "/")
296+
);
297+
dependencies.insert(name, serde_json::Value::String(version));
298+
}
299+
250300
manifest_json_contents.insert("dependencies".to_string(), serde_json::Value::Object(dependencies));
251301

252302
// save to disk

src-tauri/src/git.rs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
use crate::errors;
4+
5+
#[derive(Serialize, Deserialize, Debug, Clone)]
6+
#[serde(default, rename_all = "camelCase")]
7+
pub struct PackageJson {
8+
name: String,
9+
version: String,
10+
}
11+
12+
impl Default for PackageJson {
13+
fn default() -> Self {
14+
Self {
15+
name: "nomnom-unity-hub".to_string(),
16+
version: "0.0.0".to_string(),
17+
}
18+
}
19+
}
20+
21+
#[tauri::command]
22+
pub async fn cmd_get_git_package_json(app: tauri::AppHandle, url: String) -> Result<PackageJson, errors::AnyError> {
23+
// extract ?path= if it has it
24+
let mut url = url;
25+
let mut path = None;
26+
let mut branch = None;
27+
28+
if url.contains("#") {
29+
let split = url.split("#").collect::<Vec<_>>();
30+
if split.len() > 1 {
31+
branch = Some(split[1].to_string());
32+
url = split[0].to_string();
33+
}
34+
}
35+
36+
if url.contains("?path=") {
37+
let split = url
38+
.split("?path=")
39+
.collect::<Vec<_>>();
40+
41+
let test_path = split.get(1)
42+
.ok_or(errors::str_error("Invalid git url"))?;
43+
let test_url = split.get(0)
44+
.ok_or(errors::str_error("Invalid git url"))?;
45+
46+
path = Some(test_path.to_string());
47+
url = test_url.to_string();
48+
}
49+
50+
let cache_dir = app
51+
.path_resolver()
52+
.app_cache_dir()
53+
.ok_or(errors::str_error("Failed to get app cache dir"))?;
54+
let cache_path = cache_dir.join("temp-git");
55+
56+
if cache_path.exists() {
57+
std::fs::remove_dir_all(&cache_path)?;
58+
}
59+
60+
let cache_path_str = cache_path.to_str()
61+
.ok_or(errors::str_error("Failed to get app cache dir"))?;
62+
63+
std::fs::create_dir_all(&cache_path)?;
64+
65+
fn run_clone(args: Vec<&str>) -> bool {
66+
std::process::Command::new("git")
67+
.args(args.as_slice())
68+
.output()
69+
.inspect(|x| println!("{:?}", x))
70+
.is_ok_and(|x| x.status.success())
71+
}
72+
73+
let clone_success = {
74+
if let Some(branch) = branch {
75+
let args = vec!["clone", "-b", &branch, &url, cache_path_str];
76+
run_clone(args)
77+
} else {
78+
let args = vec!["clone", &url, cache_path_str];
79+
run_clone(args)
80+
}
81+
};
82+
83+
if !clone_success {
84+
std::fs::remove_dir_all(&cache_path)?;
85+
return Err(errors::str_error("Failed to clone repository"));
86+
}
87+
88+
let package_json = {
89+
let package_json_path = {
90+
if let Some(path) = &path {
91+
cache_path
92+
.clone()
93+
.join(path)
94+
} else {
95+
cache_path.clone()
96+
}
97+
};
98+
99+
let package_json_path = package_json_path
100+
.join("package")
101+
.with_extension("json");
102+
103+
println!("package_json_path: {}", package_json_path.display());
104+
105+
let contents = std::fs::read_to_string(&package_json_path)
106+
.map_err(|_| errors::str_error("Failed to read package.json"))?;
107+
let package_json: PackageJson = serde_json::from_str(&contents)
108+
.map_err(|_| errors::str_error("Invalid package.json"))?;
109+
110+
Ok(package_json)
111+
};
112+
113+
std::fs::remove_dir_all(&cache_path)?;
114+
package_json
115+
}

src-tauri/src/io_utils.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,65 @@ pub fn build_ids(node: &mut FileDir, id: &mut u64) {
158158
*id = *id + 1u64;
159159
build_ids(c, id);
160160
}
161+
}
162+
163+
/// Construct a relative path from a provided base directory path to the provided path
164+
///
165+
/// ```rust
166+
/// use pathdiff::diff_paths;
167+
/// use std::path::*;
168+
///
169+
/// let baz: PathBuf = "/foo/bar/baz".into();
170+
/// let bar: PathBuf = "/foo/bar".into();
171+
/// let quux: PathBuf = "/foo/bar/quux".into();
172+
/// assert_eq!(diff_paths(&bar, &baz), Some("../".into()));
173+
/// assert_eq!(diff_paths(&baz, &bar), Some("baz".into()));
174+
/// assert_eq!(diff_paths(&quux, &baz), Some("../quux".into()));
175+
/// assert_eq!(diff_paths(&baz, &quux), Some("../baz".into()));
176+
/// assert_eq!(diff_paths(&bar, &quux), Some("../".into()));
177+
///
178+
/// ```
179+
/// Under MIT LICENSE
180+
pub fn diff_paths(path: &Path, base: &Path) -> Option<std::path::PathBuf> {
181+
// This routine is adapted from the *old* Path's `path_relative_from`
182+
// function, which works differently from the new `relative_from` function.
183+
// In particular, this handles the case on unix where both paths are
184+
// absolute but with only the root as the common directory.
185+
use std::path::Component;
186+
187+
if path.is_absolute() != base.is_absolute() {
188+
if path.is_absolute() {
189+
Some(std::path::PathBuf::from(path))
190+
} else {
191+
None
192+
}
193+
} else {
194+
let mut ita = path.components();
195+
let mut itb = base.components();
196+
let mut comps: Vec<Component> = vec![];
197+
loop {
198+
match (ita.next(), itb.next()) {
199+
(None, None) => break,
200+
(Some(a), None) => {
201+
comps.push(a);
202+
comps.extend(ita.by_ref());
203+
break;
204+
}
205+
(None, _) => comps.push(Component::ParentDir),
206+
(Some(a), Some(b)) if comps.is_empty() && a == b => (),
207+
(Some(a), Some(b)) if b == Component::CurDir => comps.push(a),
208+
(Some(_), Some(b)) if b == Component::ParentDir => return None,
209+
(Some(a), Some(_)) => {
210+
comps.push(Component::ParentDir);
211+
for _ in itb {
212+
comps.push(Component::ParentDir);
213+
}
214+
comps.push(a);
215+
comps.extend(ita.by_ref());
216+
break;
217+
}
218+
}
219+
}
220+
Some(comps.iter().map(|c| c.as_os_str()).collect())
221+
}
161222
}

src-tauri/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod errors;
1212
mod package;
1313
mod prefs;
1414
mod project;
15+
mod git;
1516
mod io_utils;
1617
mod template;
1718
mod generate;
@@ -56,6 +57,8 @@ fn main() {
5657
// generate
5758
generate::cmd_generate_project,
5859
generate::cmd_generate_template,
60+
// git
61+
git::cmd_get_git_package_json
5962
])
6063
.setup(|app| {
6164
let app_handle = app.handle();

0 commit comments

Comments
 (0)