mirror of
https://github.com/storytold/craft-anything.git
synced 2026-11-05 20:47:45 +01:00
Keep Make off the folder picked on Work on my project, and don't read an address in its request as an original (#750)
Leaving "Work on my project" forgets a folder it would edit in place, and a folder dialog that ends after leaving that door is dropped, so a version made on Make can't edit the person's own project. An address in that door's request stays part of the request instead of becoming an original to recreate. Follow-up to #686's review.
This commit is contained in:
@@ -87,6 +87,11 @@ pub fn picked(app: &mut CraftApp, folder: PathBuf) {
|
||||
/// "Work on my project" picked a folder: its files are the app, edited in place (nothing asked).
|
||||
/// An existing project opens; an empty folder has nothing to work on.
|
||||
pub fn picked_own(app: &mut CraftApp, folder: PathBuf) {
|
||||
// The dialog runs beside the window: a pick that ends after leaving the door is dropped, or
|
||||
// a version made on Make would edit that folder.
|
||||
if !app.state.make.mine {
|
||||
return;
|
||||
}
|
||||
match workspace::folder_state(&folder) {
|
||||
Ok(FolderState::Project) => open_project(app, &folder),
|
||||
Ok(FolderState::Empty) => app.toast(tr("That folder is empty. Pick the folder your project's files are in."), true),
|
||||
|
||||
@@ -44,7 +44,11 @@ pub fn normalize_url(s: &str) -> String {
|
||||
}
|
||||
|
||||
/// The target the draft will use: the picked one, the typed address, or an address in the request.
|
||||
/// "Work on my project" has none: an address in its request is a link to add, not an original.
|
||||
pub fn resolve_target(d: &MakeDraft) -> TargetRef {
|
||||
if d.mine {
|
||||
return TargetRef::None;
|
||||
}
|
||||
if d.target != TargetRef::None {
|
||||
return d.target.clone();
|
||||
}
|
||||
@@ -69,12 +73,17 @@ pub fn hero(app: &mut CraftApp, ui: &mut Ui, w: f32) {
|
||||
let d = &mut app.state.make;
|
||||
let door = if d.look { 2 } else { usize::from(d.mine) };
|
||||
if let Some(i) = widgets::segmented_sized(ui, &["Make my own version", "Work on my project", "Just look inside"], door, 38.0, 12.5) {
|
||||
let left = d.mine && i != 1;
|
||||
(d.mine, d.look) = (i == 1, i == 2);
|
||||
if d.mine {
|
||||
// The person's own project: there's nothing to recreate.
|
||||
(d.target, d.editing_url, d.found, d.builder, d.game) = (TargetRef::None, false, None, None, false);
|
||||
d.url.clear();
|
||||
}
|
||||
if left && d.existing == Some(ExistingFiles::Edit) {
|
||||
// A version made on Make never edits the project picked here.
|
||||
(d.folder, d.folder_files, d.existing) = (None, None, None);
|
||||
}
|
||||
}
|
||||
ui.add_space(18.0);
|
||||
if app.state.make.look {
|
||||
@@ -523,5 +532,7 @@ mod tests {
|
||||
d.request = "a snake game".into();
|
||||
assert_eq!(resolve_target(&d), TargetRef::None);
|
||||
assert_eq!(normalize_url("http://x.y"), "http://x.y");
|
||||
let own = MakeDraft { mine: true, request: "Link the footer to https://example.com".into(), ..Default::default() };
|
||||
assert_eq!(resolve_target(&own), TargetRef::None, "an address in the request isn't an original");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2056,15 +2056,31 @@ fn the_front_door_works_on_a_project_the_person_already_has() {
|
||||
assert_eq!(h.state().state.make.existing, Some(ExistingFiles::Edit));
|
||||
assert_eq!(h.state().settings.existing_files, None, "the answer in Settings is left alone");
|
||||
h.get_by_label("Pick another folder…");
|
||||
|
||||
// Make never edits the folder picked here, and coming back asks for it again.
|
||||
h.get_by_label("Make my own version").click();
|
||||
h.run_steps(3);
|
||||
assert!(h.state().state.make.folder.is_none() && h.state().state.make.existing.is_none());
|
||||
craft_anything_ui_egui::folders::picked_own(h.state_mut(), mine.path().to_path_buf());
|
||||
assert!(h.state().state.make.folder.is_none(), "a dialog that ends after leaving the door is dropped");
|
||||
h.get_by_label("Work on my project").click();
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Choose your project's folder…");
|
||||
craft_anything_ui_egui::folders::picked_own(h.state_mut(), mine.path().to_path_buf());
|
||||
h.state_mut().state.make.request = "Link the footer to https://example.com".into();
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Start").click();
|
||||
assert!(wait(&mut h, |a| a.creating.is_none() && a.workspace.is_some()), "made on a worker");
|
||||
let ws = Workspace::open(mine.path()).expect("the project is the person's folder");
|
||||
assert!(ws.manifest.app_in_root && ws.app_dir() == mine.path());
|
||||
assert_eq!(ws.manifest.target, TargetRef::None, "an address in the request isn't an original");
|
||||
assert_eq!(ws.manifest.name, mine.path().file_name().unwrap().to_string_lossy(), "named after its folder");
|
||||
assert_eq!(std::fs::read_to_string(mine.path().join("index.html")).unwrap(), "<p>hi</p>");
|
||||
assert_eq!(runs.started(), [mine.path().to_path_buf()]);
|
||||
assert_eq!(std::fs::read_dir(d.path()).map(|r| r.count()).unwrap_or(0), 0, "nothing in the projects folder");
|
||||
|
||||
// Back on the door, the same folder is a project now, so it opens.
|
||||
h.state_mut().state.make.mine = true;
|
||||
craft_anything_ui_egui::folders::picked_own(h.state_mut(), mine.path().to_path_buf());
|
||||
h.run_steps(2);
|
||||
assert!(h.state().state.toasts.iter().any(|(text, err)| !*err && text.contains("already a project")));
|
||||
|
||||
@@ -635,6 +635,9 @@ Gaps found while using the app for real projects.
|
||||
refused and a folder that's already a project opens. Until now that was only reachable
|
||||
through "Choose a folder…" under Make's Start, on a screen that asks what to recreate
|
||||
— claimed: xerenon, branch feature/r2.9-work-on-my-project; PR #686
|
||||
- [x] Leaving "Work on my project" forgets a folder it would edit in place and drops a folder
|
||||
dialog that ends later, so a version made on Make can't edit that project, and an address
|
||||
in its request isn't read as an original to recreate (review of #686) — claimed: xerenon, branch bugfix/r2.9-own-project-review; PR #750
|
||||
- [x] Choose Claude Code's folder (`CLAUDE_CONFIG_DIR`) per AI, so one computer can build with
|
||||
two Claude accounts; an app opened from the Dock never sees the shell's variable. Settings →
|
||||
AI (a typed folder, and Add another) and `ai folder`; live-checked from the CLI with an empty
|
||||
|
||||
@@ -58,6 +58,11 @@ whenever a `Cargo.toml` changed.
|
||||
on a new branch, open a new PR that says it supersedes the old one, and comment on the old one.
|
||||
Don't close or rewrite other people's work without asking.
|
||||
|
||||
**Review fixes pushed to a PR that had already merged.** #686 was merged hours before its review
|
||||
comments were acted on; the fixes went to its branch and the threads were answered "Fixed", while
|
||||
`main` had the code without them. Read `gh pr view --json state,headRefOid` before pushing to a PR's
|
||||
branch, and land anything late in a new PR from `main`.
|
||||
|
||||
## Tests
|
||||
|
||||
**A test started a real download on a contributor's machine.** A test called `engines_install` for
|
||||
|
||||
Reference in New Issue
Block a user