feat: enhance .gitignore and add per-distro installation design and implementation plans
This commit is contained in:
parent
caf870d05e
commit
df342730ab
3 changed files with 618 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
/target
|
||||
.worktrees
|
||||
|
|
|
|||
|
|
@ -0,0 +1,276 @@
|
|||
# Per-Distro Installation Design
|
||||
|
||||
## Goal
|
||||
|
||||
Implement actual AppImage installation for `aim` across a broad Linux distro set, while preserving a single reusable install engine in `aim-core`, keeping `aim-cli` thin, and respecting distro policy constraints instead of fighting them.
|
||||
|
||||
## Agreed Product Shape
|
||||
|
||||
### Supported distro families
|
||||
|
||||
- Debian
|
||||
- Fedora
|
||||
- Arch
|
||||
- openSUSE
|
||||
- Alpine
|
||||
- Nix
|
||||
- Immutable
|
||||
- Generic Linux fallback
|
||||
|
||||
### Detection model
|
||||
|
||||
- Detect distro family from `/etc/os-release`
|
||||
- Detect policy constraints such as immutable or Nix-style environments
|
||||
- Probe runtime capabilities such as directory writability and optional helper availability
|
||||
- Let distro family define intended policy, then let capabilities refine the safe final action
|
||||
|
||||
### Support posture
|
||||
|
||||
- Broad Linux coverage is the target
|
||||
- Deep integration is preferred for mainstream distro families
|
||||
- Immutable systems should get best-effort user installs with explicit warnings
|
||||
- System installs should prefer native shared integration locations when policy allows, with fallback to `aim`-managed locations where appropriate
|
||||
|
||||
## Recommended Approach
|
||||
|
||||
Use a hybrid family-plus-capability model.
|
||||
|
||||
This was chosen over a family-only matrix because distro identity alone is not enough to determine what the current host will allow. It was also chosen over capability-only probing because distro family still matters for native path expectations and default policy.
|
||||
|
||||
The model is:
|
||||
|
||||
- distro family selects the intended install policy
|
||||
- host capabilities determine whether that policy can be executed fully, degraded, or not at all
|
||||
- one generic install engine executes the workflow using the resolved policy
|
||||
|
||||
## Install Policy Model
|
||||
|
||||
### Debian, Fedora, Arch, openSUSE
|
||||
|
||||
- `--user` installs use `aim`-managed user paths
|
||||
- `--system` prefers native shared desktop integration locations and system icon locations
|
||||
- AppImage payloads remain in an `aim`-managed system payload directory unless a later distro-specific need proves otherwise
|
||||
- Desktop caches are refreshed only when helper tools are present
|
||||
|
||||
### Alpine
|
||||
|
||||
- Treat Alpine as a lightweight Linux with shallower integration assumptions
|
||||
- Prefer `aim`-managed paths for both user and system installs
|
||||
- Run optional helpers only when present
|
||||
|
||||
### Nix
|
||||
|
||||
- Default to conservative behavior
|
||||
- Allow `--user` installs into `aim`-managed user paths, with a warning that the install is outside declarative package management
|
||||
- Deny `--system` installs until a Nix-native strategy exists
|
||||
- Never attempt to write into the Nix store or emulate a declarative install
|
||||
|
||||
### Immutable
|
||||
|
||||
- Treat `--user` as the primary supported path
|
||||
- If `--system` is requested, first test whether the host genuinely permits the required writes
|
||||
- If policy blocks system writes, either downgrade to user scope with an explicit warning or fail clearly when downgrade is not allowed by policy
|
||||
|
||||
### Generic fallback
|
||||
|
||||
- Use `aim`-managed paths only
|
||||
- Apply standards-based XDG desktop integration only
|
||||
- Skip distro-specific helper assumptions
|
||||
|
||||
### Cross-cutting rule
|
||||
|
||||
Payload storage and integration targets are separate concerns.
|
||||
|
||||
For example, a system install may place the AppImage payload under `/opt/aim/appimages`, while writing the `.desktop` file to `/usr/share/applications` and icons to `/usr/share/icons`. This keeps artifact replacement and rollback simple while still integrating natively.
|
||||
|
||||
## Execution Pipeline
|
||||
|
||||
Use one install engine with policy injected into it rather than separate installers per distro.
|
||||
|
||||
### 1. Resolve policy
|
||||
|
||||
- Detect distro family
|
||||
- Detect capabilities and policy markers
|
||||
- Resolve an `InstallPolicy` describing:
|
||||
- allowed scope
|
||||
- payload root
|
||||
- desktop entry root
|
||||
- icon root
|
||||
- integration mode
|
||||
- helper refresh actions
|
||||
- warnings and fallback notes
|
||||
|
||||
### 2. Stage artifact
|
||||
|
||||
- Download into a temporary staging path
|
||||
- Validate that the payload is an AppImage
|
||||
- Derive stable identity and final filenames before touching permanent locations
|
||||
- Mark the staged artifact executable before final commit
|
||||
|
||||
### 3. Commit payload atomically
|
||||
|
||||
- Move the staged AppImage into the final managed payload location
|
||||
- Use replacement semantics suitable for safe updates
|
||||
- Keep the old installed payload until the new one is validated and committed
|
||||
|
||||
### 4. Commit integration
|
||||
|
||||
- Generate a normalized `.desktop` file
|
||||
- Extract and install icons when available
|
||||
- Write integration artifacts into policy-selected locations
|
||||
- Keep these artifacts generated by `aim`, not manually managed
|
||||
|
||||
### 5. Refresh caches best-effort
|
||||
|
||||
- Run optional helpers only when present and relevant
|
||||
- Cache refresh failures should produce warnings, not rollback a valid install
|
||||
|
||||
### 6. Persist registry last
|
||||
|
||||
- Only persist the final `AppRecord` after payload and required integration steps succeed
|
||||
- The registry should represent completed installs, not partial attempts
|
||||
|
||||
## Reliability Model
|
||||
|
||||
### Preflight failures
|
||||
|
||||
Stop early for:
|
||||
|
||||
- unsupported scope for the resolved host policy
|
||||
- unwritable required target directories with no allowed fallback
|
||||
- payloads that are not valid AppImages
|
||||
- missing required normalized metadata for integration
|
||||
|
||||
### Transaction boundary
|
||||
|
||||
Treat install as three phases:
|
||||
|
||||
- preflight and staging
|
||||
- payload commit
|
||||
- integration commit
|
||||
|
||||
Nothing is persisted in the registry until the required phases succeed.
|
||||
|
||||
### Rollback rules
|
||||
|
||||
- If staging fails, clean temporary files only
|
||||
- If payload commit succeeds but required integration fails, remove the new payload unless degraded payload-only success was explicitly allowed
|
||||
- If integration partially succeeds, remove generated `.desktop` and icon artifacts before returning failure
|
||||
- Cache refresh failures do not trigger rollback
|
||||
|
||||
### Degraded success
|
||||
|
||||
Success with warnings is acceptable only when:
|
||||
|
||||
- optional cache refresh helpers are missing or fail
|
||||
- desktop integration was optional and the host lacks the helper stack to finish niceties
|
||||
- immutable or policy-heavy systems forced a user-scope fallback that policy explicitly allows
|
||||
|
||||
### Update safety
|
||||
|
||||
- Updates stage side-by-side and replace atomically
|
||||
- The previous working AppImage stays active until the new one is validated and committed
|
||||
- Failed updates should leave the previous installed version intact
|
||||
|
||||
## Verification Strategy
|
||||
|
||||
### Unit tests
|
||||
|
||||
- distro detection
|
||||
- immutable and Nix marker detection
|
||||
- helper capability probing
|
||||
- writable path probing
|
||||
- install policy resolution per family and scope
|
||||
- degraded and denied policy decisions
|
||||
|
||||
### Integration tests
|
||||
|
||||
- successful user install
|
||||
- successful system install using managed payload plus native integration paths
|
||||
- denied Nix system install
|
||||
- immutable system fallback to user install with warning
|
||||
- payload commit failure cleanup
|
||||
- integration failure rollback
|
||||
- cache refresh warning-only behavior
|
||||
|
||||
Fixture-driven filesystem tests should cover most of this. First implementation should not depend on real distro images in CI.
|
||||
|
||||
## Architecture Slice
|
||||
|
||||
### Core types
|
||||
|
||||
#### `DistroFamily`
|
||||
|
||||
- `Debian`
|
||||
- `Fedora`
|
||||
- `Arch`
|
||||
- `OpenSuse`
|
||||
- `Alpine`
|
||||
- `Nix`
|
||||
- `Immutable`
|
||||
- `Generic`
|
||||
|
||||
#### `HostCapabilities`
|
||||
|
||||
- parsed `os-release` identity
|
||||
- immutable and Nix policy markers
|
||||
- writable status for candidate directories
|
||||
- desktop-session presence
|
||||
- helper availability such as `update-desktop-database` and `gtk-update-icon-cache`
|
||||
|
||||
#### `InstallPolicy`
|
||||
|
||||
- resolved scope
|
||||
- payload path root
|
||||
- desktop entry root
|
||||
- icon path root
|
||||
- integration mode: `full`, `degraded`, `payload-only`, or `denied`
|
||||
- fallback notes and warnings for UI surfaces
|
||||
|
||||
#### `InstallPlan`
|
||||
|
||||
- selected artifact URL and expected identity
|
||||
- staging paths
|
||||
- final payload path
|
||||
- desktop file path
|
||||
- icon path
|
||||
- helper refresh actions to attempt after commit
|
||||
|
||||
#### `InstallOutcome`
|
||||
|
||||
- installed scope
|
||||
- resolved mode
|
||||
- written paths
|
||||
- warnings
|
||||
- rollback status
|
||||
|
||||
### Recommended module layout
|
||||
|
||||
Within `crates/aim-core/src/`:
|
||||
|
||||
- `platform/distro.rs`
|
||||
- `platform/capabilities.rs`
|
||||
- `integration/policy.rs`
|
||||
- `integration/install.rs`
|
||||
- `integration/desktop.rs`
|
||||
- `integration/refresh.rs`
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- `platform/distro.rs` detects distro families and policy markers
|
||||
- `platform/capabilities.rs` probes writability and helper availability
|
||||
- `integration/policy.rs` converts requested scope plus host facts into `InstallPolicy`
|
||||
- `integration/install.rs` owns the transactional install pipeline
|
||||
- `integration/desktop.rs` owns desktop file generation and icon handling
|
||||
- `integration/refresh.rs` owns best-effort helper execution
|
||||
|
||||
### CLI behavior
|
||||
|
||||
- `aim <QUERY>` should become a real install path rather than registry-only tracking
|
||||
- The CLI should print the resolved install mode before commit
|
||||
- If the plan degrades, the CLI should explain that before confirmation
|
||||
- Bare `aim` can later reuse the same policy summary when showing pending updates
|
||||
|
||||
## Summary
|
||||
|
||||
The agreed design is a single install engine in `aim-core` driven by a resolved per-host `InstallPolicy`. Distro families provide intended policy, runtime capabilities decide what is safe, and transactional install semantics keep installs recoverable. This preserves the thin-CLI architecture while allowing broad Linux coverage without scattering distro-specific conditionals across the entire codebase.
|
||||
|
|
@ -0,0 +1,341 @@
|
|||
# Per-Distro Installation Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Implement real AppImage installation in `aim-core` with distro-aware policy resolution, transactional payload and desktop integration, and CLI surfacing of resolved install mode and warnings.
|
||||
|
||||
**Architecture:** Add a host detection and policy layer ahead of the existing install scaffolding, then turn `integration/install.rs` into a transactional executor that stages payloads, commits managed artifacts atomically, writes desktop integration into policy-selected locations, and only persists registry state after success. Keep distro-specific behavior declarative through `DistroFamily`, `HostCapabilities`, and `InstallPolicy` instead of branching throughout the pipeline.
|
||||
|
||||
**Tech Stack:** Rust, Cargo workspace, std filesystem APIs, existing `aim-core` domain and registry types, `clap`, `dialoguer`, fixture-backed tests in `crates/aim-core/tests` and `crates/aim-cli/tests`.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Add distro family detection and host capability probing
|
||||
|
||||
**Files:**
|
||||
- Create: `crates/aim-core/src/platform/distro.rs`
|
||||
- Create: `crates/aim-core/src/platform/capabilities.rs`
|
||||
- Modify: `crates/aim-core/src/platform/mod.rs`
|
||||
- Test: `crates/aim-core/tests/platform_detection.rs`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
```rust
|
||||
use aim_core::platform::distro::{detect_distro_family, DistroFamily};
|
||||
|
||||
#[test]
|
||||
fn detects_fedora_family_from_os_release() {
|
||||
let distro = detect_distro_family("ID=fedora\nID_LIKE=rhel centos\n");
|
||||
assert_eq!(distro, DistroFamily::Fedora);
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cargo test detects_fedora_family_from_os_release --package aim-core --test platform_detection`
|
||||
Expected: FAIL because distro detection types do not exist yet
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
|
||||
Add:
|
||||
- `DistroFamily`
|
||||
- `/etc/os-release` parsing helpers
|
||||
- immutable and Nix policy markers
|
||||
- helper availability probing for desktop refresh commands
|
||||
- directory writability probing for candidate install roots
|
||||
|
||||
Keep the probing interfaces small and deterministic so tests can inject fake host facts.
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cargo test detects_fedora_family_from_os_release --package aim-core --test platform_detection`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add crates/aim-core/src/platform/distro.rs crates/aim-core/src/platform/capabilities.rs crates/aim-core/src/platform/mod.rs crates/aim-core/tests/platform_detection.rs
|
||||
git commit -m "feat: add distro and capability detection"
|
||||
```
|
||||
|
||||
### Task 2: Introduce install policy resolution
|
||||
|
||||
**Files:**
|
||||
- Create: `crates/aim-core/src/integration/policy.rs`
|
||||
- Modify: `crates/aim-core/src/integration/mod.rs`
|
||||
- Modify: `crates/aim-core/src/platform/mod.rs`
|
||||
- Test: `crates/aim-core/tests/install_policy.rs`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
```rust
|
||||
use aim_core::integration::policy::{resolve_install_policy, IntegrationMode};
|
||||
use aim_core::platform::{DistroFamily, HostCapabilities, InstallScope};
|
||||
|
||||
#[test]
|
||||
fn immutable_system_request_downgrades_to_user_when_allowed() {
|
||||
let capabilities = HostCapabilities::immutable_user_only();
|
||||
let policy = resolve_install_policy(DistroFamily::Immutable, InstallScope::System, &capabilities).unwrap();
|
||||
|
||||
assert_eq!(policy.scope, InstallScope::User);
|
||||
assert_eq!(policy.integration_mode, IntegrationMode::Degraded);
|
||||
assert!(!policy.warnings.is_empty());
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cargo test immutable_system_request_downgrades_to_user_when_allowed --package aim-core --test install_policy`
|
||||
Expected: FAIL because install policy resolution does not exist yet
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
|
||||
Create:
|
||||
- `InstallPolicy`
|
||||
- `IntegrationMode`
|
||||
- policy resolution for the agreed distro families
|
||||
- separation of payload, desktop, and icon roots
|
||||
- warning collection for downgraded or conservative behavior
|
||||
|
||||
Implement only the current agreed rules. Do not add speculative distro exceptions.
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cargo test immutable_system_request_downgrades_to_user_when_allowed --package aim-core --test install_policy`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add crates/aim-core/src/integration/policy.rs crates/aim-core/src/integration/mod.rs crates/aim-core/src/platform/mod.rs crates/aim-core/tests/install_policy.rs
|
||||
git commit -m "feat: resolve per-distro install policy"
|
||||
```
|
||||
|
||||
### Task 3: Turn install scaffolding into a staged payload executor
|
||||
|
||||
**Files:**
|
||||
- Modify: `crates/aim-core/src/integration/install.rs`
|
||||
- Modify: `crates/aim-core/src/integration/paths.rs`
|
||||
- Modify: `crates/aim-core/src/app/add.rs`
|
||||
- Test: `crates/aim-core/tests/install_payload.rs`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
```rust
|
||||
use aim_core::integration::install::stage_and_commit_payload;
|
||||
|
||||
#[test]
|
||||
fn payload_commit_moves_staged_appimage_into_final_location() {
|
||||
let outcome = stage_and_commit_payload(/* fixture inputs */).unwrap();
|
||||
assert!(outcome.final_payload_path.ends_with(".AppImage"));
|
||||
assert!(outcome.final_payload_path.exists());
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cargo test payload_commit_moves_staged_appimage_into_final_location --package aim-core --test install_payload`
|
||||
Expected: FAIL because install execution still only exposes path helpers
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
|
||||
Implement:
|
||||
- staging download target creation
|
||||
- AppImage validation hook
|
||||
- executable bit application in staging
|
||||
- atomic payload replacement into the managed payload root
|
||||
- minimal rollback for payload commit failure
|
||||
|
||||
Do not write registry state yet.
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cargo test payload_commit_moves_staged_appimage_into_final_location --package aim-core --test install_payload`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add crates/aim-core/src/integration/install.rs crates/aim-core/src/integration/paths.rs crates/aim-core/src/app/add.rs crates/aim-core/tests/install_payload.rs
|
||||
git commit -m "feat: add staged payload install executor"
|
||||
```
|
||||
|
||||
### Task 4: Add desktop integration and refresh handling
|
||||
|
||||
**Files:**
|
||||
- Create: `crates/aim-core/src/integration/desktop.rs`
|
||||
- Create: `crates/aim-core/src/integration/refresh.rs`
|
||||
- Modify: `crates/aim-core/src/integration/install.rs`
|
||||
- Modify: `crates/aim-core/src/integration/mod.rs`
|
||||
- Test: `crates/aim-core/tests/install_integration.rs`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
```rust
|
||||
use aim_core::integration::install::execute_install;
|
||||
|
||||
#[test]
|
||||
fn install_writes_desktop_entry_and_reports_refresh_warning_only() {
|
||||
let outcome = execute_install(/* fixture with missing helper */).unwrap();
|
||||
|
||||
assert!(outcome.desktop_entry_path.unwrap().exists());
|
||||
assert!(!outcome.warnings.is_empty());
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cargo test install_writes_desktop_entry_and_reports_refresh_warning_only --package aim-core --test install_integration`
|
||||
Expected: FAIL because desktop integration and refresh steps do not exist yet
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
|
||||
Add:
|
||||
- `.desktop` generation from normalized metadata
|
||||
- icon extraction and placement hooks
|
||||
- refresh action planning
|
||||
- best-effort helper execution for desktop database and icon cache refresh
|
||||
- rollback of generated integration files when required integration fails
|
||||
|
||||
Keep helper execution optional and warning-driven.
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cargo test install_writes_desktop_entry_and_reports_refresh_warning_only --package aim-core --test install_integration`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add crates/aim-core/src/integration/desktop.rs crates/aim-core/src/integration/refresh.rs crates/aim-core/src/integration/install.rs crates/aim-core/src/integration/mod.rs crates/aim-core/tests/install_integration.rs
|
||||
git commit -m "feat: add desktop integration and refresh handling"
|
||||
```
|
||||
|
||||
### Task 5: Persist registry state only after successful install and surface policy in the CLI
|
||||
|
||||
**Files:**
|
||||
- Modify: `crates/aim-core/src/app/add.rs`
|
||||
- Modify: `crates/aim-core/src/registry/mod.rs`
|
||||
- Modify: `crates/aim-cli/src/lib.rs`
|
||||
- Modify: `crates/aim-cli/src/ui/prompt.rs`
|
||||
- Modify: `crates/aim-cli/src/ui/render.rs`
|
||||
- Test: `crates/aim-cli/tests/end_to_end_cli.rs`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
```rust
|
||||
#[test]
|
||||
fn cli_add_installs_and_renders_resolved_mode() {
|
||||
let output = run_cli_add(/* fixture query */);
|
||||
|
||||
assert!(output.contains("installing as user"));
|
||||
assert!(output.contains("installed app:"));
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cargo test cli_add_installs_and_renders_resolved_mode --package aim-cli --test end_to_end_cli`
|
||||
Expected: FAIL because the CLI still performs registry-backed tracking only
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
|
||||
Change the add flow so it:
|
||||
- builds an install plan instead of only a tracking record
|
||||
- prints the resolved install mode and warnings before commit
|
||||
- persists the final `AppRecord` only after successful install completion
|
||||
- renders installed outcomes rather than tracked-only outcomes
|
||||
|
||||
Preserve review prompts where source ambiguity still exists.
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cargo test cli_add_installs_and_renders_resolved_mode --package aim-cli --test end_to_end_cli`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add crates/aim-core/src/app/add.rs crates/aim-core/src/registry/mod.rs crates/aim-cli/src/lib.rs crates/aim-cli/src/ui/prompt.rs crates/aim-cli/src/ui/render.rs crates/aim-cli/tests/end_to_end_cli.rs
|
||||
git commit -m "feat: execute installs from cli add flow"
|
||||
```
|
||||
|
||||
### Task 6: Lock down rollback and failure semantics
|
||||
|
||||
**Files:**
|
||||
- Modify: `crates/aim-core/src/integration/install.rs`
|
||||
- Modify: `crates/aim-core/src/integration/desktop.rs`
|
||||
- Test: `crates/aim-core/tests/install_failures.rs`
|
||||
- Modify: `README.md`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
```rust
|
||||
use aim_core::integration::install::execute_install;
|
||||
|
||||
#[test]
|
||||
fn integration_failure_removes_new_payload_and_generated_files() {
|
||||
let error = execute_install(/* fixture with forced desktop write failure */).unwrap_err();
|
||||
|
||||
assert!(error.to_string().contains("desktop integration failed"));
|
||||
assert_install_root_is_clean();
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cargo test integration_failure_removes_new_payload_and_generated_files --package aim-core --test install_failures`
|
||||
Expected: FAIL because rollback behavior is not complete yet
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
|
||||
Finish:
|
||||
- rollback of newly committed payloads on required integration failure
|
||||
- cleanup of generated desktop and icon artifacts
|
||||
- warning-only handling for refresh failures
|
||||
- README updates describing actual install behavior and degraded cases
|
||||
|
||||
Do not broaden feature scope beyond the approved design.
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cargo test integration_failure_removes_new_payload_and_generated_files --package aim-core --test install_failures`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add crates/aim-core/src/integration/install.rs crates/aim-core/src/integration/desktop.rs crates/aim-core/tests/install_failures.rs README.md
|
||||
git commit -m "feat: finalize install rollback behavior"
|
||||
```
|
||||
|
||||
### Task 7: Run full workspace verification
|
||||
|
||||
**Files:**
|
||||
- Modify: none unless verification exposes regressions tied to the approved scope
|
||||
|
||||
**Step 1: Run formatter**
|
||||
|
||||
Run: `cargo fmt --check`
|
||||
Expected: PASS
|
||||
|
||||
**Step 2: Run lints**
|
||||
|
||||
Run: `cargo clippy --workspace --all-targets --all-features -- -D warnings`
|
||||
Expected: PASS
|
||||
|
||||
**Step 3: Run full test suite**
|
||||
|
||||
Run: `cargo test --workspace`
|
||||
Expected: PASS
|
||||
|
||||
**Step 4: Fix only scoped regressions if any appear**
|
||||
|
||||
If verification fails, make the smallest design-consistent change needed and rerun the affected command before rerunning the full suite.
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "chore: verify per-distro installation implementation"
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue