Skip to content

Commit

Permalink
CPS Custom In Memory Profile option
Browse files Browse the repository at this point in the history
Prevents overriding existing project profiles not enabled by default
  • Loading branch information
mitchcapper authored and Irame committed Apr 18, 2023
1 parent 789c66c commit 84937f9
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 13 deletions.
10 changes: 10 additions & 0 deletions SmartCmdArgs/SmartCmdArgs.Shared/CmdArgsOptionPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public CmdArgsOptionPage() : base()
private bool _vcsSupportEnabled;
private bool _useSolutionDir;
private bool _macroEvaluationEnabled;
private bool _CPSCustomProjectEnabled;

[Category("General")]
[DisplayName("Relative path root")]
Expand Down Expand Up @@ -126,6 +127,15 @@ public bool MacroEvaluationEnabled
set => SetAndNotify(value, ref _macroEvaluationEnabled);
}

[Category("Settings Defaults")]
[DisplayName("CPS Custom Project Profile")]
[Description("If enabled CPS style projects will have an additional in memory 'Smart CLI Command' profile added, and our custom args will only run when its selected rather than overriding the active profile.")]
[DefaultValue(false)]
public bool CPSCustomProjectEnabled {
get => _CPSCustomProjectEnabled;
set => SetAndNotify(value, ref _CPSCustomProjectEnabled);
}

public override void SaveSettingsToStorage()
{
if (_dontSave)
Expand Down
28 changes: 27 additions & 1 deletion SmartCmdArgs/SmartCmdArgs.Shared/CmdArgsPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public sealed class CmdArgsPackage : AsyncPackage
public bool SaveSettingsToJson => Settings.SaveSettingsToJson ?? Options.SaveSettingsToJson;
public bool IsVcsSupportEnabled => Settings.VcsSupportEnabled ?? Options.VcsSupportEnabled;
public bool IsMacroEvaluationEnabled => Settings.MacroEvaluationEnabled ?? Options.MacroEvaluationEnabled;
public bool CPSCustomProjectEnabled => Settings.CPSCustomProjectEnabled ?? Options.CPSCustomProjectEnabled;
public bool IsUseSolutionDirEnabled => vsHelper?.GetSolutionFilename() != null && (Settings.UseSolutionDir ?? Options.UseSolutionDir);

public bool IsUseMonospaceFontEnabled => Options.UseMonospaceFont;
Expand Down Expand Up @@ -120,6 +121,24 @@ public CmdArgsPackage()
this.AddOptionKey(SolutionOptionKey);
}

private void CPSCreateAndSetProfileIfUsed(Guid ProjectGuid) {
if (!CPSCustomProjectEnabled || ProjectGuid == Guid.Empty)
return;

if (! ToolWindowViewModel.TreeViewModel.AllItems.Any(a=>a is CmdArgument))
return;

var ivProject = vsHelper.HierarchyForProjectGuid(ProjectGuid);
if (!ivProject.IsCpsProject())
return;

var project = ivProject.GetProject();
if (CpsProjectSupport.IsActiveLaunchProfileCustomProfile(project))
return;

CpsProjectSupport.EnsureCustomProfileCreated(project, true);
}

#region Package Members
internal Interface GetService<Service, Interface>()
{
Expand Down Expand Up @@ -211,6 +230,8 @@ private void SettingsViewModel_PropertyChanged(object sender, System.ComponentMo

private void OnTreeContentChangedThrottled(object sender, TreeViewModel.TreeChangedEventArgs e)
{
CPSCreateAndSetProfileIfUsed(e.AffectedProject?.Id ?? Guid.Empty);

if (IsVcsSupportEnabled)
{
Logger.Info($"Tree content changed and VCS support is enabled. Saving all project commands to json file for project '{e.AffectedProject.Id}'.");
Expand Down Expand Up @@ -282,7 +303,7 @@ private void UpdateConfigurationForProject(IVsHierarchy project)
if (commandLineArgs == null)
return;

ProjectArguments.SetArguments(project, commandLineArgs);
ProjectArguments.SetArguments(project, commandLineArgs, CPSCustomProjectEnabled);
Logger.Info($"Updated Configuration for Project: {project.GetName()}");
}

Expand Down Expand Up @@ -530,6 +551,8 @@ private void UpdateCommandsForProject(IVsHierarchy project)
return;
}

CPSCreateAndSetProfileIfUsed(project.GetGuid());

var solutionData = toolWindowStateLoadedFromSolution ?? new SuoDataJson();

// joins data from solution and project
Expand Down Expand Up @@ -814,6 +837,9 @@ private void UpdateCurrentStartupProject()

ToolWindowViewModel.TreeViewModel.Projects.ForEach(p => p.Value.IsStartupProject = startupProjectGuids.Contains(p.Key));
ToolWindowViewModel.TreeViewModel.UpdateTree();

//we don't have to worry if we are empty or not it will check that for us
startupProjectGuids.ForEach(guid => CPSCreateAndSetProfileIfUsed(guid));
}

public Task OpenFileInVisualStudioAsync(string path) => vsHelper.OpenFileInVisualStudioAsync(path);
Expand Down
40 changes: 34 additions & 6 deletions SmartCmdArgs/SmartCmdArgs.Shared/Helper/CpsProjectSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public static string GetActiveLaunchProfileName(EnvDTE.Project project)
return null;
}

public static bool IsActiveLaunchProfileCustomProfile(EnvDTE.Project project) => GetActiveLaunchProfileName(project) == WritableLaunchProfile.CustomProfileName;

public static IEnumerable<string> GetLaunchProfileNames(EnvDTE.Project project)
{
if (TryGetProjectServices(project, out IUnconfiguredProjectServices unconfiguredProjectServices, out IProjectServices projectServices))
Expand All @@ -64,7 +66,12 @@ public static IEnumerable<string> GetLaunchProfileNames(EnvDTE.Project project)
return null;
}

public static void SetCpsProjectArguments(EnvDTE.Project project, string arguments)
public static void EnsureCustomProfileCreated(EnvDTE.Project project, bool SetActive)
{
SetCpsProjectArguments(project, "", true, SetActive);
}

public static void SetCpsProjectArguments(EnvDTE.Project project, string arguments, bool cpsUseCustomProfile, bool setActive = false)
{
IUnconfiguredProjectServices unconfiguredProjectServices;
IProjectServices projectServices;
Expand All @@ -77,15 +84,19 @@ public static void SetCpsProjectArguments(EnvDTE.Project project, string argumen
if (activeLaunchProfile == null)
return;

WritableLaunchProfile writableLaunchProfile = new WritableLaunchProfile(activeLaunchProfile);
WritableLaunchProfile writableLaunchProfile = new WritableLaunchProfile(activeLaunchProfile, cpsUseCustomProfile);
writableLaunchProfile.CommandLineArgs = arguments;

// Does not work on VS2015, which should be okay ...
// We don't hold references for VS2015, where the interface is called IThreadHandling
IProjectThreadingService projectThreadingService = projectServices.ThreadingPolicy;
projectThreadingService.ExecuteSynchronously(() =>
{
return launchSettingsProvider.AddOrUpdateProfileAsync(writableLaunchProfile, addToFront: false);
var task = launchSettingsProvider.AddOrUpdateProfileAsync(writableLaunchProfile, addToFront: false);
if (setActive)
task = task.ContinueWith(_ => launchSettingsProvider.SetActiveProfileAsync(writableLaunchProfile.Name));
return task;
});
}
}
Expand Down Expand Up @@ -117,6 +128,9 @@ public static Dictionary<string, string> GetCpsProjectAllArguments(EnvDTE.Projec
}

class WritableLaunchProfile : ILaunchProfile
#if VS17
, Microsoft.VisualStudio.ProjectSystem.Debug.IPersistOption
#endif
{
public string Name { set; get; }
public string CommandName { set; get; }
Expand All @@ -127,13 +141,27 @@ class WritableLaunchProfile : ILaunchProfile
public string LaunchUrl { set; get; }
public ImmutableDictionary<string, string> EnvironmentVariables { set; get; }
public ImmutableDictionary<string, object> OtherSettings { set; get; }
public bool DoNotPersist { get; set; }

public WritableLaunchProfile(ILaunchProfile launchProfile)
public const string CustomProfileName = "Smart CLI Args";
public WritableLaunchProfile(ILaunchProfile launchProfile, bool cpsUseCustomProfile)
{
Name = launchProfile.Name;
if (!cpsUseCustomProfile)
{
Name = launchProfile.Name;
CommandLineArgs = launchProfile.CommandLineArgs;
} else
{
Name = CustomProfileName;
DoNotPersist = true;
if (launchProfile.Name == CustomProfileName)
CommandLineArgs = launchProfile.CommandLineArgs;
else
CommandLineArgs = "";//ensure we dont get into an odd state where hidden args are being applied

}
ExecutablePath = launchProfile.ExecutablePath;
CommandName = launchProfile.CommandName;
CommandLineArgs = launchProfile.CommandLineArgs;
WorkingDirectory = launchProfile.WorkingDirectory;
LaunchBrowser = launchProfile.LaunchBrowser;
LaunchUrl = launchProfile.LaunchUrl;
Expand Down
10 changes: 5 additions & 5 deletions SmartCmdArgs/SmartCmdArgs.Shared/Helper/ProjectArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,11 @@ private static void GetVFProjEngineAllArguments(EnvDTE.Project project, List<Cmd

#region Common Project System (CPS)

private static void SetCpsProjectArguments(EnvDTE.Project project, string arguments)
private static void SetCpsProjectArguments(EnvDTE.Project project, string arguments, bool cpsUseCustomProfile)
{
// Should only be called in VS 2017 or higher
// .Net Core 2 is not supported by VS 2015, so this should not cause problems
CpsProjectSupport.SetCpsProjectArguments(project, arguments);
CpsProjectSupport.SetCpsProjectArguments(project, arguments, cpsUseCustomProfile);
}

private static void GetCpsProjectAllArguments(EnvDTE.Project project, List<CmdArgumentJson> allArgs)
Expand Down Expand Up @@ -302,7 +302,7 @@ private static void GetCpsProjectAllArguments(EnvDTE.Project project, List<CmdAr
} },
// C# - Lagacy DotNetCore
{ProjectKinds.CSCore, new ProjectArgumentsHandlers() {
SetArguments = (project, arguments) => SetCpsProjectArguments(project, arguments),
SetArguments = (project, arguments) => SetCpsProjectArguments(project, arguments, false),
GetAllArguments = (project, allArgs) => GetCpsProjectAllArguments(project, allArgs)
} },
// F#
Expand Down Expand Up @@ -356,12 +356,12 @@ public static void AddAllArguments(IVsHierarchy project, List<CmdArgumentJson> a
}
}

public static void SetArguments(IVsHierarchy project, string arguments)
public static void SetArguments(IVsHierarchy project, string arguments, bool CpsUseCustomProfile=false)
{
if (project.IsCpsProject())
{
Logger.Info($"Setting arguments on CPS project of type '{project.GetKind()}'.");
SetCpsProjectArguments(project.GetProject(), arguments);
SetCpsProjectArguments(project.GetProject(), arguments, CpsUseCustomProfile);
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions SmartCmdArgs/SmartCmdArgs.Shared/Logic/JsonDataObjects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class SettingsJson
public bool? VcsSupportEnabled { get; set; }
public bool? UseSolutionDir { get; set; }
public bool? MacroEvaluationEnabled { get; set; }
public bool? CPSCustomProjectEnabled { get; set; }

public SettingsJson() { }

Expand All @@ -28,6 +29,7 @@ public SettingsJson(SettingsViewModel settingsViewModel)
VcsSupportEnabled = settingsViewModel.VcsSupportEnabled;
UseSolutionDir = settingsViewModel.UseSolutionDir;
MacroEvaluationEnabled = settingsViewModel.MacroEvaluationEnabled;
CPSCustomProjectEnabled = settingsViewModel.CPSCustomProjectEnabled;
}
}

Expand Down
5 changes: 5 additions & 0 deletions SmartCmdArgs/SmartCmdArgs.Shared/View/SettingsControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
<TextBlock Margin="15,0,10,5" TextWrapping="WrapWithOverflow">
If enabled Macros like '$(ProjectDir)' will be evaluated and replaced by the corresponding string.
</TextBlock>

<uc:SettingsCheckBox HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5,5,5,5" LabelText="Custom CPS Project Profile" IsChecked="{Binding CPSCustomProjectEnabled}" DefaultValue="{Binding Package.Options.CPSCustomProjectEnabled, Mode=OneWay}" />
<TextBlock Margin="15,0,10,5" TextWrapping="WrapWithOverflow">
If enabled CPS style projects will have an additional in memory 'Smart CLI Command' profile added, and our custom args will only run when its selected rather than overriding the active profile.
</TextBlock>
</StackPanel>
</ScrollViewer>
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,0">
Expand Down
11 changes: 10 additions & 1 deletion SmartCmdArgs/SmartCmdArgs.Shared/ViewModel/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class SettingsViewModel : PropertyChangedBase
private bool? _vcsSupportEnabled;
private bool? _useSolutionDir;
private bool? _macroEvaluationEnabled;
private bool? _CPSCustomProjectEnabled;

public bool? SaveSettingsToJson
{
Expand All @@ -43,8 +44,16 @@ public bool? MacroEvaluationEnabled
set => SetAndNotify(value, ref _macroEvaluationEnabled);
}


public bool? CPSCustomProjectEnabled
{
get => _CPSCustomProjectEnabled;
set => SetAndNotify(value, ref _CPSCustomProjectEnabled);
}

public RelayCommand OpenOptionsCommand { get; }
public CmdArgsPackage Package => _package;

public CmdArgsPackage Package => _package;

public SettingsViewModel(CmdArgsPackage package)
{
Expand Down

0 comments on commit 84937f9

Please sign in to comment.