User/ryanbod/folders enable staticanalysis (#5137)

* Enabling static analysis and settings treat warnings as errors

* Fixing/Supressing static analysis warnings in ContextmenuLoader and removing unused code

* Fixing static analysis errors in Main.cs

* Fixing static analysis warnings for folderpluginSettings.xaml.cs
This commit is contained in:
ryanbodrug-microsoft
2020-07-23 16:05:36 -07:00
committed by GitHub
parent 47736603af
commit 53c4c6cbb8
5 changed files with 81 additions and 90 deletions

View File

@@ -21,8 +21,9 @@ namespace Microsoft.Plugin.Folder
public ContextMenuLoader(PluginInitContext context) public ContextMenuLoader(PluginInitContext context)
{ {
_context = context; _context = context;
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alive, and instead log the exception")]
public List<ContextMenuResult> LoadContextMenus(Result selectedResult) public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{ {
var contextMenus = new List<ContextMenuResult>(); var contextMenus = new List<ContextMenuResult>();
@@ -95,6 +96,7 @@ namespace Microsoft.Plugin.Folder
return contextMenus; return contextMenus;
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alive, and instead log the exception")]
private ContextMenuResult CreateOpenContainingFolderResult(SearchResult record) private ContextMenuResult CreateOpenContainingFolderResult(SearchResult record)
{ {
return new ContextMenuResult return new ContextMenuResult
@@ -124,35 +126,7 @@ namespace Microsoft.Plugin.Folder
}; };
} }
public static void LogException(string message, Exception e)
private Result CreateOpenWithEditorResult(SearchResult record)
{
string editorPath = "notepad.exe"; // TODO add the ability to create a custom editor
var name = "Open With Editor: " + Path.GetFileNameWithoutExtension(editorPath);
return new Result
{
Title = name,
Action = _ =>
{
try
{
Process.Start(editorPath, record.FullPath);
return true;
}
catch (Exception e)
{
var message = $"Fail to editor for file at {record.FullPath}";
LogException(message, e);
_context.API.ShowMsg(message);
return false;
}
},
IcoPath = editorPath
};
}
public void LogException(string message, Exception e)
{ {
Log.Exception($"|Microsoft.Plugin.Folder.ContextMenu|{message}", e); Log.Exception($"|Microsoft.Plugin.Folder.ContextMenu|{message}", e);
} }

View File

@@ -1,4 +1,6 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
@@ -15,13 +17,13 @@ namespace Microsoft.Plugin.Folder
public partial class FileSystemSettings public partial class FileSystemSettings
{ {
private IPublicAPI woxAPI; private IPublicAPI woxAPI;
private Settings _settings; private FolderSettings _settings;
public FileSystemSettings(IPublicAPI woxAPI, Settings settings) public FileSystemSettings(IPublicAPI woxAPI, FolderSettings settings)
{ {
this.woxAPI = woxAPI; this.woxAPI = woxAPI;
InitializeComponent(); InitializeComponent();
_settings = settings; _settings = settings ?? throw new ArgumentNullException(paramName:nameof(settings));
lbxFolders.ItemsSource = _settings.FolderLinks; lbxFolders.ItemsSource = _settings.FolderLinks;
} }
@@ -30,7 +32,7 @@ namespace Microsoft.Plugin.Folder
var selectedFolder = lbxFolders.SelectedItem as FolderLink; var selectedFolder = lbxFolders.SelectedItem as FolderLink;
if (selectedFolder != null) if (selectedFolder != null)
{ {
string msg = string.Format(woxAPI.GetTranslation("wox_plugin_folder_delete_folder_link"), selectedFolder.Path); string msg = string.Format(CultureInfo.InvariantCulture, woxAPI.GetTranslation("wox_plugin_folder_delete_folder_link"), selectedFolder.Path);
if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes) if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{ {
@@ -50,15 +52,17 @@ namespace Microsoft.Plugin.Folder
var selectedFolder = lbxFolders.SelectedItem as FolderLink; var selectedFolder = lbxFolders.SelectedItem as FolderLink;
if (selectedFolder != null) if (selectedFolder != null)
{ {
var folderBrowserDialog = new FolderBrowserDialog(); using (var folderBrowserDialog = new FolderBrowserDialog())
folderBrowserDialog.SelectedPath = selectedFolder.Path; {
if (folderBrowserDialog.ShowDialog() == DialogResult.OK) folderBrowserDialog.SelectedPath = selectedFolder.Path;
{ if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
var link = _settings.FolderLinks.First(x => x.Path == selectedFolder.Path); {
link.Path = folderBrowserDialog.SelectedPath; var link = _settings.FolderLinks.First(x => x.Path == selectedFolder.Path);
} link.Path = folderBrowserDialog.SelectedPath;
}
lbxFolders.Items.Refresh(); lbxFolders.Items.Refresh();
}
} }
else else
{ {
@@ -69,36 +73,28 @@ namespace Microsoft.Plugin.Folder
private void btnAdd_Click(object sender, RoutedEventArgs e) private void btnAdd_Click(object sender, RoutedEventArgs e)
{ {
var folderBrowserDialog = new FolderBrowserDialog(); using (var folderBrowserDialog = new FolderBrowserDialog())
if (folderBrowserDialog.ShowDialog() == DialogResult.OK) {
{ if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
var newFolder = new FolderLink {
{ var newFolder = new FolderLink
Path = folderBrowserDialog.SelectedPath {
}; Path = folderBrowserDialog.SelectedPath
};
if (_settings.FolderLinks == null)
{ _settings.FolderLinks.Add(newFolder);
_settings.FolderLinks = new List<FolderLink>();
} }
_settings.FolderLinks.Add(newFolder); lbxFolders.Items.Refresh();
} }
lbxFolders.Items.Refresh();
} }
private void lbxFolders_Drop(object sender, DragEventArgs e) private void lbxFolders_Drop(object sender, DragEventArgs e)
{ {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files != null && files.Count() > 0) if (files != null && files.Any())
{ {
if (_settings.FolderLinks == null)
{
_settings.FolderLinks = new List<FolderLink>();
}
foreach (string s in files) foreach (string s in files)
{ {
if (Directory.Exists(s)) if (Directory.Exists(s))

View File

@@ -2,6 +2,7 @@ using Microsoft.PowerToys.Settings.UI.Lib;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@@ -24,13 +25,13 @@ namespace Microsoft.Plugin.Folder
private static List<string> _driverNames; private static List<string> _driverNames;
private PluginInitContext _context; private PluginInitContext _context;
private readonly Settings _settings; private readonly FolderSettings _settings;
private readonly PluginJsonStorage<Settings> _storage; private readonly PluginJsonStorage<FolderSettings> _storage;
private IContextMenu _contextMenuLoader; private IContextMenu _contextMenuLoader;
public Main() public Main()
{ {
_storage = new PluginJsonStorage<Settings>(); _storage = new PluginJsonStorage<FolderSettings>();
_settings = _storage.Load(); _settings = _storage.Load();
} }
@@ -49,13 +50,19 @@ namespace Microsoft.Plugin.Folder
_context = context; _context = context;
_contextMenuLoader = new ContextMenuLoader(context); _contextMenuLoader = new ContextMenuLoader(context);
InitialDriverList(); InitialDriverList();
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")]
public List<Result> Query(Query query) public List<Result> Query(Query query)
{ {
if(query == null)
{
throw new ArgumentNullException(paramName: nameof(query));
}
var results = GetUserFolderResults(query); var results = GetUserFolderResults(query);
string search = query.Search.ToLower(); string search = query.Search.ToLower(CultureInfo.InvariantCulture);
if (!IsDriveOrSharedFolder(search)) if (!IsDriveOrSharedFolder(search))
return results; return results;
@@ -72,7 +79,7 @@ namespace Microsoft.Plugin.Folder
private static bool IsDriveOrSharedFolder(string search) private static bool IsDriveOrSharedFolder(string search)
{ {
if (search.StartsWith(@"\\")) if (search.StartsWith(@"\\", StringComparison.InvariantCulture))
{ // share folder { // share folder
return true; return true;
} }
@@ -90,7 +97,7 @@ namespace Microsoft.Plugin.Folder
return false; return false;
} }
private Result CreateFolderResult(string title, string subtitle, string path, Query query) private static Result CreateFolderResult(string title, string subtitle, string path, Query query)
{ {
return new Result return new Result
{ {
@@ -106,18 +113,25 @@ namespace Microsoft.Plugin.Folder
return true; return true;
} }
}; };
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")]
private List<Result> GetUserFolderResults(Query query) private List<Result> GetUserFolderResults(Query query)
{ {
string search = query.Search.ToLower(); if(query == null)
{
throw new ArgumentNullException(paramName: nameof(query));
}
string search = query.Search.ToLower(CultureInfo.InvariantCulture);
var userFolderLinks = _settings.FolderLinks.Where( var userFolderLinks = _settings.FolderLinks.Where(
x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase)); x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase));
var results = userFolderLinks.Select(item => var results = userFolderLinks.Select(item =>
CreateFolderResult(item.Nickname, item.Path, item.Path, query)).ToList(); CreateFolderResult(item.Nickname, item.Path, item.Path, query)).ToList();
return results; return results;
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")]
private void InitialDriverList() private void InitialDriverList()
{ {
if (_driverNames == null) if (_driverNames == null)
@@ -126,7 +140,7 @@ namespace Microsoft.Plugin.Folder
var allDrives = DriveInfo.GetDrives(); var allDrives = DriveInfo.GetDrives();
foreach (DriveInfo driver in allDrives) foreach (DriveInfo driver in allDrives)
{ {
_driverNames.Add(driver.Name.ToLower().TrimEnd('\\')); _driverNames.Add(driver.Name.ToLower(CultureInfo.InvariantCulture).TrimEnd('\\'));
} }
} }
} }
@@ -134,8 +148,9 @@ namespace Microsoft.Plugin.Folder
private static readonly char[] _specialSearchChars = new char[] private static readonly char[] _specialSearchChars = new char[]
{ {
'?', '*', '>' '?', '*', '>'
}; };
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")]
private List<Result> QueryInternal_Directory_Exists(Query query) private List<Result> QueryInternal_Directory_Exists(Query query)
{ {
var search = query.Search; var search = query.Search;
@@ -149,7 +164,7 @@ namespace Microsoft.Plugin.Folder
int index = search.LastIndexOf('\\'); int index = search.LastIndexOf('\\');
if (index > 0 && index < (search.Length - 1)) if (index > 0 && index < (search.Length - 1))
{ {
incompleteName = search.Substring(index + 1).ToLower(); incompleteName = search.Substring(index + 1).ToLower(CultureInfo.InvariantCulture);
search = search.Substring(0, index + 1); search = search.Substring(0, index + 1);
if (!Directory.Exists(search)) if (!Directory.Exists(search))
{ {
@@ -164,19 +179,19 @@ namespace Microsoft.Plugin.Folder
else else
{ {
// folder exist, add \ at the end of doesn't exist // folder exist, add \ at the end of doesn't exist
if (!search.EndsWith("\\")) if (!search.EndsWith("\\", StringComparison.InvariantCulture))
{ {
search += "\\"; search += "\\";
} }
} }
results.Add(CreateOpenCurrentFolderResult(incompleteName, search)); results.Add(CreateOpenCurrentFolderResult( search));
var searchOption = SearchOption.TopDirectoryOnly; var searchOption = SearchOption.TopDirectoryOnly;
incompleteName += "*"; incompleteName += "*";
// give the ability to search all folder when starting with > // give the ability to search all folder when starting with >
if (incompleteName.StartsWith(">")) if (incompleteName.StartsWith(">", StringComparison.InvariantCulture))
{ {
searchOption = SearchOption.AllDirectories; searchOption = SearchOption.AllDirectories;
@@ -223,8 +238,9 @@ namespace Microsoft.Plugin.Folder
// Initial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection. // Initial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList(); return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList();
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alve and instead inform the user of the error")]
private static Result CreateFileResult(string filePath, Query query) private static Result CreateFileResult(string filePath, Query query)
{ {
var result = new Result var result = new Result
@@ -251,14 +267,14 @@ namespace Microsoft.Plugin.Folder
return result; return result;
} }
private static Result CreateOpenCurrentFolderResult(string incompleteName, string search) private static Result CreateOpenCurrentFolderResult(string search)
{ {
var firstResult = "Open " + search; var firstResult = "Open " + search;
var folderName = search.TrimEnd('\\').Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None).Last(); var folderName = search.TrimEnd('\\').Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None).Last();
var sanitizedPath = Regex.Replace(search, @"[\/\\]+", "\\"); var sanitizedPath = Regex.Replace(search, @"[\/\\]+", "\\");
// A network path must start with \\ // A network path must start with \\
if (sanitizedPath.StartsWith("\\")) if (sanitizedPath.StartsWith("\\", StringComparison.InvariantCulture))
{ {
sanitizedPath = sanitizedPath.Insert(0, "\\"); sanitizedPath = sanitizedPath.Insert(0, "\\");
} }

View File

@@ -23,6 +23,7 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -94,6 +95,10 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" /> <PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Runtime" Version="4.3.1" /> <PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup> </ItemGroup>

View File

@@ -4,9 +4,9 @@ using Wox.Infrastructure.Storage;
namespace Microsoft.Plugin.Folder namespace Microsoft.Plugin.Folder
{ {
public class Settings public class FolderSettings
{ {
[JsonProperty] [JsonProperty]
public List<FolderLink> FolderLinks { get; set; } = new List<FolderLink>(); public List<FolderLink> FolderLinks { get;} = new List<FolderLink>();
} }
} }