Skip to content

Fix configs seed self-copy in all-users scope - #3543

Open
WaynePatrickDalton wants to merge 4 commits into
pyrevitlabs:developfrom
Pascall-Watson:fix-seed-config-lock
Open

Fix configs seed self-copy in all-users scope#3543
WaynePatrickDalton wants to merge 4 commits into
pyrevitlabs:developfrom
Pascall-Watson:fix-seed-config-lock

Conversation

@WaynePatrickDalton

@WaynePatrickDalton WaynePatrickDalton commented Aug 10, 2026

Copy link
Copy Markdown

Fix configs seed self-copy failure in all-users scope

Description

Hey @jmcouffin - I came across this when updating our pyRevit wix based installer. Looking it up online, seems a few more users over the years have had this issue - although, perhaps this 'bug' is intended feature of pyrevit. Let me know eitherway!

This pull request attemps to fix a known bug where configs seed can fail with a misleading file-lock style error when source and target resolve to the same config file in all-users scope. This PR was generated using GPT5.3 Codex and Fable5 via Github Copilot on VSC.

What changed:

  • Normalizes source and target paths using Path.GetFullPath, trims trailing directory separators, and compares using OrdinalIgnoreCase.
  • Adds same-path handling in SeedConfig:
  • Skips copy when source equals target.
  • Logs a debug message explaining seeding was skipped because both paths resolve to the same file.
  • Returns success instead of throwing.
  • Preserves lock intent for same-path behavior by setting read-only on the target when lockSeedConfig is true and the file exists.
  • Preserves different-path behavior and existing exception wrapping semantics for real failures.
  • Adds unit tests for:
  • same-path seed success without throw,
  • same-path seed with lock applying read-only,
  • different-path seed still copying as before.

Background and prior reports:


Checklist

  • Code follows the PEP 8 style guide. (Not applicable for this C# change)
  • Code has been formatted with Black. (Not applicable for this C# change)
  • Changes are tested and verified to work as expected.

Validation performed:

  • dotnet build -c Debug
  • dotnet vstest .\bin\Debug\net48\pyRevitLabs.UnitTests.dll --TestCaseFilter:"FullyQualifiedName~PyRevitConfigsTests"
  • dotnet vstest .\bin\Debug\net48\pyRevitLabs.UnitTests.dll --TestCaseFilter:"FullyQualifiedName~PyRevitInstallScopeTests"

Result summary:

  • Build succeeded with 0 warnings and 0 errors.
  • SeedConfig tests passed: 3 passed, 0 failed.
  • Install scope regression sanity tests passed: 6 passed, 0 failed.

Related Issues


Additional Notes

Reference documentation:

Implementation note:

  • The fix targets the all-users self-copy case specifically (ProgramData to the same ProgramData file) and keeps the existing copy/failure behavior for true different-path operations.

@devloai devloai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary:

  • Fixes a bug where SeedConfig fails with a misleading file-lock error when source and target resolve to the same config file in all-users scope (ProgramData → same ProgramData file).
  • Normalizes source/target paths via Path.GetFullPath, compares with OrdinalIgnoreCase, and skips the copy when they're identical — logging a debug message and returning success instead of throwing.
  • Preserves lock intent by applying read-only attributes on the target when lockSeedConfig is true.
  • Extracts the lock logic into a shared ApplySeedConfigLock helper to avoid duplication.
  • Adds unit tests covering same-path skip, same-path with lock, and different-path copy behavior.

Review Summary:

The fix is well-targeted and correctly addresses issue #1266. The path normalization and same-path short-circuit logic is sound, and the refactoring into ApplySeedConfigLock is clean. One medium-severity issue: NormalizePath (which calls Path.GetFullPath) is invoked outside the try block that wraps failures in PyRevitException, so malformed paths will propagate unwrapped System.ArgumentException instead of the expected PyRevitException — this breaks the PR's stated goal of preserving exception-wrapping semantics. The fix is to move the samePath computation inside the existing try. One low-severity observation: the same-path branch silently skips the lock when the config file doesn't exist, with no diagnostic log explaining that the lock wasn't applied. Tests are well-structured with proper setup/cleanup and environment variable isolation.

Suggestions

  • Add a test case for SeedConfig when sourceFile does not exist in same-path mode to verify it returns without throwing. Apply
  • Add a test verifying that SeedConfig wraps Path.GetFullPath failures in PyRevitException after moving NormalizePath inside the try block. Apply

Comment thread dev/pyRevitLabs/pyRevitLabs.PyRevit/PyRevitConfigs.cs Outdated
Comment thread dev/pyRevitLabs/pyRevitLabs.PyRevit/PyRevitConfigs.cs Outdated
- compute same-path check inside the try block so path resolution errors are wrapped in PyRevitException as before
- log a debug message when lockSeedConfig is set but the config file is missing in the same-path case
- update tests for upstream active-config resolution (admin-locked machine config now drives the same-path scenario)
@WaynePatrickDalton

Copy link
Copy Markdown
Author

Pulling the PR branch fast-forwarded in upstream develop changes that reworked active-config resolution (GetActiveConfig now routes non-elevated processes to the per-user config), which broke the two same-path tests. I updated pyRevitLabs.UnitTests.PyRevitConfigs.cs to drive the same-path scenario via an admin-locked (read-only) machine config, which resolves deterministically regardless of elevation.

Validation:

Build: 0 Warning(s) 0 Error(s)
PyRevitConfigsTests: Passed! - Failed: 0, Passed: 3
PyRevitInstallScopeTests: Passed! - Failed: 0, Passed: 14, Skipped: 3 (skips are elevation-dependent tests, pre-existing)

@WaynePatrickDalton
WaynePatrickDalton marked this pull request as ready for review August 10, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI pyrevit configs seed command not working as expected

1 participant