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:
Aek
2026-11-03 17:05:51 -08:00
committed by GitHub
parent 59a030ac7e
commit 66bda5607d
5 changed files with 40 additions and 0 deletions
+5
View File
@@ -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),
+11
View File
@@ -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");
}
}
+16
View File
@@ -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")));
+3
View File
@@ -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
+5
View File
@@ -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