Skip to content
Merged

dev #126

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
08113a8
Misc: Simplify OsuCollection
Piotrekol Nov 12, 2025
9e2c510
Fix: collection map removal performance
Piotrekol Nov 12, 2025
fb4ae06
Misc: Allow for multiple collection actions in one batch
Piotrekol Nov 12, 2025
2662fa3
Fix: collection map pull mapset performance
Piotrekol Nov 12, 2025
6c5fc70
Misc: Do not allow for empty collection names
Piotrekol Nov 12, 2025
bfb8381
Misc: Replace reflection form shenanigans with DI
Piotrekol Nov 15, 2025
2fac5b8
Add: Single file publish configuration
Piotrekol Nov 15, 2025
aa1a768
Fix: Single file publish version check
Piotrekol Nov 15, 2025
25e2c4f
Fix: Download configuration failing to load
Piotrekol Nov 15, 2025
9ee4ea9
Fix: File cache not dling to temp path
Piotrekol Jan 10, 2026
dc870eb
Fix: Handle beatmaps with no audio
Piotrekol Jan 10, 2026
3d9efbe
Misc: Split db/osdb collection save actions
Piotrekol Jan 17, 2026
87a322d
Misc: Cleanup default collection save messages
Piotrekol Jan 17, 2026
2c12fd3
Fix: Handling of file backgrounds
Piotrekol Jan 17, 2026
016a4e4
Add: Internal Read/Write osu!.db support
Piotrekol Jul 13, 2025
b17b853
Fix: copy as urls not working with unsubmitted maps
Piotrekol Jan 17, 2026
e31c204
Add: Option to open selected map in osu via direct
Piotrekol Jan 17, 2026
7744167
Add: Ability to suppress ok message boxes; auto-focus osu! when map c…
Piotrekol Jan 17, 2026
77d6b92
Add: Restore CLI
Piotrekol Feb 12, 2026
acfea9b
Misc: osu path detection adjustments
Piotrekol Feb 12, 2026
fd7def7
Misc: Github workflow
Piotrekol Feb 12, 2026
3d50439
Misc: CLI cleanup
Piotrekol Feb 14, 2026
b038cde
Add: CLI generate command
Piotrekol Feb 15, 2026
90f7945
Fix: Version not fully visible on main window
Piotrekol Feb 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ dotnet_naming_style.begins_with_i.capitalization = pascal_case

# CA1716: Identifiers should not match keywords
dotnet_diagnostic.CA1716.severity = none
dotnet_code_quality.CA1826.exclude_ordefault_methods = true

[*.{cs,vb}]
dotnet_style_object_initializer = true:suggestion
Expand Down
66 changes: 66 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: CI

on:
pull_request:
branches: [master]

env:
DOTNET_VERSION: '9.0.x'
CONFIGURATION: Release

jobs:
build-and-test:
runs-on: windows-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Set version with commit hash
shell: pwsh
run: |
$commitSha = "${{ github.sha }}".Substring(0, 7)
$filePath = "Directory.Build.props"
$content = Get-Content $filePath -Raw
$content = $content -replace '<InformationalVersion>.*?</InformationalVersion>', "<InformationalVersion>0.0.0+$commitSha</InformationalVersion>"
Set-Content $filePath $content -NoNewline
Write-Host "InformationalVersion set to: 0.0.0+$commitSha"

- name: Restore dependencies
run: dotnet restore

- name: Build solution
run: dotnet build --configuration ${{ env.CONFIGURATION }} --no-restore

- name: Run tests
run: dotnet test --configuration ${{ env.CONFIGURATION }} --no-build --verbosity normal

- name: Publish WinForms app
run: dotnet publish CollectionManager.App.WinForms/CollectionManager.App.WinForms.csproj -f net9.0-windows -p:PublishProfile=FolderProfile

- name: Publish CLI app
run: dotnet publish CollectionManager.App.Cli/CollectionManager.App.Cli.csproj -f net9.0 -p:PublishProfile=FolderProfile

- name: Zip WinForms app
shell: pwsh
run: |
New-Item -ItemType Directory -Path ./artifacts -Force
Compress-Archive -Path ./CollectionManager.App.WinForms/bin/publish/* -DestinationPath ./artifacts/CollectionManager-WinForms.zip

- name: Zip CLI app
shell: pwsh
run: |
Compress-Archive -Path ./CollectionManager.App.Cli/bin/publish/* -DestinationPath ./artifacts/CollectionManager-CLI.zip

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
artifacts/CollectionManager-WinForms.zip
artifacts/CollectionManager-CLI.zip
90 changes: 90 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Release

on:
push:
tags:
- 'v*'

env:
DOTNET_VERSION: '9.0.x'
CONFIGURATION: Release

jobs:
build-and-release:
runs-on: windows-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Extract version from tag
id: version
shell: pwsh
run: |
$version = "${{ github.ref_name }}" -replace '^v', ''
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
Write-Host "Version: $version"

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Update version in Directory.Build.props
shell: pwsh
run: |
$version = "${{ steps.version.outputs.VERSION }}"
$filePath = "Directory.Build.props"
$content = Get-Content $filePath -Raw
$content = $content -replace '<AssemblyVersion>.*?</AssemblyVersion>', "<AssemblyVersion>$version</AssemblyVersion>"
$content = $content -replace '<FileVersion>.*?</FileVersion>', "<FileVersion>$version</FileVersion>"
$content = $content -replace '<InformationalVersion>.*?</InformationalVersion>', "<InformationalVersion>$version</InformationalVersion>"
Set-Content $filePath $content -NoNewline

- name: Restore dependencies
run: dotnet restore

- name: Build solution
run: dotnet build --configuration ${{ env.CONFIGURATION }} --no-restore

- name: Run tests
run: dotnet test --configuration ${{ env.CONFIGURATION }} --no-build --verbosity normal

- name: Publish WinForms app
run: dotnet publish CollectionManager.App.WinForms/CollectionManager.App.WinForms.csproj -f net9.0-windows -p:PublishProfile=FolderProfile

- name: Publish CLI app
run: dotnet publish CollectionManager.App.Cli/CollectionManager.App.Cli.csproj -f net9.0 -p:PublishProfile=FolderProfile

- name: Zip WinForms app
shell: pwsh
run: |
New-Item -ItemType Directory -Path ./artifacts -Force
Compress-Archive -Path ./CollectionManager.App.WinForms/bin/publish/* -DestinationPath ./artifacts/CollectionManager-WinForms.zip

- name: Zip CLI app
shell: pwsh
run: |
Compress-Archive -Path ./CollectionManager.App.Cli/bin/publish/* -DestinationPath ./artifacts/CollectionManager-CLI.zip

- name: Install InnoSetup
run: choco install innosetup -y

- name: Build installer
shell: pwsh
run: |
$version = "${{ steps.version.outputs.VERSION }}"
iscc "/DAppVersion=$version" "InnoSetup\script.iss"
Move-Item "InnoSetup\output\CollectionManagerSetup.exe" "./artifacts/" -Force

- name: Create draft release
uses: softprops/action-gh-release@v2
with:
draft: true
generate_release_notes: true
files: |
artifacts/CollectionManager-WinForms.zip
artifacts/CollectionManager-CLI.zip
artifacts/CollectionManagerSetup.exe
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17 changes: 17 additions & 0 deletions CollectionManager.App.Cli/CollectionManager.App.Cli.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AssemblyTitle>osu! Collection Manager CLI</AssemblyTitle>
<Copyright>Copyright © 2017-present Piotrekol</Copyright>
<PackageId>CollectionManager.App.Cli</PackageId>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\CollectionManager.Core\CollectionManager.Core.csproj" />
<ProjectReference Include="..\CollectionManager.Extensions\CollectionManager.Extensions.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="CommandLineParser" />
</ItemGroup>
</Project>
15 changes: 15 additions & 0 deletions CollectionManager.App.Cli/Common/CommonOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace CollectionManager.App.Cli.Common;

using CommandLine;

internal abstract class CommonOptions
{
[Option('o', "Output", Required = true, HelpText = "Output filename with or without path.")]
public string OutputFilePath { get; init; }

[Option('l', "OsuLocation", Required = false, HelpText = "Location of your osu! or directory where valid osu!.db or client.realm can be found. If not provided, will be found automatically.")]
public string OsuLocation { get; init; }

[Option('s', "SkipOsuLocation", Required = false, HelpText = "Skip loading of osu! database.")]
public bool SkipOsuLocation { get; init; }
}
65 changes: 65 additions & 0 deletions CollectionManager.App.Cli/Common/CommonOptionsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
namespace CollectionManager.App.Cli.Common;

using CollectionManager.Core.Extensions;
using CollectionManager.Core.Modules.FileIo;
using CollectionManager.Core.Types;
using System.IO;

internal static class CommonOptionsExtensions
{
public static OsuFileIo LoadOsuDatabase(this CommonOptions options)
{
OsuFileIo osuFileIo = new(new BeatmapExtension());

if (options.SkipOsuLocation)
{
return osuFileIo;
}

string osuLocation = ResolveOsuLocation(options);

if (string.IsNullOrWhiteSpace(osuLocation))
{
throw new InvalidOperationException("Could not find osu!");
}

Console.WriteLine($"Using osu! database found at \"{osuLocation}\".");
_ = osuFileIo.OsuDatabase.Load(osuLocation, progress: null, cancellationToken: default);

return osuFileIo;
}

private static string ResolveOsuLocation(CommonOptions options)
{
string path = options.OsuLocation;

if (string.IsNullOrWhiteSpace(path))
{
OsuPathResult osuPath = OsuPathResolver.GetOsuOrLazerPath();

if (osuPath.Type is OsuType.None)
{
return null;
}

path = Path.Combine(osuPath.Path, osuPath.Type.GetDatabaseFileName());
}

if (Path.HasExtension(path))
{
return path;
}

if (OsuPathResolver.IsOsuStableDirectory(path))
{
return Path.Combine(path, OsuType.Stable.GetDatabaseFileName());
}

if (OsuPathResolver.IsOsuLazerDataDirectory(path))
{
return Path.Combine(path, OsuType.Lazer.GetDatabaseFileName());
}

return path;
}
}
25 changes: 25 additions & 0 deletions CollectionManager.App.Cli/Convert/ConvertCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace CollectionManager.App.Cli.Convert;

using CollectionManager.App.Cli.Common;
using CollectionManager.Core.Modules.FileIo;
using CollectionManager.Core.Types;
using CommandLine;
using System.Threading.Tasks;

[Verb("convert", HelpText = "Convert collection files between formats (.db/.osdb)")]
internal sealed class ConvertCommand : CommonOptions
{
[Option('i', "Input", Required = true, HelpText = "Input db/osdb collection file.")]
public string InputFilePath { get; init; }

public Task<int> RunAsync()
{
using OsuFileIo osuFileIo = this.LoadOsuDatabase();
Console.WriteLine("Converting collections.");
OsuCollections collections = osuFileIo.CollectionLoader.LoadCollection(InputFilePath);
osuFileIo.CollectionLoader.SaveCollection(collections, OutputFilePath);
Console.WriteLine("Done.");

return Task.FromResult(0);
}
}
Loading
Loading