diff --git a/src/.idea/.idea.AudioTagger/.idea/.name b/src/.idea/.idea.AudioTagger/.idea/.name
new file mode 100644
index 0000000..9722465
--- /dev/null
+++ b/src/.idea/.idea.AudioTagger/.idea/.name
@@ -0,0 +1 @@
+AudioTagger
\ No newline at end of file
diff --git a/src/.idea/.idea.AudioTagger/.idea/vcs.xml b/src/.idea/.idea.AudioTagger/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/src/.idea/.idea.AudioTagger/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.idea/.idea.AudioTagger/.idea/workspace.xml b/src/.idea/.idea.AudioTagger/.idea/workspace.xml
index 38e94b2..45f98da 100644
--- a/src/.idea/.idea.AudioTagger/.idea/workspace.xml
+++ b/src/.idea/.idea.AudioTagger/.idea/workspace.xml
@@ -7,11 +7,7 @@
-
-
-
-
-
+
@@ -32,6 +28,9 @@
"accountId": "653de2b3-2fa9-4b2d-ad29-b83ddffa6c63"
}
}
+
+
+
{
"associatedIndex": 3
@@ -44,17 +43,17 @@
{
"keyToString": {
"RunOnceActivity.ShowReadmeOnStart": "true",
- "git-widget-placeholder": "rider-improvements",
+ "git-widget-placeholder": "dotnet-9-code-cleanup",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
- "settings.editor.selected.configurable": "editor.preferences.completion",
+ "settings.editor.selected.configurable": "preferences.pluginManager",
"vue.rearranger.settings.migration": "true"
}
}
-
+
@@ -84,7 +83,8 @@
1729839918012
-
+
+
diff --git a/src/AudioTagger.Console/GetUserInput.cs b/src/AudioTagger.Console/GetUserInput.cs
index d462909..8715528 100644
--- a/src/AudioTagger.Console/GetUserInput.cs
+++ b/src/AudioTagger.Console/GetUserInput.cs
@@ -1,13 +1,9 @@
-using System;
-using System.Linq;
-using System.Collections.Generic;
-using AudioTagger.Library;
+using AudioTagger.Library;
namespace AudioTagger.Console;
public enum UserResponse
{
- None,
Yes,
No,
Cancel
@@ -15,8 +11,8 @@ public enum UserResponse
public sealed record KeyResponse
{
- public char Key { get; init; }
- public UserResponse Response { get; init; }
+ public char Key { get; }
+ public UserResponse Response { get; }
public KeyResponse(char key, UserResponse response)
{
@@ -30,7 +26,7 @@ public static class ResponseHandler
///
/// Ask the user a question that they can answer with a single keystroke.
///
- public static UserResponse AskUserQuestion(IReadOnlyList question,
+ private static UserResponse AskUserQuestion(IReadOnlyList question,
IReadOnlyList allowedResponses,
IPrinter printer)
{
@@ -56,13 +52,13 @@ public static UserResponse AskUserQuestion(IReadOnlyList question
ConsoleKeyInfo keyInfo = System.Console.ReadKey(true);
char keyChar = char.ToLowerInvariant(keyInfo.KeyChar);
- KeyResponse? relevantKeyResponse =
- allowedResponses
- .Where(r => r.Key == keyChar)?
- .FirstOrDefault();
+ var relevantKeyResponse =
+ allowedResponses.FirstOrDefault(r => r.Key == keyChar);
if (relevantKeyResponse == null)
+ {
continue;
+ }
return relevantKeyResponse.Response;
}
@@ -82,7 +78,7 @@ public static UserResponse AskUserYesNoCancel(IPrinter printer)
new ("N", ConsoleColor.Magenta),
new (" (or "),
new ("C", ConsoleColor.Magenta),
- new (" to cancel): "),
+ new (" to cancel): ")
};
var allowedResponses = new List
diff --git a/src/AudioTagger.Console/MediaFilePathInfo.cs b/src/AudioTagger.Console/MediaFilePathInfo.cs
index 0e8f484..1def957 100644
--- a/src/AudioTagger.Console/MediaFilePathInfo.cs
+++ b/src/AudioTagger.Console/MediaFilePathInfo.cs
@@ -11,9 +11,9 @@ internal sealed class MediaFilePathInfo
Path.DirectorySeparatorChar
];
- private string WorkingPath { get; init; }
- private List SubDirectories { get; init; }
- private string FileName { get; init; }
+ private string WorkingPath { get; }
+ private List SubDirectories { get; }
+ private string FileName { get; }
public MediaFilePathInfo(
string workingPath,
diff --git a/src/AudioTagger.Console/MediaFileViewer.cs b/src/AudioTagger.Console/MediaFileViewer.cs
index 200ab13..6cd996c 100644
--- a/src/AudioTagger.Console/MediaFileViewer.cs
+++ b/src/AudioTagger.Console/MediaFileViewer.cs
@@ -1,3 +1,4 @@
+using System.Globalization;
using Spectre.Console;
namespace AudioTagger.Console;
@@ -7,7 +8,7 @@ public sealed class MediaFileViewer
public void PrintFileDetails(MediaFile file)
{
// TODO: Handle colors more gracefully.
- var tagNameFormatter = (string s) => "[grey]" + s + "[/]";
+ string TagNameFormatter(string s) => "[grey]" + s + "[/]";
Table table = new();
table.AddColumns(string.Empty, string.Empty);
@@ -15,45 +16,45 @@ public void PrintFileDetails(MediaFile file)
table.HideHeaders();
table.Expand = true;
- table.AddRow(tagNameFormatter("Title"), file.Title.EscapeMarkup());
+ table.AddRow(TagNameFormatter("Title"), file.Title.EscapeMarkup());
if (file.AlbumArtists.Any())
{
- table.AddRow(tagNameFormatter("Album Artist"),
+ table.AddRow(TagNameFormatter("Album Artist"),
file.AlbumArtists.Join().EscapeMarkup());
}
- table.AddRow(tagNameFormatter("Artist"), file.Artists.Join().EscapeMarkup());
- table.AddRow(tagNameFormatter("Album"), file.Album.EscapeMarkup());
+ table.AddRow(TagNameFormatter("Artist"), file.Artists.Join().EscapeMarkup());
+ table.AddRow(TagNameFormatter("Album"), file.Album.EscapeMarkup());
if (file.TrackNo > 0)
- table.AddRow(tagNameFormatter("Track"), file.TrackNo.ToString());
+ table.AddRow(TagNameFormatter("Track"), file.TrackNo.ToString());
if (file.Year > 0)
- table.AddRow(tagNameFormatter("Year"), file.Year.ToString());
- table.AddRow(tagNameFormatter("Duration"), file.Duration.ToString("m\\:ss"));
+ table.AddRow(TagNameFormatter("Year"), file.Year.ToString());
+ table.AddRow(TagNameFormatter("Duration"), file.Duration.ToString("m\\:ss"));
int genreCount = file.Genres.Length;
- table.AddRow(tagNameFormatter("Genres"),
+ table.AddRow(TagNameFormatter("Genres"),
file.Genres.Join().EscapeMarkup() +
(genreCount > 1 ? $" ({genreCount})" : string.Empty));
string bitrate = file.BitRate.ToString();
string sampleRate = file.SampleRate.ToString("#,##0");
- table.AddRow(tagNameFormatter("Quality"), $"{bitrate} kbps @ {sampleRate} kHz | {file.ReplayGainSummary()}");
+ table.AddRow(TagNameFormatter("Quality"), $"{bitrate} kbps @ {sampleRate} kHz | {file.ReplayGainSummary()}");
- if (file.Composers?.Length > 0)
+ if (file.Composers.Length > 0)
{
table.AddRow(
- tagNameFormatter("Composers"),
+ TagNameFormatter("Composers"),
file.Composers.Join().EscapeMarkup());
}
if (file.Comments.HasText())
- table.AddRow(tagNameFormatter("Comments"), file.Comments.EscapeMarkup());
+ table.AddRow(TagNameFormatter("Comments"), file.Comments.EscapeMarkup());
if (file.Description.HasText())
- table.AddRow(tagNameFormatter("Comments"), file.Description.EscapeMarkup());
+ table.AddRow(TagNameFormatter("Comments"), file.Description.EscapeMarkup());
if (file.Lyrics.HasText())
- table.AddRow(tagNameFormatter("Lyrics"), file.Lyrics[..25].EscapeMarkup() + "...");
+ table.AddRow(TagNameFormatter("Lyrics"), file.Lyrics[..25].EscapeMarkup() + "...");
table.Columns[0].Width(15);
@@ -78,7 +79,7 @@ public static TableRow PrintFileSummary(MediaFile file)
file.Year == 0 ? string.Empty : file.Year.ToString(),
file.Genres.Join().EscapeMarkup(),
file.Duration.ToString("m\\:ss"),
- file.ReplayGainTrack.ToString()
+ file.ReplayGainTrack.ToString(CultureInfo.InvariantCulture)
};
IEnumerable markups = rows.Select(r => new Markup(r));
diff --git a/src/AudioTagger.Console/OperationLibrary.cs b/src/AudioTagger.Console/OperationLibrary.cs
index 5b595a2..7e21d68 100644
--- a/src/AudioTagger.Console/OperationLibrary.cs
+++ b/src/AudioTagger.Console/OperationLibrary.cs
@@ -7,7 +7,7 @@ namespace AudioTagger.Console;
internal static class OperationLibrary
{
- internal static readonly IReadOnlyList Operations =
+ private static readonly IReadOnlyList Operations =
[
new(
["-v", "--view"],
@@ -95,7 +95,7 @@ internal static class OperationLibrary
["--cache-tags"],
"Cache files' tag data locally to a JSON file whose path is specified in the settings. (Eventually, this will be helpful in speeding up certain operations.)",
new TagCacher(),
- isHidden: true),
+ isHidden: true)
];
public static Dictionary GenerateHelpTextPairs(bool includeHidden)
@@ -109,7 +109,7 @@ public static Dictionary GenerateHelpTextPairs(bool includeHidde
o => o.Description);
}
- public static Result GetPathOperation(string requestedOperation)
+ private static Result GetPathOperation(string requestedOperation)
{
string loweredOperation = requestedOperation.ToLowerInvariant();
@@ -129,10 +129,9 @@ public static Result> GetPathOperations(
var successes = new List();
var failures = new List();
- Result currentResult;
foreach (string operation in requestedOperations)
{
- currentResult = GetPathOperation(operation);
+ Result currentResult = GetPathOperation(operation);
if (currentResult.IsSuccess)
{
successes.Add(currentResult.Value);
@@ -167,5 +166,5 @@ public Operation(
(Commands, Description, PathOperation, IsHidden) =
(commands, description, pathOperation, isHidden);
}
- };
+ }
}
diff --git a/src/AudioTagger.Console/Operations/MediaFileRenamer.cs b/src/AudioTagger.Console/Operations/MediaFileRenamer.cs
index d3b687b..67ae3bf 100644
--- a/src/AudioTagger.Console/Operations/MediaFileRenamer.cs
+++ b/src/AudioTagger.Console/Operations/MediaFileRenamer.cs
@@ -17,7 +17,7 @@ public void Start(
Settings settings,
IPrinter printer)
{
- if (settings?.Renaming is null)
+ if (settings.Renaming is null)
{
printer.Error("The settings file contained no rename settings, so cannot continue.");
return;
@@ -80,7 +80,7 @@ private static bool ConfirmStart(DirectoryInfo workingDirectory, IPrinter printe
new SelectionPrompt()
// Escaped because substrings like "[1984]" will be misinterpreted as formatting codes.
.Title($"All files will be saved under directory \"{Markup.Escape(workingDirectory.FullName)}\"")
- .AddChoices(["Continue", "Cancel"]));
+ .AddChoices("Continue", "Cancel"));
if (directoryResponse == "Continue")
{
@@ -108,7 +108,7 @@ private static void RenameFiles(
{
MediaFile file = mediaFiles.ElementAt(i);
- if (file.Title?.Length == 0)
+ if (file.Title.Length == 0)
{
printer.Print($"Skipping \"{file.FileNameOnly}\" because it has no title.",
fgColor: ConsoleColor.DarkRed);
@@ -190,14 +190,14 @@ private static bool RenameSingleFile(
var populatedTagNames = file.PopulatedTagNames();
string? matchedRenamePattern = null;
- foreach (string testPattern in renamePatterns)
+ foreach (string pattern in renamePatterns)
{
- MatchCollection matches = TagFinderRegex.Matches(testPattern);
- var expectedTags = matches.Cast().Select(m => m.Value).ToImmutableList();
- if (expectedTags.Count == populatedTagNames.Count &&
- expectedTags.TrueForAll(tag => populatedTagNames.Contains(tag)))
+ var matches = TagFinderRegex.Matches(pattern);
+ var expectedTags = matches.Select(m => m.Value).ToList();
+
+ if (AreIdentical(expectedTags, populatedTagNames))
{
- matchedRenamePattern = testPattern;
+ matchedRenamePattern = pattern;
}
}
@@ -213,7 +213,7 @@ private static bool RenameSingleFile(
? GenerateSafeDirectoryName(file)
: string.Empty;
string newAlbumDir = useAlbumDirectory && useArtistDirectory && file.Album.HasText()
- ? IOUtilities.SanitizePath(file.Album)
+ ? IoUtilities.SanitizePath(file.Album)
: string.Empty;
string newFileName = GenerateFileNameUsingPattern(file, populatedTagNames, matchedRenamePattern);
MediaFilePathInfo newPathInfo = new(workingPath, [newArtistDir, newAlbumDir], newFileName);
@@ -225,7 +225,7 @@ private static bool RenameSingleFile(
}
printer.Print(" Old name: " + oldPathInfo.FullFilePath(true));
- printer.Print(" New name: " + newPathInfo.FullFilePath(true));;
+ printer.Print(" New name: " + newPathInfo.FullFilePath(true));
if (doConfirm)
{
@@ -237,7 +237,7 @@ private static bool RenameSingleFile(
string response = AnsiConsole.Prompt(
new SelectionPrompt()
.Title("Rename this file?")
- .AddChoices([no, yes, yesToAll, cancel]));
+ .AddChoices(no, yes, yesToAll, cancel));
if (response == cancel)
{
@@ -283,8 +283,8 @@ static string GenerateFileNameUsingPattern(
);
var ext = Path.GetExtension(file.FileNameOnly);
- var unsanitizedName = workingFileName.ToString() + ext;
- return IOUtilities.SanitizePath(unsanitizedName);
+ var unsanitizedName = workingFileName + ext;
+ return IoUtilities.SanitizePath(unsanitizedName);
StringBuilder ReplacePlaceholders(StringBuilder workingName, string tagName)
{
@@ -293,28 +293,28 @@ StringBuilder ReplacePlaceholders(StringBuilder workingName, string tagName)
"ALBUMARTISTS" =>
workingName.Replace(
"%ALBUMARTISTS%",
- IOUtilities.SanitizePath(file.AlbumArtists)),
+ IoUtilities.SanitizePath(file.AlbumArtists)),
"ARTISTS" =>
workingName.Replace(
"%ARTISTS%",
- IOUtilities.SanitizePath(file.Artists)),
+ IoUtilities.SanitizePath(file.Artists)),
"ALBUM" =>
workingName.Replace(
"%ALBUM%",
- IOUtilities.SanitizePath(file.Album)),
+ IoUtilities.SanitizePath(file.Album)),
"TITLE" =>
workingName.Replace(
"%TITLE%",
- IOUtilities.SanitizePath(file.Title)),
+ IoUtilities.SanitizePath(file.Title)),
"YEAR" =>
workingName.Replace(
"%YEAR%",
- IOUtilities.SanitizePath(file.Year.ToString())),
+ IoUtilities.SanitizePath(file.Year.ToString())),
"TRACK" =>
workingName.Replace(
"%TRACK%",
- IOUtilities.SanitizePath(file.TrackNo.ToString())),
- _ => throw new InvalidOperationException($"File tag name \"{tagName} is not supported."),
+ IoUtilities.SanitizePath(file.TrackNo.ToString())),
+ _ => throw new InvalidOperationException($"File tag name \"{tagName} is not supported.")
};
}
}
@@ -326,17 +326,17 @@ static string GenerateSafeDirectoryName(MediaFile file)
{
if (MediaFile.HasAnyValues(file.AlbumArtists))
{
- return IOUtilities.SanitizePath(file.AlbumArtists);
+ return IoUtilities.SanitizePath(file.AlbumArtists);
}
if (MediaFile.HasAnyValues(file.Artists))
{
- return IOUtilities.SanitizePath(file.Artists);
+ return IoUtilities.SanitizePath(file.Artists);
}
if (file.Album.HasText())
{
- return IOUtilities.SanitizePath(file.Album);
+ return IoUtilities.SanitizePath(file.Album);
}
return "___UNSPECIFIED___";
@@ -408,4 +408,8 @@ private static void PrintDeletedDirectories(IList dirs, IPrinter printer
foreach (string dir in dirs)
printer.Print("- " + dir);
}
+
+ private static bool AreIdentical(List expectedTags, IList populatedTagNames)
+ => expectedTags.Count == populatedTagNames.Count &&
+ expectedTags.TrueForAll(populatedTagNames.Contains);
}
diff --git a/src/AudioTagger.Console/Operations/Normalization.cs b/src/AudioTagger.Console/Operations/Normalization.cs
index 2e55098..9c945ad 100644
--- a/src/AudioTagger.Console/Operations/Normalization.cs
+++ b/src/AudioTagger.Console/Operations/Normalization.cs
@@ -29,7 +29,7 @@ public void Start(IReadOnlyCollection mediaFiles,
{
FileName = "mp3gain",
Arguments = $"-r -k -p -s i \"{file.FileInfo}\"",
- RedirectStandardOutput = true,
+ RedirectStandardOutput = true
};
Process.Start(startInfo)!.WaitForExit();
diff --git a/src/AudioTagger.Console/Operations/TagArtworkExtractor.cs b/src/AudioTagger.Console/Operations/TagArtworkExtractor.cs
index 2a0bf19..1fd0d48 100644
--- a/src/AudioTagger.Console/Operations/TagArtworkExtractor.cs
+++ b/src/AudioTagger.Console/Operations/TagArtworkExtractor.cs
@@ -6,7 +6,7 @@ namespace AudioTagger.Console.Operations;
public sealed class TagArtworkExtractor : IPathOperation
{
- private static readonly string _artworkFileName = "cover.jpg";
+ private const string ArtworkFileName = "cover.jpg";
private static bool AreAllSame(IEnumerable items) =>
items.Distinct().Count() == 1;
@@ -50,17 +50,15 @@ private static void ProcessDirectory(FilesGroupedByDir fileGroup, IPrinter print
if (fileGroup.None(f => f.HasAlbumArt()))
{
- printer.Warning($"No artwork found in this directory.");
+ printer.Warning("No artwork found in this directory.");
return;
}
var albumNames = fileGroup.Select(file => file.Album);
var artistNames = fileGroup
- .Select(file => {
- return file.AlbumArtists.FirstOrDefault()
- ?? file.Artists.FirstOrDefault()
- ?? "None";
- });
+ .Select(file => file.AlbumArtists.FirstOrDefault()
+ ?? file.Artists.FirstOrDefault()
+ ?? "None");
if (!AreAllSame(artistNames) || !AreAllSame(albumNames))
{
@@ -98,10 +96,10 @@ private static void ExtractArtwork(FilesGroupedByCount fileGroup, IPrinter print
MediaFile artSourceFile = fileGroup.First();
string directoryName = artSourceFile.FileInfo.DirectoryName!;
- var extractResult = artSourceFile.ExtractArtworkToFile(directoryName, _artworkFileName);
+ var extractResult = artSourceFile.ExtractArtworkToFile(directoryName, ArtworkFileName);
if (extractResult.IsSuccess)
{
- printer.Print($"Saved most common artwork to \"{_artworkFileName}\" in the same directory.");
+ printer.Print($"Saved most common artwork to \"{ArtworkFileName}\" in the same directory.");
}
else
{
diff --git a/src/AudioTagger.Console/Operations/TagDuplicateFinder.cs b/src/AudioTagger.Console/Operations/TagDuplicateFinder.cs
index 5b89958..d37f821 100644
--- a/src/AudioTagger.Console/Operations/TagDuplicateFinder.cs
+++ b/src/AudioTagger.Console/Operations/TagDuplicateFinder.cs
@@ -15,7 +15,7 @@ public void Start(
Watch watch = new();
- var exclusions = settings.Duplicates?.Exclusions ?? [];
+ var exclusions = settings.Duplicates.Exclusions ?? [];
printer.Print($"Found {exclusions.Count} exclusion rule(s) in the settings.");
var includedFiles = exclusions.IsEmpty
@@ -24,7 +24,7 @@ public void Start(
if (includedFiles.Count == mediaFiles.Count)
{
- printer.Print($"No files were excluded via exclusion rules.");
+ printer.Print("No files were excluded via exclusion rules.");
}
else
{
@@ -33,14 +33,14 @@ public void Start(
printer.Print($"Out of {mediaFiles.Count:#,##0} media files, {diff:#,##0} {wasWere} excluded via exclusion rules.");
}
- static string pluralizeTerm(int count) => Utilities.Pluralize(count, "term", "terms");
+ static string PluralizeTerm(int count) => Utilities.Pluralize(count, "term", "terms");
- var artistReplacements = settings.Duplicates?.ArtistReplacements ?? [];
- string artistLabel = pluralizeTerm(artistReplacements.Count);
+ var artistReplacements = settings.Duplicates.ArtistReplacements ?? [];
+ string artistLabel = PluralizeTerm(artistReplacements.Count);
printer.Print($"Found {artistReplacements.Count} artist replacement {artistLabel}.");
var titleReplacements = settings.Duplicates?.TitleReplacements ?? [];
- string titleLabel = pluralizeTerm(titleReplacements.Count);
+ string titleLabel = PluralizeTerm(titleReplacements.Count);
printer.Print($"Found {titleReplacements.Count} title replacement {titleLabel}.");
var duplicateGroups = includedFiles
@@ -64,8 +64,8 @@ public void Start(
printer.Print($"Found {groupCount} duplicate {groupLabel} in {watch.ElapsedFriendly}.");
PrintResults(duplicateGroups, printer);
- string? searchFor = settings?.Duplicates?.PathSearchFor?.TextOrNull();
- string? replaceWith = settings?.Duplicates?.PathReplaceWith?.TextOrNull();
+ string? searchFor = settings.Duplicates?.PathSearchFor?.TextOrNull();
+ string? replaceWith = settings.Duplicates?.PathReplaceWith?.TextOrNull();
string? saveDir = settings?.Duplicates?.SavePlaylistDirectory;
CreatePlaylistFile(duplicateGroups, saveDir, (searchFor, replaceWith), printer);
}
@@ -81,14 +81,14 @@ private static bool ExcludeFile(MediaFile file, ICollection exclu
{
return exclusion switch
{
- { Artist: string a, Title: string t } =>
+ { Artist: { } a, Title: { } t } =>
file.AlbumArtists.Contains(a, StringComparer.OrdinalIgnoreCase) ||
file.Artists.Contains(a, StringComparer.OrdinalIgnoreCase) &&
file.Title.StartsWith(t, StringComparison.InvariantCultureIgnoreCase),
- { Artist: string a } =>
+ { Artist: { } a } =>
file.AlbumArtists.Contains(a, StringComparer.OrdinalIgnoreCase) ||
file.Artists.Contains(a, StringComparer.OrdinalIgnoreCase),
- { Title: string t } =>
+ { Title: { } t } =>
file.Title.StartsWith(t, StringComparison.InvariantCultureIgnoreCase),
_ => false
};
@@ -122,7 +122,7 @@ private static void PrintResults(
bgColor: null,
addLineBreak: true
);
- printer.Print(new LineSubString[] { titleArtistFormatted, separator, metadata });
+ printer.Print([titleArtistFormatted, separator, metadata]);
innerIndex++;
}
@@ -172,6 +172,7 @@ private static string RemoveSubstrings(string source, ICollection terms)
/// Creates a playlist list in M3U playlist format.
///
///
+ ///
/// Optionally replace parts of the file paths.
///
private static void CreatePlaylistFile(
diff --git a/src/AudioTagger.Console/Operations/TagGenreExtractor.cs b/src/AudioTagger.Console/Operations/TagGenreExtractor.cs
index 7479370..68d6556 100644
--- a/src/AudioTagger.Console/Operations/TagGenreExtractor.cs
+++ b/src/AudioTagger.Console/Operations/TagGenreExtractor.cs
@@ -19,8 +19,8 @@ private static string MostPopulousGenre(IGrouping group) =>
group
.Select(f => f.Genres.First())
.GroupBy(genre => genre)
- .OrderByDescending(group => group.Count())
- .Select(group => group.Key)
+ .OrderByDescending(g => g.Count())
+ .Select(g => g.Key)
.First() // Keep only the most populous genre.
.Trim();
@@ -86,12 +86,13 @@ public void Start(
WriteSummary(existingGenres.Count, mergedGenres.Count, printer);
- Result writeResult = GenreService.Write(settings.ArtistGenreCsvFilePath, mergedGenres);
+ var writeResult = GenreService.Write(settings.ArtistGenreCsvFilePath, mergedGenres);
if (writeResult.IsSuccess)
printer.Success($"Genres written to \"{settings.ArtistGenreCsvFilePath}\" in {watch.ElapsedFriendly}.");
else
printer.FirstError(writeResult, "Genre save error: ");
+ return;
static void WriteSummary(int beforeCount, int afterCount, IPrinter printer)
{
diff --git a/src/AudioTagger.Console/Operations/TagParser.cs b/src/AudioTagger.Console/Operations/TagParser.cs
index 0e36f63..8ca6fd7 100644
--- a/src/AudioTagger.Console/Operations/TagParser.cs
+++ b/src/AudioTagger.Console/Operations/TagParser.cs
@@ -12,7 +12,7 @@ public void Start(IReadOnlyCollection mediaFiles,
{
Watch watch = new();
- Regex regex = new("""(?<=[アルバム|シングル][『「]).+(?=[」』])"""); // Make class-level?
+ Regex regex = new("(?<=[アルバム|シングル][『「]).+(?=[」』])"); // Make class-level?
foreach (MediaFile mediaFile in mediaFiles)
{
diff --git a/src/AudioTagger.Console/Operations/TagRewriter.cs b/src/AudioTagger.Console/Operations/TagRewriter.cs
index 97ae7c2..5c5a55c 100644
--- a/src/AudioTagger.Console/Operations/TagRewriter.cs
+++ b/src/AudioTagger.Console/Operations/TagRewriter.cs
@@ -13,12 +13,13 @@ public void Start(
var watch = new Watch();
var failures = 0;
- Result result;
foreach (MediaFile file in mediaFiles)
{
- result = file.RewriteFileTags();
+ var result = file.RewriteFileTags();
+
if (result.IsFailed)
{
+ failures++;
printer.FirstError(result);
}
}
diff --git a/src/AudioTagger.Console/Operations/TagScanner.cs b/src/AudioTagger.Console/Operations/TagScanner.cs
index 21a636f..70e890e 100644
--- a/src/AudioTagger.Console/Operations/TagScanner.cs
+++ b/src/AudioTagger.Console/Operations/TagScanner.cs
@@ -15,8 +15,8 @@ public void Start(IReadOnlyCollection mediaFiles,
printer.Print($"Found {mediaFiles.Count} audio files.");
- Regex playlistUrlRegex = new("""(?<=Playlist URL: ).+""");
- Regex videoUrlRegex = new("""(?<=URL: ).+""");
+ Regex playlistUrlRegex = new("(?<=Playlist URL: ).+");
+ Regex videoUrlRegex = new("(?<=URL: ).+");
StringBuilder okFiles = new();
StringBuilder lowBitRateNoUrl = new();
@@ -31,14 +31,12 @@ public void Start(IReadOnlyCollection mediaFiles,
if (file.SampleRate >= 48_000)
{
if (file.Comments.HasText() &&
- playlistUrlRegex.Match(file.Comments) is Match playlistMatch &&
- playlistMatch.Success)
+ playlistUrlRegex.Match(file.Comments) is { Success: true } playlistMatch)
{
highSampleRateWithPlaylistUrl.AppendLine($"{playlistMatch.Value};{file.FileInfo}");
}
else if (file.Comments.HasText() &&
- videoUrlRegex.Match(file.Comments) is Match videoMatch &&
- videoMatch.Success)
+ videoUrlRegex.Match(file.Comments) is { Success: true } videoMatch)
{
highSampleRateWithVideoUrl.AppendLine($"{videoMatch.Value};{file.FileInfo}");
}
@@ -50,14 +48,12 @@ public void Start(IReadOnlyCollection mediaFiles,
else if (file.BitRate < 110)
{
if (file.Comments.HasText() &&
- playlistUrlRegex.Match(file.Comments) is Match playlistMatch &&
- playlistMatch.Success)
+ playlistUrlRegex.Match(file.Comments) is { Success: true } playlistMatch)
{
lowBitRateWithPlaylistUrl.AppendLine($"{playlistMatch.Value};{file.FileInfo}");
}
else if (file.Comments.HasText() &&
- videoUrlRegex.Match(file.Comments) is Match videoMatch &&
- videoMatch.Success)
+ videoUrlRegex.Match(file.Comments) is { Success: true } videoMatch)
{
lowBitRateWithVideoUrl.AppendLine($"{videoMatch.Value};{file.FileInfo}");
}
diff --git a/src/AudioTagger.Console/Operations/TagStats.cs b/src/AudioTagger.Console/Operations/TagStats.cs
index d484dbc..ba4cfe9 100644
--- a/src/AudioTagger.Console/Operations/TagStats.cs
+++ b/src/AudioTagger.Console/Operations/TagStats.cs
@@ -1,4 +1,3 @@
-using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
using AudioTagger.Library;
using Spectre.Console;
@@ -110,7 +109,7 @@ public void Start(
const int mostAlbumTracksCount = 30;
var mostAlbumTracks = mediaFiles
- .Where(m => m.AlbumArt is not null && m.AlbumArt.Length != 0)
+ .Where(m => m.AlbumArt.Length != 0)
.GroupBy(m => $"{m.ArtistSummary} / {m.Album}")
.ToDictionary(g => g.Key, m => m.Count())
.OrderByDescending(d => d.Value)
@@ -126,9 +125,9 @@ public void Start(
[Justify.Left, Justify.Left]);
- int largestEmbeddedAlbumArtCount = 50;
+ const int largestEmbeddedAlbumArtCount = 50;
var largestEmbeddedAlbumArt = mediaFiles
- .Where(m => m.AlbumArt is not null && m.AlbumArt.Length != 0)
+ .Where(m => m.AlbumArt.Length != 0)
.OrderByDescending(m => m.AlbumArt.Length)
.GroupBy(m => $"{m.ArtistSummary} / {m.Album}")
.ToDictionary(g => g.Key, m => (m.Sum(n => n.AlbumArt.Length), m.Count()))
@@ -141,13 +140,13 @@ public void Start(
largestEmbeddedAlbumArt.Select(r => new[] {
r.Key,
r.Value.Item1.ToString("#,##0"),
- r.Value.Item2.ToString("#,##0"),
+ r.Value.Item2.ToString("#,##0")
}).ToList(),
[Justify.Left, Justify.Right, Justify.Right]);
- int largestEmbeddedAlbumFilesCount = 50;
+ const int largestEmbeddedAlbumFilesCount = 50;
var largestEmbeddedAlbumFiles = mediaFiles
- .Where(m => m.AlbumArt is not null && m.AlbumArt.Length != 0)
+ .Where(m => m.AlbumArt.Length != 0)
.OrderByDescending(m => m.AlbumArt.Length)
.Take(largestEmbeddedAlbumFilesCount);
@@ -180,8 +179,7 @@ private static void PrintToTable(
throw new InvalidOperationException("Column names and row data must be provided.");
}
- if (columnNames.Count != rows[0].Length ||
- !rows.All(r => r.Length == columnNames.Count))
+ if (columnNames.Count != rows[0].Length || rows.Any(r => r.Length != columnNames.Count))
{
throw new InvalidOperationException("The counts of columns and rows must be identical.");
}
@@ -221,7 +219,7 @@ private static void PrintToTable(
AnsiConsole.Write(panel);
}
- class ArtistsComparer : IEqualityComparer
+ private class ArtistsComparer : IEqualityComparer
{
public bool Equals(string[]? x, string[]? y)
{
@@ -238,13 +236,13 @@ public bool Equals(string[]? x, string[]? y)
return ConcatenateArtists(x) == ConcatenateArtists(y);
}
- public int GetHashCode([DisallowNull] string[] obj)
+ public int GetHashCode(string[] obj)
{
// Not sure this is correct.
return string.Concat(obj).ToLower().GetHashCode();
}
- static string ConcatenateArtists(IEnumerable artists)
+ private static string ConcatenateArtists(IEnumerable artists)
{
return Regex.Replace(
string.Concat(artists)
@@ -267,7 +265,7 @@ public bool Equals(string? x, string? y)
};
}
- public int GetHashCode([DisallowNull] string obj)
+ public int GetHashCode(string obj)
{
return obj.ToLower().GetHashCode();
}
diff --git a/src/AudioTagger.Console/Operations/TagUpdater.cs b/src/AudioTagger.Console/Operations/TagUpdater.cs
index 4954d85..fe67fde 100644
--- a/src/AudioTagger.Console/Operations/TagUpdater.cs
+++ b/src/AudioTagger.Console/Operations/TagUpdater.cs
@@ -13,11 +13,10 @@ public void Start(
Settings settings,
IPrinter printer)
{
- bool cancelRequested = false;
bool doConfirm = true;
List errorFiles = [];
- var regexes = settings?.Tagging?.RegexPatterns;
+ var regexes = settings.Tagging?.RegexPatterns;
if (regexes?.Any() != true)
{
throw new InvalidOperationException("No tagging regexes found in settings! Cannot continue.");
@@ -30,11 +29,11 @@ public void Start(
{
try
{
- cancelRequested = UpdateTags(
+ var cancelRequested = UpdateTags(
mediaFile,
regexCollection,
printer,
- settings!,
+ settings,
ref doConfirm);
if (cancelRequested)
@@ -44,7 +43,6 @@ public void Start(
{
printer.Error($"Update error: {ex.Message}");
errorFiles.Add(mediaFile.FileNameOnly);
- continue;
}
}
@@ -83,7 +81,7 @@ private static bool UpdateTags(
.OfType()
.Where(g => g.Success);
- if (matchedTags?.Any() != true)
+ if (matchedTags.Any() != true)
{
printer.Print($"Could not parse data for filename \"{mediaFile.FileNameOnly}.\"",
ResultType.Failure);
@@ -128,7 +126,7 @@ private static bool UpdateTags(
string response = AnsiConsole.Prompt(
new SelectionPrompt()
.Title("Apply these updates?")
- .AddChoices([no, yes, yesToAll, cancel]));
+ .AddChoices(no, yes, yesToAll, cancel));
if (response == cancel)
{
diff --git a/src/AudioTagger.Console/Operations/TagUpdaterGenreOnly.cs b/src/AudioTagger.Console/Operations/TagUpdaterGenreOnly.cs
index 61bbd8a..7e2194c 100644
--- a/src/AudioTagger.Console/Operations/TagUpdaterGenreOnly.cs
+++ b/src/AudioTagger.Console/Operations/TagUpdaterGenreOnly.cs
@@ -34,7 +34,6 @@ public void Start(IReadOnlyCollection mediaFiles,
{
printer.Error($"Error updating {mediaFile.FileNameOnly}: {ex.Message}");
errorFiles.Add(mediaFile.FileNameOnly);
- continue;
}
}
@@ -62,14 +61,15 @@ private static void UpdateGenreTag(MediaFile mediaFile,
return;
}
- if (!artistsWithGenres.ContainsKey(artistName))
+ if (!artistsWithGenres.TryGetValue(artistName, out var genre))
{
printer.Print($"No registered genre found for artist \"{artistName}\", so skipping \"{mediaFile.FileNameOnly}\".",
fgColor: ConsoleColor.Gray);
+
return;
}
- if (mediaFile.Genres.FirstOrDefault() == artistsWithGenres[artistName])
+ if (mediaFile.Genres.FirstOrDefault() == genre)
{
printer.Print($"Genre is correct, so skipping \"{mediaFile.FileNameOnly}\".");
return;
@@ -97,8 +97,8 @@ private static void UpdateGenreTag(MediaFile mediaFile,
return;
}
- printer.Print($"Added \"{proposedUpdates["Genres"]}\" to '{mediaFile.FileNameOnly}'", 0, 0, fgColor: ConsoleColor.Green);
- return;
+ printer.Print($"Added \"{proposedUpdates["Genres"]}\" to '{mediaFile.FileNameOnly}'",
+ 0, 0, fgColor: ConsoleColor.Green);
}
///
diff --git a/src/AudioTagger.Console/Operations/TagUpdaterMultiple.cs b/src/AudioTagger.Console/Operations/TagUpdaterMultiple.cs
index 32bd9ea..cd08928 100644
--- a/src/AudioTagger.Console/Operations/TagUpdaterMultiple.cs
+++ b/src/AudioTagger.Console/Operations/TagUpdaterMultiple.cs
@@ -8,7 +8,7 @@ namespace AudioTagger.Console.Operations;
///
public sealed class TagUpdaterMultiple : IPathOperation
{
- private static readonly string _inputFile = "input.txt";
+ private const string InputFile = "input.txt";
private enum TagUpdateType { Overwrite, Prepend, Append }
@@ -26,11 +26,11 @@ public void Start(IReadOnlyCollection mediaFiles,
string[] inputLines;
try
{
- inputLines = File.ReadAllLines(_inputFile).Where(l => l.HasText()).ToArray();
+ inputLines = File.ReadAllLines(InputFile).Where(l => l.HasText()).ToArray();
}
catch (FileNotFoundException)
{
- printer.Error($"Could not find the file {_inputFile}");
+ printer.Error($"Could not find the file {InputFile}");
return;
}
catch (Exception ex)
@@ -98,7 +98,7 @@ public void Start(IReadOnlyCollection mediaFiles,
private static TagUpdateType ConfirmUpdateType(string tagName)
{
- if (tagName == "year" || tagName == "trackNo")
+ if (tagName is "year" or "trackNo")
{
return TagUpdateType.Overwrite;
}
@@ -125,7 +125,7 @@ private static string ConfirmUpdateTagName()
{"Genres", "genres"},
{"Year", "year"},
{"Comment", "comment"},
- {"Track No.", "trackNo"},
+ {"Track No.", "trackNo"}
};
string response = AnsiConsole.Prompt(
@@ -144,7 +144,7 @@ private static bool ConfirmContinue()
string shouldProceed = AnsiConsole.Prompt(
new SelectionPrompt()
.Title("[yellow]Do you want to continue?[/]")
- .AddChoices([no, yes]));
+ .AddChoices(no, yes));
return shouldProceed == yes;
}
@@ -183,7 +183,7 @@ private static void UpdateTags(MediaFile mediaFile,
case "albumArtists":
string[] sanitizedAlbumArtists = tagValue.Replace("___", " ")
.Replace("__", " ")
- .Split(new[] { ";" },
+ .Split([";"],
StringSplitOptions.RemoveEmptyEntries |
StringSplitOptions.TrimEntries)
.Select(a => a.Normalize())
@@ -195,7 +195,7 @@ private static void UpdateTags(MediaFile mediaFile,
case "artists":
string[] sanitizedArtists = tagValue.Replace("___", " ")
.Replace("__", " ")
- .Split(new[] { ";" },
+ .Split([";"],
StringSplitOptions.RemoveEmptyEntries |
StringSplitOptions.TrimEntries)
.Select(a => a.Normalize())
@@ -216,7 +216,7 @@ private static void UpdateTags(MediaFile mediaFile,
case "genres":
string[] sanitizedGenres = tagValue.Replace("___", " ")
.Replace("__", " ")
- .Split(new[] { ";" },
+ .Split([";"],
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.Select(g => g.Normalize())
.ToArray();
@@ -254,7 +254,7 @@ static string GetUpdatedValue(string currentValue, string newValue, TagUpdateTyp
{
TagUpdateType.Overwrite => newValue,
TagUpdateType.Prepend => newValue + divider + currentValue,
- _ => currentValue + divider + newValue,
+ _ => currentValue + divider + newValue
};
}
diff --git a/src/AudioTagger.Console/Operations/TagUpdaterReverseTrackNumbers.cs b/src/AudioTagger.Console/Operations/TagUpdaterReverseTrackNumbers.cs
index 36a2e02..f76a595 100644
--- a/src/AudioTagger.Console/Operations/TagUpdaterReverseTrackNumbers.cs
+++ b/src/AudioTagger.Console/Operations/TagUpdaterReverseTrackNumbers.cs
@@ -79,7 +79,7 @@ private static bool ConfirmContinue()
string shouldProceed = AnsiConsole.Prompt(
new SelectionPrompt()
.Title("[yellow]Do you want to continue?[/]")
- .AddChoices([no, yes]));
+ .AddChoices(no, yes));
return shouldProceed == yes;
}
diff --git a/src/AudioTagger.Console/Operations/TagUpdaterSingle.cs b/src/AudioTagger.Console/Operations/TagUpdaterSingle.cs
index c7fd507..390c1c1 100644
--- a/src/AudioTagger.Console/Operations/TagUpdaterSingle.cs
+++ b/src/AudioTagger.Console/Operations/TagUpdaterSingle.cs
@@ -76,7 +76,7 @@ private static string ConfirmTagValue(string tagName, TagUpdateType updateType)
private static TagUpdateType ConfirmUpdateType(string tagName)
{
- if (tagName == "year" || tagName == "trackNo")
+ if (tagName is "year" or "trackNo")
{
return TagUpdateType.Overwrite;
}
@@ -103,7 +103,7 @@ private static string ConfirmUpdateTagName()
{"Genres", "genres"},
{"Year", "year"},
{"Comment", "comment"},
- {"Track No.", "trackNo"},
+ {"Track No.", "trackNo"}
};
string response = AnsiConsole.Prompt(
@@ -122,7 +122,7 @@ private static bool ConfirmContinue()
string shouldProceed = AnsiConsole.Prompt(
new SelectionPrompt()
.Title("[yellow]Do you want to continue?[/]")
- .AddChoices([no, yes]));
+ .AddChoices(no, yes));
return shouldProceed == yes;
}
@@ -150,7 +150,7 @@ private static void UpdateTags(MediaFile mediaFile,
: tagValue.Replace("___", " ")
.Replace("__", " ")
.Split(
- new[] { ";" },
+ [";"],
StringSplitOptions.RemoveEmptyEntries |
StringSplitOptions.TrimEntries)
.Select(a => a.Normalize())
@@ -166,7 +166,7 @@ private static void UpdateTags(MediaFile mediaFile,
: tagValue.Replace("___", " ")
.Replace("__", " ")
.Split(
- new[] { ";" },
+ [";"],
StringSplitOptions.RemoveEmptyEntries |
StringSplitOptions.TrimEntries)
.Select(a => a.Normalize())
@@ -191,7 +191,7 @@ private static void UpdateTags(MediaFile mediaFile,
: tagValue.Replace("___", " ")
.Replace("__", " ")
.Split(
- new[] { ";" },
+ [";"],
StringSplitOptions.RemoveEmptyEntries |
StringSplitOptions.TrimEntries)
.Select(g => g.Normalize())
@@ -238,7 +238,7 @@ static string GetUpdatedValue(
{
TagUpdateType.Overwrite => newValue,
TagUpdateType.Prepend => newValue + divider + currentValue,
- _ => currentValue + divider + newValue,
+ _ => currentValue + divider + newValue
};
}
diff --git a/src/AudioTagger.Console/Operations/TagUpdaterYearOnly.cs b/src/AudioTagger.Console/Operations/TagUpdaterYearOnly.cs
index fbeedb8..7938bfe 100644
--- a/src/AudioTagger.Console/Operations/TagUpdaterYearOnly.cs
+++ b/src/AudioTagger.Console/Operations/TagUpdaterYearOnly.cs
@@ -10,7 +10,6 @@ public void Start(IReadOnlyCollection mediaFiles,
Settings settings,
IPrinter printer)
{
- var isCancelled = false;
var doConfirm = true;
var errorFiles = new List();
@@ -18,7 +17,7 @@ public void Start(IReadOnlyCollection mediaFiles,
{
try
{
- isCancelled = UpdateTags(mediaFile, printer, ref doConfirm);
+ var isCancelled = UpdateTags(mediaFile, printer, ref doConfirm);
if (isCancelled)
break;
@@ -28,7 +27,6 @@ public void Start(IReadOnlyCollection mediaFiles,
printer.Error($"Error updating {mediaFile.FileNameOnly}: {ex.Message}");
//printer.PrintException(ex);
errorFiles.Add(mediaFile.FileNameOnly);
- continue;
}
}
@@ -53,7 +51,7 @@ private static bool UpdateTags(MediaFile mediaFile, IPrinter printer, ref bool d
var updateableFields = new UpdatableFields(updateType, createdYear);
var proposedUpdates = updateableFields.GetUpdateKeyValuePairs(mediaFile);
- if (proposedUpdates?.Any() != true)
+ if (proposedUpdates.Any() != true)
{
printer.Print($"No {updateType} updates needed for \"{mediaFile.FileNameOnly}\".",
ResultType.Neutral);
@@ -72,7 +70,7 @@ private static bool UpdateTags(MediaFile mediaFile, IPrinter printer, ref bool d
string response = AnsiConsole.Prompt(
new SelectionPrompt()
.Title("Apply these updates?")
- .AddChoices([no, yes, yesToAll, cancel]));
+ .AddChoices(no, yes, yesToAll, cancel));
if (response == cancel)
{
diff --git a/src/AudioTagger.Console/Operations/TagViewer.cs b/src/AudioTagger.Console/Operations/TagViewer.cs
index 0dafb36..f6abe36 100644
--- a/src/AudioTagger.Console/Operations/TagViewer.cs
+++ b/src/AudioTagger.Console/Operations/TagViewer.cs
@@ -27,12 +27,10 @@ public void Start(IReadOnlyCollection mediaFiles,
catch (TagLib.CorruptFileException e)
{
printer.Error("The file's tag metadata was corrupt: " + e.Message);
- continue;
}
catch (Exception e)
{
printer.Error($"An unexpected error occurred with file {mediaFile.FileNameOnly}: " + e.Message);
- continue;
}
}
}
diff --git a/src/AudioTagger.Console/Operations/TagViewerSummary.cs b/src/AudioTagger.Console/Operations/TagViewerSummary.cs
index 16a3b8e..7a2b811 100644
--- a/src/AudioTagger.Console/Operations/TagViewerSummary.cs
+++ b/src/AudioTagger.Console/Operations/TagViewerSummary.cs
@@ -13,16 +13,14 @@ public void Start(IReadOnlyCollection mediaFiles,
ArgumentNullException.ThrowIfNull(mediaFiles);
var orderedFiles = mediaFiles
- .OrderBy(m => {
- return string.Concat(
- m.AlbumArtists?.Any() == true
+ .OrderBy(m => string.Concat(
+ m.AlbumArtists.Any()
? m.AlbumArtists
- : m.Artists?.Any() == true
+ : m.Artists.Any()
? m.Artists
: []
- );
- })
- .ThenBy(m => m.Album ?? string.Empty)
+ ))
+ .ThenBy(m => m.Album)
.ThenBy(m => m.TrackNo)
.ThenBy(m => m.Title)
.ToImmutableArray();
diff --git a/src/AudioTagger.Console/Program.cs b/src/AudioTagger.Console/Program.cs
index f9b9110..ab8f978 100644
--- a/src/AudioTagger.Console/Program.cs
+++ b/src/AudioTagger.Console/Program.cs
@@ -37,8 +37,8 @@ private static void Run(string[] args, IPrinter printer)
Settings settings = readSettingsResult.Value;
// Prefer ID3 v2.3 over v2.4 because the former is apparently more widely supported.
- SettingsService.SetId3v2Version(
- version: SettingsService.Id3v2Version.TwoPoint3,
+ SettingsService.SetId3V2Version(
+ version: SettingsService.Id3V2Version.TwoPoint3,
forceAsDefault: true);
var operationArgs = args.TakeWhile(a => a.StartsWith('-')).ToImmutableArray();
@@ -89,7 +89,7 @@ private static void ProcessPath(
Watch watch = new();
- var fileNameResult = IOUtilities.GetAllFileNames(path, searchSubDirectories: true);
+ var fileNameResult = IoUtilities.GetAllFileNames(path, searchSubDirectories: true);
if (fileNameResult.IsFailed)
{
printer.FirstError(fileNameResult, "Error reading filenames for path \"{path}\":");
@@ -114,10 +114,12 @@ private static void ProcessPath(
{
printer.Warning($"Tags could not be read for {tagReadErrors.Count} file(s).");
- int showCount = 10;
+ const int showCount = 10;
tagReadErrors.Take(showCount).ToList().ForEach(printer.Error);
if (tagReadErrors.Count > showCount)
+ {
printer.Error($"plus {tagReadErrors.Count - showCount} more errors...");
+ }
}
try
@@ -131,7 +133,6 @@ private static void ProcessPath(
{
printer.Error($"Error in while processing path \"{path}\": {ex.Message}");
printer.PrintException(ex);
- return;
}
}
@@ -143,14 +144,12 @@ private static (List, List) ReadTagsShowingProgress(
AnsiConsole.Progress()
.AutoClear(true)
- .Columns(new ProgressColumn[]
- {
+ .Columns(
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn(),
new RemainingTimeColumn(),
- new SpinnerColumn(),
- })
+ new SpinnerColumn())
.Start(ctx =>
{
var task = ctx.AddTask("Reading tag data", maxValue: fileNames.Count);
@@ -214,7 +213,7 @@ private static void PrintInstructions(IPrinter printer)
private static (ImmutableList Valid, ImmutableList Invalid) CheckPaths(
ICollection paths)
{
- if (paths?.Any() != true)
+ if (paths.Any() != true)
{
return new ([], []);
}
diff --git a/src/AudioTagger.Console/SpectrePrinter.cs b/src/AudioTagger.Console/SpectrePrinter.cs
index 0a5da8e..ad35b3c 100644
--- a/src/AudioTagger.Console/SpectrePrinter.cs
+++ b/src/AudioTagger.Console/SpectrePrinter.cs
@@ -61,11 +61,12 @@ public void Print(IEnumerable lineParts,
foreach (LineSubString linePart in lineParts)
{
var subString = new LineSubString(linePart.Text, linePart.FgColor, linePart.BgColor).GetSpectreString();
+
if (linePart.AddLineBreak)
AnsiConsole.MarkupLine(subString);
else
AnsiConsole.Markup(subString);
- };
+ }
PrintEmptyLines(appendLines);
}
@@ -98,7 +99,7 @@ public void Print(IEnumerable lines,
public void FirstError(IResultBase failResult, string? prepend = null)
{
string pre = prepend is null ? string.Empty : $"{prepend} ";
- string message = failResult?.Errors?.FirstOrDefault()?.Message ?? string.Empty;
+ string message = failResult.Errors?.FirstOrDefault()?.Message ?? string.Empty;
Error($"{pre}{message}");
}
diff --git a/src/AudioTagger.Console/Usings.cs b/src/AudioTagger.Console/Usings.cs
index 4fd2184..8cf013f 100644
--- a/src/AudioTagger.Console/Usings.cs
+++ b/src/AudioTagger.Console/Usings.cs
@@ -2,7 +2,6 @@
global using System.Linq;
global using System.Collections.Generic;
global using System.Collections.Immutable;
-global using System.Collections.Frozen;
global using System.IO;
global using AudioTagger.Library.MediaFiles;
global using AudioTagger.Library.UserSettings;
diff --git a/src/AudioTagger.Library/Genres/GenreService.cs b/src/AudioTagger.Library/Genres/GenreService.cs
index 153f760..2974c0f 100644
--- a/src/AudioTagger.Library/Genres/GenreService.cs
+++ b/src/AudioTagger.Library/Genres/GenreService.cs
@@ -38,7 +38,7 @@ public static Result> Read(string? genreFileName)
{
if (genreFileName is null)
{
- return Result.Fail($"No artist-genre file name was passed.");
+ return Result.Fail("No artist-genre file name was passed.");
}
Dictionary artistsWithGenres = [];
diff --git a/src/AudioTagger.Library/IOUtilities.cs b/src/AudioTagger.Library/IOUtilities.cs
index 1582f5f..f597b48 100644
--- a/src/AudioTagger.Library/IOUtilities.cs
+++ b/src/AudioTagger.Library/IOUtilities.cs
@@ -3,7 +3,7 @@
namespace AudioTagger.Library;
-public static class IOUtilities
+public static class IoUtilities
{
private static readonly List SupportedExtensions =
[".mp3", ".ogg", ".mkv", ".mp4", ".m4a", ".opus"];
@@ -14,13 +14,12 @@ public static class IOUtilities
private static readonly char[] UnsafePathChars =
[':', '?', '/', '⧸', '"', '|', '*'];
- public static readonly Func IsSupportedFileExtension =
- new(
- fileName =>
- fileName.HasText() &&
- !fileName.StartsWith(".") && // Unix-based OS hidden files
- SupportedExtensions.Any(ext =>
- fileName.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase)));
+ private static readonly Func IsSupportedFileExtension =
+ fileName =>
+ fileName.HasText() &&
+ !fileName.StartsWith(".") && // Unix-based OS hidden files
+ SupportedExtensions.Any(ext =>
+ fileName.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase));
public static Result> GetAllFileNames(string path, bool searchSubDirectories)
{
@@ -42,7 +41,7 @@ public static Result> GetAllFileNames(string path, bool s
if (System.IO.File.Exists(path))
{
- var file = new string[] { path }.ToImmutableArray();
+ var file = new[] { path }.ToImmutableArray();
return Result.Ok(file);
}
diff --git a/src/AudioTagger.Library/LineSubstring.cs b/src/AudioTagger.Library/LineSubstring.cs
index 326ed71..b8e458d 100644
--- a/src/AudioTagger.Library/LineSubstring.cs
+++ b/src/AudioTagger.Library/LineSubstring.cs
@@ -6,10 +6,10 @@ public sealed class LineSubString(
ConsoleColor? bgColor = null,
bool addLineBreak = false)
{
- public string Text { get; set; } = text;
- public ConsoleColor? FgColor { get; set; } = fgColor;
- public ConsoleColor? BgColor { get; set; } = bgColor;
- public bool AddLineBreak { get; set; } = addLineBreak;
+ public string Text { get; } = text;
+ public ConsoleColor? FgColor { get; } = fgColor;
+ public ConsoleColor? BgColor { get; } = bgColor;
+ public bool AddLineBreak { get; } = addLineBreak;
public string GetSpectreString()
{
diff --git a/src/AudioTagger.Library/MediaFiles/MediaFile.cs b/src/AudioTagger.Library/MediaFiles/MediaFile.cs
index fd5bd05..13aa141 100644
--- a/src/AudioTagger.Library/MediaFiles/MediaFile.cs
+++ b/src/AudioTagger.Library/MediaFiles/MediaFile.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System.Globalization;
+using System.IO;
using FluentResults;
namespace AudioTagger.Library.MediaFiles;
@@ -47,7 +48,7 @@ public string[] Artists
{
get => _taggedFile.Tag.Performers?.Select(a => a?.Normalize() ?? string.Empty)
.ToArray()
- ?? Array.Empty();
+ ?? [];
set => _taggedFile.Tag.Performers =
value.Where(a => a.HasText())
@@ -64,7 +65,7 @@ public string[] Artists
public string Album
{
get => _taggedFile.Tag.Album?.Normalize() ?? string.Empty;
- set => _taggedFile.Tag.Album = value?.Trim()?.Normalize();
+ set => _taggedFile.Tag.Album = value.Trim().Normalize();
}
public bool LacksArtists => AlbumArtists.Length == 0 && Artists.Length == 0;
@@ -81,50 +82,41 @@ public uint TrackNo
set => _taggedFile.Tag.Track = value;
}
- public TimeSpan Duration
- {
- get => _taggedFile.Properties.Duration;
- }
+ public TimeSpan Duration => _taggedFile.Properties.Duration;
public string[] Genres
{
get => _taggedFile.Tag.Genres;
// TODO: Add first genre tag too?
- set => _taggedFile.Tag.Genres = value?.Select(g => g?.Trim()?.Normalize()
- ?? string.Empty)?
- .ToArray()
- ?? Array.Empty();
+ set => _taggedFile.Tag.Genres = value.Select(g => g.Trim().Normalize()).ToArray();
}
public string[] Composers
{
- get => _taggedFile.Tag.Composers?.Select(c => c?.Trim()?.Normalize()
- ?? string.Empty)?
+ get => _taggedFile.Tag.Composers?.Select(c => c?.Trim().Normalize()
+ ?? string.Empty)
.ToArray()
- ?? Array.Empty();
+ ?? [];
- set => _taggedFile.Tag.Composers = value?.Select(g => g?.Trim()?
- .Normalize())?
- .ToArray()
- ?? Array.Empty();
+ set => _taggedFile.Tag.Composers = value.Select(g => g.Trim().Normalize()).ToArray();
}
public string Lyrics
{
- get => _taggedFile.Tag.Lyrics?.Trim()?.Normalize() ?? string.Empty;
+ get => _taggedFile.Tag.Lyrics?.Trim().Normalize() ?? string.Empty;
set => _taggedFile.Tag.Lyrics = value.Trim().Normalize();
}
public string Comments
{
- get => _taggedFile.Tag.Comment?.Trim()?.Normalize() ?? string.Empty;
+ get => _taggedFile.Tag.Comment?.Trim().Normalize() ?? string.Empty;
set => _taggedFile.Tag.Comment = value.Trim().Normalize();
}
public string Description
{
- get => _taggedFile.Tag.Description?.Trim()?.Normalize() ?? string.Empty;
+ get => _taggedFile.Tag.Description?.Trim().Normalize() ?? string.Empty;
set => _taggedFile.Tag.Description = value.Trim().Normalize();
}
@@ -142,8 +134,12 @@ public string Description
public string ReplayGainSummary()
{
const string noData = "———";
- string trackGain = double.IsNaN(ReplayGainTrack) ? noData : ReplayGainTrack.ToString();
- string albumGain = double.IsNaN(ReplayGainAlbum) ? noData : ReplayGainAlbum.ToString();
+ string trackGain = double.IsNaN(ReplayGainTrack)
+ ? noData
+ : ReplayGainTrack.ToString(CultureInfo.InvariantCulture);
+ string albumGain = double.IsNaN(ReplayGainAlbum)
+ ? noData
+ : ReplayGainAlbum.ToString(CultureInfo.InvariantCulture);
return $"Track: {trackGain} | Album: {albumGain}";
}
@@ -160,9 +156,8 @@ public byte[] AlbumArt
var albumData = _taggedFile.Tag?.Pictures;
return albumData == null || albumData.Length == 0
- ? Array.Empty()
- : _taggedFile.Tag?.Pictures[0]?.Data?.Data
- ?? Array.Empty();
+ ? []
+ : _taggedFile.Tag?.Pictures[0]?.Data?.Data ?? [];
}
}
@@ -269,17 +264,17 @@ public ImmutableList PopulatedTagNames()
{
List tags = [];
- if (HasAnyValues(this.AlbumArtists))
+ if (HasAnyValues(AlbumArtists))
tags.Add("ALBUMARTISTS");
- if (HasAnyValues(this.Artists))
+ if (HasAnyValues(Artists))
tags.Add("ARTISTS");
- if (this.Album.HasText())
+ if (Album.HasText())
tags.Add("ALBUM");
- if (this.Title.HasText())
+ if (Title.HasText())
tags.Add("TITLE");
- if (this.Year != 0)
+ if (Year != 0)
tags.Add("YEAR");
- if (this.TrackNo != 0)
+ if (TrackNo != 0)
tags.Add("TRACK");
return [.. tags];
@@ -290,7 +285,7 @@ public ImmutableList PopulatedTagNames()
///
public static bool HasAnyValues(IEnumerable tagValues)
{
- if (tagValues?.Any() != true)
+ if (tagValues.Any() != true)
{
return false;
}
diff --git a/src/AudioTagger.Library/MediaFiles/MediaFileExtensionMethods.cs b/src/AudioTagger.Library/MediaFiles/MediaFileExtensionMethods.cs
index a959c36..eb80b65 100644
--- a/src/AudioTagger.Library/MediaFiles/MediaFileExtensionMethods.cs
+++ b/src/AudioTagger.Library/MediaFiles/MediaFileExtensionMethods.cs
@@ -10,9 +10,7 @@ public static class MediaFileExtensionMethods
/// A joined string. Never returns null.
public static string Join(this IEnumerable collection, string separator = "; ")
{
- return collection is null
- ? string.Empty
- : string.Join(separator, collection);
+ return string.Join(separator, collection);
}
///
@@ -25,21 +23,18 @@ public static class MediaFileExtensionMethods
/// A combined string. Never returns null. Example: "first1; first2 (second1; second2)"
public static string JoinWith(this IEnumerable first, IEnumerable second, string separator = "; ")
{
- if (first is null && second is null)
- return string.Empty;
-
- string joinerFunc(IEnumerable collection) => string.Join(separator, collection);
+ string Joiner(IEnumerable collection) => string.Join(separator, collection);
if (first?.Any() != true)
- return joinerFunc(second);
+ return Joiner(second);
if (second?.Any() != true)
- return joinerFunc(first);
+ return Joiner(first);
if (first.Count() != second.Count())
- return $"{joinerFunc(first)} ({joinerFunc(second)})";
+ return $"{Joiner(first)} ({Joiner(second)})";
- return joinerFunc(first); // Identical collections of equal length, so only print the first.
+ return Joiner(first); // Identical collections of equal length, so only print the first.
}
///
@@ -65,7 +60,7 @@ static string Format(IList artists, string separator) =>
&& primary.Count == secondary.Count
=> $"{Format(primary, separator)}",
([..], [..]) => $"{Format(primary, separator)} ({Format(secondary, separator)})",
- _ => string.Empty,
+ _ => string.Empty
};
}
}
diff --git a/src/AudioTagger.Library/OutputLine.cs b/src/AudioTagger.Library/OutputLine.cs
index f061b4d..48ac7c8 100644
--- a/src/AudioTagger.Library/OutputLine.cs
+++ b/src/AudioTagger.Library/OutputLine.cs
@@ -4,9 +4,9 @@ namespace AudioTagger.Library;
public sealed class OutputLine
{
- public List Line { get; set; } = [];
+ public List Line { get; } = [];
- public OutputLine() { }
+ private OutputLine() { }
public OutputLine(LineSubString lineParts)
{
@@ -94,7 +94,7 @@ public static IList GetTagPrintedLines(MediaFile fileData)
new(fileData.ReplayGainSummary())
}));
- if (fileData.Composers?.Length > 0)
+ if (fileData.Composers.Length > 0)
lines.Add(TagDataWithHeader("Composers", fileData.Composers.Join()));
if (fileData.Comments.HasText())
@@ -129,7 +129,7 @@ public static Dictionary GetTagKeyValuePairs(
"Quality",
$"{bitrate}kbps" + separator + $"{sampleRate} kHz" + separator + fileData.ReplayGainSummary());
- if (fileData.Composers?.Length > 0)
+ if (fileData.Composers.Length > 0)
lines.Add("Composers", string.Join("; ", fileData.Composers));
if (includeComments && fileData.Comments.HasText())
diff --git a/src/AudioTagger.Library/RegexCollection.cs b/src/AudioTagger.Library/RegexCollection.cs
index ec390f7..8dcdb49 100644
--- a/src/AudioTagger.Library/RegexCollection.cs
+++ b/src/AudioTagger.Library/RegexCollection.cs
@@ -2,7 +2,7 @@
namespace AudioTagger.Library;
-public sealed record class RegexCollection
+public sealed record RegexCollection
{
///
/// The regexes used for reading tags from names.
@@ -36,16 +36,10 @@ public static class RegexCollectionExtensionMethods
public static Match? GetFirstMatch(this RegexCollection regexes,
string fileName)
{
- foreach (string pattern in regexes.Patterns)
- {
- Match match = Regex.Match(fileName, pattern, RegexOptions.CultureInvariant);
-
- if (match.Success)
- {
- return match;
- }
- }
-
- return null;
+ return
+ regexes.Patterns
+ .Select(pattern =>
+ Regex.Match(fileName, pattern, RegexOptions.CultureInvariant))
+ .FirstOrDefault(match => match.Success);
}
}
diff --git a/src/AudioTagger.Library/Results.cs b/src/AudioTagger.Library/Results.cs
index b54ed57..c86fd76 100644
--- a/src/AudioTagger.Library/Results.cs
+++ b/src/AudioTagger.Library/Results.cs
@@ -20,6 +20,6 @@ public static class ResultsMap
{ ResultType.Success, new(ConsoleColor.DarkGreen, "✔︎ ")},
{ ResultType.Failure, new(ConsoleColor.DarkRed, "× ")},
{ ResultType.Cancelled, new(ConsoleColor.DarkRed, "* ")},
- { ResultType.Unknown, new(ConsoleColor.Blue, "? ")},
+ { ResultType.Unknown, new(ConsoleColor.Blue, "? ")}
};
}
diff --git a/src/AudioTagger.Library/UpdatableFields.cs b/src/AudioTagger.Library/UpdatableFields.cs
index 97ad3ee..96838fd 100644
--- a/src/AudioTagger.Library/UpdatableFields.cs
+++ b/src/AudioTagger.Library/UpdatableFields.cs
@@ -14,7 +14,7 @@ public sealed class UpdatableFields
public uint? TrackNo { get; }
public string[]? Genres { get; }
- public byte Count { get; }
+ private byte Count { get; }
///
/// Constructor that reads matched regex group names and
@@ -42,7 +42,7 @@ public UpdatableFields(
AlbumArtists = element.Value
.Replace("___", " ")
.Replace("__", " ")
- .Split(new[] { ";" },
+ .Split([";"],
StringSplitOptions.RemoveEmptyEntries |
StringSplitOptions.TrimEntries)
.Select(a => a.Normalize())
@@ -53,7 +53,7 @@ public UpdatableFields(
{
Artists = element.Value.Replace("___", " ")
.Replace("__", " ")
- .Split(new[] { ";" },
+ .Split([";"],
StringSplitOptions.RemoveEmptyEntries |
StringSplitOptions.TrimEntries)
.Select(a => a.Normalize())
@@ -71,7 +71,7 @@ public UpdatableFields(
{
Genres = element.Value.Replace("___", " ")
.Replace("__", " ")
- .Split(new[] { ";" },
+ .Split([";"],
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.Select(g => g.Normalize())
.ToArray();
@@ -92,7 +92,7 @@ public UpdatableFields(
// If no genre was manually passed in, check the settings for a registered one.
if (Genres?.Any() != true &&
Artists?.Any() == true &&
- artistsWithGenres?.Any() == true)
+ artistsWithGenres.Any())
{
if (artistsWithGenres.Any() &&
artistsWithGenres.ContainsKey(Artists[0]))
diff --git a/src/AudioTagger.Library/UserSettings/Settings.cs b/src/AudioTagger.Library/UserSettings/Settings.cs
index 0f138af..5363b91 100644
--- a/src/AudioTagger.Library/UserSettings/Settings.cs
+++ b/src/AudioTagger.Library/UserSettings/Settings.cs
@@ -5,22 +5,22 @@ namespace AudioTagger.Library.UserSettings;
public sealed record Settings
{
[JsonPropertyName("duplicates")]
- public Duplicates Duplicates { get; set; } = new();
+ public Duplicates Duplicates { get; init; } = new();
[JsonPropertyName("tagging")]
- public Tagging? Tagging { get; set; }
+ public Tagging? Tagging { get; init; }
[JsonPropertyName("renaming")]
- public Renaming? Renaming { get; set; }
+ public Renaming? Renaming { get; init; }
[JsonPropertyName("artistGenreCsvFilePath")]
- public string? ArtistGenreCsvFilePath { get; set; } = null;
+ public string? ArtistGenreCsvFilePath { get; init; }
[JsonPropertyName("resetSavedArtistGenres")]
- public bool ResetSavedArtistGenres { get; set; } = false;
+ public bool ResetSavedArtistGenres { get; init; }
[JsonPropertyName("tagCacheFilePath")]
- public string? TagCacheFilePath { get; set; }
+ public string? TagCacheFilePath { get; init; }
}
///
@@ -34,7 +34,7 @@ public sealed record Duplicates
/// "The Beatles" and "Beatles" would be recognized as the same artist.
///
[JsonPropertyName("titleReplacements")]
- public ImmutableList? TitleReplacements { get; set; }
+ public ImmutableList? TitleReplacements { get; init; }
///
/// A collection of substrings that should be ignored when searching for
@@ -42,7 +42,7 @@ public sealed record Duplicates
/// "TrackTitle" and "TrackTitle (Remix)" would be considered identical.
///
[JsonPropertyName("artistReplacements")]
- public ImmutableList? ArtistReplacements { get; set; }
+ public ImmutableList? ArtistReplacements { get; init; }
///
/// When creating a playlist file, search for this substring in
@@ -50,26 +50,26 @@ public sealed record Duplicates
/// with the string specified in the `PathReplaceWith` property).
///
[JsonPropertyName("pathSearchFor")]
- public string? PathSearchFor { get; set; }
+ public string? PathSearchFor { get; init; }
///
/// When creating a playlist of duplicate tracks, replace the matched
/// path substring from the `PathSearchFor` property with this text.
///
[JsonPropertyName("pathReplaceWith")]
- public string? PathReplaceWith { get; set; }
+ public string? PathReplaceWith { get; init; }
///
/// The directory to which the playlist of duplicates should be saved.
///
[JsonPropertyName("savePlaylistDirectory")]
- public string? SavePlaylistDirectory { get; set; }
+ public string? SavePlaylistDirectory { get; init; }
///
/// Track metadata that should be ignored when searching for duplicates.
///
[JsonPropertyName("exclusions")]
- public ImmutableList? Exclusions { get; set; }
+ public ImmutableList? Exclusions { get; init; }
}
///
@@ -94,11 +94,11 @@ public sealed record Tagging
public sealed record Renaming
{
[JsonPropertyName("patterns")]
- public ImmutableList? Patterns { get; set; }
+ public ImmutableList? Patterns { get; }
[JsonPropertyName("useAlbumDirectories")]
- public bool UseAlbumDirectories { get; set; } = false;
+ public bool UseAlbumDirectories { get; } = false;
[JsonPropertyName("ignoredDirectories")]
- public ImmutableList? IgnoredDirectories { get; set; }
+ public ImmutableList? IgnoredDirectories { get; }
}
diff --git a/src/AudioTagger.Library/UserSettings/SettingsService.cs b/src/AudioTagger.Library/UserSettings/SettingsService.cs
index 7d580bf..aceba3b 100644
--- a/src/AudioTagger.Library/UserSettings/SettingsService.cs
+++ b/src/AudioTagger.Library/UserSettings/SettingsService.cs
@@ -6,16 +6,16 @@ namespace AudioTagger.Library.UserSettings;
public static class SettingsService
{
- private const string _settingsFileName = "settings.json";
+ private const string SettingsFileName = "settings.json";
///
/// Subversions of ID3 version 2 (such as 2.3 or 2.4).
///
- public enum Id3v2Version : byte
+ public enum Id3V2Version : byte
{
TwoPoint2 = 2,
TwoPoint3 = 3,
- TwoPoint4 = 4,
+ TwoPoint4 = 4
}
///
@@ -26,7 +26,7 @@ public enum Id3v2Version : byte
/// When true, forces the specified version when writing the file.
/// When false, will defer to the version within the file, if any.
///
- public static void SetId3v2Version(Id3v2Version version, bool forceAsDefault)
+ public static void SetId3V2Version(Id3V2Version version, bool forceAsDefault)
{
TagLib.Id3v2.Tag.DefaultVersion = (byte)version;
TagLib.Id3v2.Tag.ForceDefaultVersion = forceAsDefault;
@@ -39,7 +39,7 @@ public static void SetId3v2Version(Id3v2Version version, bool forceAsDefault)
/// A bool indicating success or no action (true) or else failure (false).
public static bool CreateIfMissing(IPrinter printer)
{
- if (File.Exists(_settingsFileName))
+ if (File.Exists(SettingsFileName))
{
return true;
}
@@ -50,7 +50,7 @@ public static bool CreateIfMissing(IPrinter printer)
}
catch (Exception ex)
{
- printer.Error($"There was an error creating \"{_settingsFileName}\": {ex.Message}");
+ printer.Error($"There was an error creating \"{SettingsFileName}\": {ex.Message}");
return false;
}
}
@@ -64,10 +64,10 @@ public static Result Read(IPrinter printer, bool createFileIfMissing =
{
if (createFileIfMissing && !CreateIfMissing(printer))
{
- return Result.Fail($"Settings file \"{_settingsFileName}\" missing.");
+ return Result.Fail($"Settings file \"{SettingsFileName}\" missing.");
}
- string text = File.ReadAllText(_settingsFileName);
+ string text = File.ReadAllText(SettingsFileName);
Settings json = JsonSerializer.Deserialize(text)
?? throw new JsonException();
return Result.Ok(json);
@@ -96,12 +96,12 @@ public static bool Write(Settings settings, IPrinter printer)
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(
System.Text.Unicode.UnicodeRanges.All)
});
- File.WriteAllText(_settingsFileName, json);
+ File.WriteAllText(SettingsFileName, json);
return true;
}
catch (FileNotFoundException)
{
- printer.Error($"Settings file \"{_settingsFileName}\" is missing.");
+ printer.Error($"Settings file \"{SettingsFileName}\" is missing.");
return false;
}
catch (JsonException ex)
diff --git a/src/AudioTagger.Tests/MediaFileTests.cs b/src/AudioTagger.Tests/MediaFileTests.cs
index fc70ab3..3e006c9 100644
--- a/src/AudioTagger.Tests/MediaFileTests.cs
+++ b/src/AudioTagger.Tests/MediaFileTests.cs
@@ -7,14 +7,14 @@ public sealed class MediaFileTests
{
public sealed class ArtistSummary
{
- private static readonly string Separator = "; ";
+ private const string Separator = "; ";
[Fact]
public void ContainsAllArtists_ReturnsExpectedString()
{
string[] albumArtists = ["Album Artist A"];
string[] artists = ["Artist 1", "Artist 2"];
- string expected = "Album Artist A (Artist 1; Artist 2)";
+ const string expected = "Album Artist A (Artist 1; Artist 2)";
string actual = albumArtists.JoinWith(artists, Separator);
Assert.Equal(expected, actual);
}
@@ -24,7 +24,7 @@ public void ContainsOnlyAlbumArtists_ReturnsExpectedString()
{
string[] albumArtists = ["Album Artist"];
string[] artists = [];
- string expected = "Album Artist";
+ const string expected = "Album Artist";
string actual = albumArtists.JoinWith(artists, Separator);
Assert.Equal(expected, actual);
}
@@ -34,7 +34,7 @@ public void ContainsOnlyTrackArtists_ReturnsExpectedString()
{
string[] albumArtists = [];
string[] artists = ["Artist 1", "Artist 2"];
- string expected = "Artist 1; Artist 2";
+ const string expected = "Artist 1; Artist 2";
string actual = albumArtists.JoinWith(artists, Separator);
Assert.Equal(expected, actual);
}
diff --git a/src/AudioTagger.sln.DotSettings b/src/AudioTagger.sln.DotSettings
new file mode 100644
index 0000000..9744a58
--- /dev/null
+++ b/src/AudioTagger.sln.DotSettings
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file