diff --git a/src/GitMan/Actions/RepositoryAction.cs b/src/GitMan/Actions/RepositoryAction.cs index f5cbbf3..8617192 100644 --- a/src/GitMan/Actions/RepositoryAction.cs +++ b/src/GitMan/Actions/RepositoryAction.cs @@ -1,4 +1,5 @@ -using System; +using GitMan.Config; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -9,10 +10,29 @@ namespace GitMan.Actions { internal class RepositoryAction { - public bool UseShellExecute { get; set; } - public string NameTemplate { get; set; } - public string CommandTemplate { get; set; } - public string SearchFilter { get; set; } + private readonly bool _useShellExecute; + private readonly string _nameTemplate; + private readonly string _commandTemplate; + private readonly string _searchFilter; + + public RepositoryAction(ActionSettings settings) + { + _useShellExecute = settings.Shell.GetValueOrDefault(false); + _nameTemplate = settings.Name; + _commandTemplate = GetCommand(settings.Program, settings.Args); + _searchFilter = settings.SearchFilter; + } + + private static string GetCommand(string program, string[] args) + { + program ??= string.Empty; + args ??= Array.Empty(); + + var items = Enumerable.Repeat(program, 1).Concat(args); + var quoted = items.Select(item => $"\"{item}\""); + var command = string.Join(' ', quoted); + return command; + } public IEnumerable GetMenuItems(DirectoryInfo directoryInfo) { @@ -21,7 +41,7 @@ public IEnumerable GetMenuItems(DirectoryInfo directoryInfo) private IEnumerable EnumerateMatches(DirectoryInfo directoryInfo) { - return directoryInfo.EnumerateFileSystemInfos(SearchFilter, SearchOption.AllDirectories); + return directoryInfo.EnumerateFileSystemInfos(_searchFilter, SearchOption.AllDirectories); } private static string Substitute(string value, FileSystemInfo info) @@ -39,18 +59,18 @@ private static string Substitute(string value, FileSystemInfo info) private string GetName(FileSystemInfo fileSystemInfo) { - var name = Substitute(NameTemplate, fileSystemInfo); + var name = Substitute(_nameTemplate, fileSystemInfo); return name; } private ProcessStartInfo GetProcessStartInfo(FileSystemInfo fileSystemInfo) { - var command = Substitute(CommandTemplate, fileSystemInfo); + var command = Substitute(_commandTemplate, fileSystemInfo); var startInfo = new ProcessStartInfo { FileName = command, - UseShellExecute = UseShellExecute, + UseShellExecute = _useShellExecute, }; return startInfo; diff --git a/src/GitMan/Actions/RepositoryActions.cs b/src/GitMan/Actions/RepositoryActions.cs deleted file mode 100644 index 214fd71..0000000 --- a/src/GitMan/Actions/RepositoryActions.cs +++ /dev/null @@ -1,96 +0,0 @@ -using GitMan.Config; -using System.Collections.Generic; -using System.IO; - -namespace GitMan.Actions -{ - internal static class RepositoryActions - { - public static IEnumerable GetDefaults(Settings settings) - { - yield return MakeFolderAction(); - - if (GitBashExists(settings)) - { - yield return MakeGitBashAction(settings); - } - - if (VsCodeExists(settings)) - { - yield return MakeVsCodeAction(settings); - } - - yield return MakeSolutionAction(); - } - - private static RepositoryAction MakeSolutionAction() - { - var action = new RepositoryAction - { - CommandTemplate = "{path}", - NameTemplate = "Open {name}", - SearchFilter = "*.sln", - UseShellExecute = true, - }; - - return action; - } - - private static RepositoryAction MakeFolderAction() - { - var action = new RepositoryAction - { - CommandTemplate = "{directory}", - NameTemplate = "Open folder", - SearchFilter = ".git", - UseShellExecute = true, - }; - - return action; - } - - private static RepositoryAction MakeGitBashAction(Settings settings) - { - var gitBashPath = settings.GitBashPath; - var commandTemplate = $"\"{gitBashPath}\" --cd=\"{{directory}}\""; - - var action = new RepositoryAction - { - CommandTemplate = commandTemplate, - NameTemplate = "Git Bash", - SearchFilter = ".git", - UseShellExecute = false, - }; - - return action; - } - - private static RepositoryAction MakeVsCodeAction(Settings settings) - { - var vsCodePath = settings.VsCodePath; - var commandTemplate = $"\"{vsCodePath}\" \"{{directory}}\""; - - var action = new RepositoryAction - { - CommandTemplate = commandTemplate, - NameTemplate = "VS Code", - SearchFilter = ".git", - UseShellExecute = false, - }; - - return action; - } - - private static bool GitBashExists(Settings settings) - { - var gitBashExists = File.Exists(settings.GitBashPath); - return gitBashExists; - } - - private static bool VsCodeExists(Settings settings) - { - var vsCodeExists = File.Exists(settings.VsCodePath); - return vsCodeExists; - } - } -} diff --git a/src/GitMan/Config/ActionSettings.cs b/src/GitMan/Config/ActionSettings.cs new file mode 100644 index 0000000..2dc2989 --- /dev/null +++ b/src/GitMan/Config/ActionSettings.cs @@ -0,0 +1,11 @@ +namespace GitMan.Config +{ + internal class ActionSettings + { + public string Name { get; set; } + public string Program { get; set; } + public string[] Args { get; set; } + public string SearchFilter { get; set; } + public bool? Shell { get; set; } + } +} diff --git a/src/GitMan/Config/DefaultActions.cs b/src/GitMan/Config/DefaultActions.cs new file mode 100644 index 0000000..1b1dabd --- /dev/null +++ b/src/GitMan/Config/DefaultActions.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace GitMan.Config +{ + internal static class DefaultActions + { + public static ActionSettings[] Get() + { + var actions = new List(); + + AddFolderAction(actions); + AddGitBashAction(actions); + AddVsCodeAction(actions); + AddSolutionAction(actions); + + return actions.ToArray(); + } + + private static void AddSolutionAction(List actions) + { + var action = new ActionSettings + { + Program = "{path}", + Name = "Open {name}", + SearchFilter = "*.sln", + Shell = true, + }; + + actions.Add(action); + } + + private static void AddFolderAction(List actions) + { + var action = new ActionSettings + { + Program = "{directory}", + Name = "Open folder", + SearchFilter = ".git", + Shell = true, + }; + + actions.Add(action); + } + + private static void AddGitBashAction(List actions) + { + const string gitBashPath = "C:\\Program Files\\Git\\git-bash.exe"; + + var gitBashExists = File.Exists(gitBashPath); + + if (gitBashExists) + { + var args = new [] { "--cd={directory}" }; + + var action = new ActionSettings + { + Program = gitBashPath, + Args = args, + Name = "Git Bash", + SearchFilter = ".git", + }; + + actions.Add(action); + } + } + + private static void AddVsCodeAction(List actions) + { + var userProfile = Environment.GetEnvironmentVariable("USERPROFILE"); + var vsCodePath = Path.Combine(userProfile, "AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe"); + + var vsCodeExists = File.Exists(vsCodePath); + + if (vsCodeExists) + { + var args = new [] { "{directory}" }; + + var action = new ActionSettings + { + Program = vsCodePath, + Args = args, + Name = "VS Code", + SearchFilter = ".git", + }; + + actions.Add(action); + } + } + } +} diff --git a/src/GitMan/Config/Settings.cs b/src/GitMan/Config/Settings.cs index 7a28f01..387385c 100644 --- a/src/GitMan/Config/Settings.cs +++ b/src/GitMan/Config/Settings.cs @@ -11,23 +11,24 @@ internal class Settings public string GitBashPath { get; set; } public AzureProviderSettings[] AzureProviders { get; set; } public GitHubProviderSettings[] GitHubProviders { get; set; } + public ActionSettings[] Actions { get; set; } private static Settings CreateDefault() { var userProfile = Environment.GetEnvironmentVariable("USERPROFILE"); - var repositoryFolder = Path.Combine(userProfile, "./Source/Repos"); - var vsCodePath = Path.Combine(userProfile, "./AppData/Local/Programs/Microsoft VS Code/Code.exe"); - const string gitBashPath = "C:/Program Files/Git/git-bash.exe"; + var repositoryFolder = Path.Combine(userProfile, "Source\\Repos"); + + var actions = DefaultActions.Get(); + var azureProviders = Array.Empty(); var gitHubProviders = Array.Empty(); var settings = new Settings { RepositoryFolder = repositoryFolder, - VsCodePath = vsCodePath, - GitBashPath = gitBashPath, AzureProviders = azureProviders, GitHubProviders = gitHubProviders, + Actions = actions, }; return settings; @@ -50,6 +51,7 @@ public static Settings Load() settings.AzureProviders ??= Array.Empty(); settings.GitHubProviders ??= Array.Empty(); + settings.Actions ??= Array.Empty(); return settings; } @@ -58,10 +60,11 @@ public void Save() { var options = new JsonSerializerOptions { + IgnoreNullValues = true, WriteIndented = true, }; - var json = JsonSerializer.ToString(this, options); + var json = JsonSerializer.ToString( this, options); File.WriteAllText("config.json", json); } } diff --git a/src/GitMan/Context.cs b/src/GitMan/Context.cs index 6025d9a..01de10a 100644 --- a/src/GitMan/Context.cs +++ b/src/GitMan/Context.cs @@ -1,6 +1,6 @@ using GitMan.Actions; -using GitMan.Providers; using GitMan.Config; +using GitMan.Providers; using System; using System.Collections.Generic; using System.Drawing; @@ -16,7 +16,6 @@ public class Context : ApplicationContext private readonly NotifyIcon _icon; private readonly Main _main; private readonly Settings _settings; - private readonly RepositoryAction[] _repositoryActions; private readonly RemoteProvider[] _remoteProviders; private readonly RepositoryDirectory _repositoryDirectory; @@ -28,8 +27,6 @@ public Context() _settings = Settings.Load(); - _repositoryActions = RepositoryActions.GetDefaults(_settings).ToArray(); - var azureProviders = _settings.AzureProviders .Select(provider => (RemoteProvider)new AzureProvider(provider)); var gitHubProviders = _settings.GitHubProviders @@ -137,8 +134,9 @@ private MenuItem MakeMenuItem(Repository repository) var directoryInfo = new DirectoryInfo(repository.FullName); var subItems = new List(); + var actions = _settings.Actions.Select(settings => new RepositoryAction(settings)); - foreach (var repositoryAction in _repositoryActions) + foreach (var repositoryAction in actions) { subItems.AddRange(repositoryAction.GetMenuItems(directoryInfo)); }