Skip to content

Commit 04a9b19

Browse files
Merge branch 'develop' for release v6.5.2
Co-authored-by: Cursor <cursoragent@cursor.com>
2 parents 9893add + fe1127d commit 04a9b19

39 files changed

Lines changed: 1045 additions & 147 deletions

build/Modules/PublishWingetModule.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,12 @@ await context.Shell.Command.ExecuteCommandLineTool(
162162
private static IEnumerable<string> BuildPyRevitUrls(VersionInfo versionInfo, string releaseTag)
163163
{
164164
var baseUrl = $"https://github.com/pyrevitlabs/pyRevit/releases/download/{releaseTag}/";
165-
yield return $"{baseUrl}pyRevit_{versionInfo.InstallVersion}_signed.exe|x86|user";
166165
yield return $"{baseUrl}pyRevit_{versionInfo.InstallVersion}_admin_signed.exe|x64|machine";
167166
}
168167

169168
private static IEnumerable<string> BuildCliUrls(VersionInfo versionInfo, string releaseTag)
170169
{
171170
var baseUrl = $"https://github.com/pyrevitlabs/pyRevit/releases/download/{releaseTag}/";
172-
yield return $"{baseUrl}pyRevit_CLI_{versionInfo.InstallVersion}_signed.exe|x64|user";
173171
yield return $"{baseUrl}pyRevit_CLI_{versionInfo.InstallVersion}_admin_signed.exe|x64|machine";
174172
yield return $"{baseUrl}pyRevit_CLI_{versionInfo.InstallVersion}_admin_signed.msi|x64|machine";
175173
}

build/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ dotnet test tests/Build.Tests.csproj -c Release
115115
| `pack` | Restore CI-stamped metadata (if present), build Inno/MSI installers and Chocolatey package (requires `bin/`) |
116116
| `sign` | Sign binaries, installers, and `.nupkg` via `sign code trusted-signing` |
117117
| `publish` | Generate release notes, create draft GitHub release, push Chocolatey |
118-
| `winget` | Generate WinGet manifests, strip `elevationProhibited` from user installers, submit PRs to winget-pkgs |
118+
| `winget` | Generate WinGet manifests (machine-scope installers only), strip `elevationProhibited` if present, submit PRs to winget-pkgs |
119119
| `notify` | Comment on linked GitHub issues |
120120

121121
Combine modes as needed, e.g. WIP pack+sign:

dev/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</PropertyGroup>
1818

1919
<PropertyGroup>
20-
<Version>6.5.0.26173+1406</Version>
20+
<Version>6.5.2.26175+2113</Version>
2121
<Copyright>Copyright © 2014-2026</Copyright>
2222
<Company>pyRevitLabs.io</Company>
2323
</PropertyGroup>

dev/pyRevitLabs/pyRevitCLI/PyRevitCLI.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,9 @@ private static void ProcessArguments() {
859859
else if (all("seed"))
860860
PyRevitConfigs.SeedConfig(lockSeedConfig: arguments["--lock"].IsTrue);
861861

862+
else if (all("seedshippeddefaults"))
863+
PyRevitConfigs.SeedShippedExtensionDefaults();
864+
862865
else if (any("enable", "disable")) {
863866
if (arguments["<option_path>"] != null) {
864867
// extract section and option names

dev/pyRevitLabs/pyRevitCLI/PyRevitCLIAppCmds.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ internal static void
157157
Environment.UserDomainName, Environment.UserName));
158158
Console.WriteLine(string.Format("Active User: {0}", UserEnv.GetLoggedInUserName()));
159159
Console.WriteLine(string.Format("Admin Access: {0}", UserEnv.IsRunAsAdmin() ? "Yes" : "No"));
160+
Console.WriteLine(string.Format("Install Scope: {0}",
161+
PyRevitInstallScope.IsAllUsersInstall() ? "AllUsers" : "PerUser"));
162+
Console.WriteLine(string.Format("Active Config: \"{0}\"",
163+
PyRevitInstallScope.GetActiveConfigFilePath()));
160164
Console.WriteLine(string.Format("%APPDATA%: \"{0}\"",
161165
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)));
162166
Console.WriteLine(string.Format("Latest Installed .Net Framework: {0}",

dev/pyRevitLabs/pyRevitCLI/PyRevitCLIAppHelps.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ internal static void PrintHelp(PyRevitCLICommandType commandType, int exitCode)
329329
header: "Manage pyRevit configurations",
330330
mgmtCommands: new Dictionary<string, string>() {
331331
{ "seed", "Seed existing configuration file to %PROGRAMDATA%" },
332+
{ "seedshippeddefaults", "Write disabled flags for shipped extensions with default_enabled=False" },
332333
{ "routes", "Routes configurations" },
333334
{ "telemetry", "Script Telemetry configurations" },
334335
{ "apptelemetry", "Application Telemetry configurations" },

dev/pyRevitLabs/pyRevitCLI/PyRevitCLIExtensionCmds.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ internal static void
175175
if (extName != null) {
176176
PyRevitClone clone = null;
177177
if (cloneName != null)
178-
clone = PyRevitClones.GetRegisteredClone(cloneName);
178+
clone = TryResolveShippedClone(cloneName);
179179

180180
if (enable) {
181181
if (clone != null)
@@ -192,6 +192,30 @@ internal static void
192192
}
193193
}
194194

195+
private static PyRevitClone TryResolveShippedClone(string cloneName) {
196+
try {
197+
return PyRevitClones.GetRegisteredClone(cloneName);
198+
}
199+
catch {
200+
PyRevitClone fallbackClone = null;
201+
foreach (var attachment in PyRevitAttachments.GetAttachments()) {
202+
try {
203+
var manifestClone = PyRevitClone.GetCloneFromManifest(attachment.Manifest);
204+
if (manifestClone.Matches(cloneName))
205+
return manifestClone;
206+
if (fallbackClone == null)
207+
fallbackClone = manifestClone;
208+
}
209+
catch {
210+
continue;
211+
}
212+
}
213+
if (fallbackClone != null)
214+
return new PyRevitClone(fallbackClone.ClonePath, name: cloneName);
215+
return null;
216+
}
217+
}
218+
195219
internal static void
196220
ForgetExtensionLookupSources(bool all, string lookupPath) {
197221
if (all)

dev/pyRevitLabs/pyRevitCLI/Resources/UsagePatterns.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ Usage:
102102
pyrevit configs apptelemetry server [<server_path>] [--log=<log_file>]
103103
pyrevit configs outputcss [<css_path>] [--log=<log_file>]
104104
pyrevit configs seed [--lock] [--log=<log_file>]
105+
pyrevit configs seedshippeddefaults [--log=<log_file>]
105106
pyrevit configs <option_path> [(enable | disable)] [--log=<log_file>]
106107
pyrevit configs <option_path> [<option_value>] [--log=<log_file>]
107108
pyrevit doctor (-h | --help)

dev/pyRevitLabs/pyRevitLabs.Common/CommonUtils.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,44 @@ public static bool VerifyPath(string path) {
4343
return false;
4444
}
4545

46+
/// <summary>
47+
/// Expands %VAR% tokens in a user-supplied path (e.g. --dest=%LOCALAPPDATA%\pyRevit).
48+
/// Repeats until stable so nested values like TEMP=%LOCALAPPDATA%\Temp resolve fully.
49+
/// </summary>
50+
public static string ExpandEnvironmentPath(string path) {
51+
if (string.IsNullOrWhiteSpace(path))
52+
return path;
53+
return ExpandEnvironmentPathRecursive(path.Trim());
54+
}
55+
56+
/// <summary>
57+
/// User temp directory with environment variables expanded (handles TEMP=%LOCALAPPDATA%\Temp).
58+
/// </summary>
59+
public static string GetUserTempDirectory() {
60+
var temp = Environment.GetEnvironmentVariable("TEMP");
61+
var candidate = !string.IsNullOrWhiteSpace(temp)
62+
? ExpandEnvironmentPathRecursive(temp.Trim())
63+
: ExpandEnvironmentPathRecursive("%TEMP%");
64+
if (IsConcreteExpandedPath(candidate))
65+
return candidate;
66+
return Path.GetTempPath().TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
67+
}
68+
69+
private static bool IsConcreteExpandedPath(string path) {
70+
return !string.IsNullOrWhiteSpace(path) && path.IndexOf('%') < 0;
71+
}
72+
73+
private static string ExpandEnvironmentPathRecursive(string path) {
74+
var expanded = path;
75+
for (int pass = 0; pass < 8; pass++) {
76+
var next = Environment.ExpandEnvironmentVariables(expanded).Trim();
77+
if (string.Equals(next, expanded, StringComparison.OrdinalIgnoreCase))
78+
break;
79+
expanded = next;
80+
}
81+
return expanded;
82+
}
83+
4684
public static bool VerifyPythonScript(string path) {
4785
return VerifyFile(path) && path.ToLower().EndsWith(".py");
4886
}

dev/pyRevitLabs/pyRevitLabs.Common/Consts.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace pyRevitLabs.Common {
99
public class PyRevitLabsConsts {
10+
public const string PyRevitPathOverrideEnvVar = "PYREVIT_PATH_OVERRIDE";
11+
public const string PyRevitProgramDataPathOverrideEnvVar = "PYREVIT_PROGRAMDATA_PATH_OVERRIDE";
1012
// product
1113
public const string ProductName = "pyRevit";
1214

@@ -50,13 +52,31 @@ public class PyRevitLabsConsts {
5052
public const string AppdataCacheDirName = "Cache";
5153
public const string AppdataLogsDirName = "Logs";
5254

55+
// install scope marker (all-users installer creates this under %ProgramData%\pyRevit\)
56+
public const string InstallAllUsersMarkerFileName = "install_all_users";
57+
public const string DefaultConfigsFileName = "pyRevit_config.ini";
58+
5359
// pyRevit %appdata% path
5460
// @reviewed
55-
public static string PyRevitPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), AppdataDirName);
61+
public static string PyRevitPath {
62+
get {
63+
string pathOverride = Environment.GetEnvironmentVariable(PyRevitPathOverrideEnvVar);
64+
if (!string.IsNullOrWhiteSpace(pathOverride))
65+
return pathOverride;
66+
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), AppdataDirName);
67+
}
68+
}
5669

5770
// pyRevit %programdata% path
5871
// @reviewed
59-
public static string PyRevitProgramDataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), AppdataDirName);
72+
public static string PyRevitProgramDataPath {
73+
get {
74+
string pathOverride = Environment.GetEnvironmentVariable(PyRevitProgramDataPathOverrideEnvVar);
75+
if (!string.IsNullOrWhiteSpace(pathOverride))
76+
return pathOverride;
77+
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), AppdataDirName);
78+
}
79+
}
6080

6181
// pyrevit general cache folder
6282
public static string CacheDirectory => Path.Combine(PyRevitPath, AppdataCacheDirName);

0 commit comments

Comments
 (0)