diff --git a/nuget.config b/nuget.config index fbcef1011..71109544a 100644 --- a/nuget.config +++ b/nuget.config @@ -1,7 +1,8 @@ - + + diff --git a/samples/BaGet.Protocol.Samples.Tests/BaGet.Protocol.Samples.Tests.csproj b/samples/BaGet.Protocol.Samples.Tests/BaGet.Protocol.Samples.Tests.csproj index 51c3b7967..f46258d41 100644 --- a/samples/BaGet.Protocol.Samples.Tests/BaGet.Protocol.Samples.Tests.csproj +++ b/samples/BaGet.Protocol.Samples.Tests/BaGet.Protocol.Samples.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net6.0;net5.0 false IDE0007 diff --git a/samples/BaGetWebApplication/BaGetWebApplication.csproj b/samples/BaGetWebApplication/BaGetWebApplication.csproj index 3123a668b..ce78a20bd 100644 --- a/samples/BaGetWebApplication/BaGetWebApplication.csproj +++ b/samples/BaGetWebApplication/BaGetWebApplication.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net6.0;net5.0 diff --git a/src/BaGet.Core/Configuration/BaGetOptions.cs b/src/BaGet.Core/Configuration/BaGetOptions.cs index efd19ee8d..bbb4cc5b7 100644 --- a/src/BaGet.Core/Configuration/BaGetOptions.cs +++ b/src/BaGet.Core/Configuration/BaGetOptions.cs @@ -37,6 +37,8 @@ public class BaGetOptions /// public bool IsReadOnlyMode { get; set; } = false; + public string LocalPackages { get; set; } + /// /// The URLs the BaGet server will use. /// As per documentation here (Server URLs). diff --git a/src/BaGet.Core/Extensions/BaGetApplicationExtensions.cs b/src/BaGet.Core/Extensions/BaGetApplicationExtensions.cs index 7dc2967f3..11cd43c46 100644 --- a/src/BaGet.Core/Extensions/BaGetApplicationExtensions.cs +++ b/src/BaGet.Core/Extensions/BaGetApplicationExtensions.cs @@ -1,5 +1,7 @@ using System; +using System.IO; using BaGet.Core; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; diff --git a/src/BaGet.Web/BaGet.Web.csproj b/src/BaGet.Web/BaGet.Web.csproj index 276e6569d..247315e75 100644 --- a/src/BaGet.Web/BaGet.Web.csproj +++ b/src/BaGet.Web/BaGet.Web.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net6.0;net5.0 NuGet BaGet's NuGet server implementation diff --git a/src/BaGet/BaGet.csproj b/src/BaGet/BaGet.csproj index 880268ce1..bf6003514 100644 --- a/src/BaGet/BaGet.csproj +++ b/src/BaGet/BaGet.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net6.0;net5.0 diff --git a/src/BaGet/BackgroundServices/ImportLocalPackagesService.cs b/src/BaGet/BackgroundServices/ImportLocalPackagesService.cs new file mode 100644 index 000000000..fd3ffadba --- /dev/null +++ b/src/BaGet/BackgroundServices/ImportLocalPackagesService.cs @@ -0,0 +1,92 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using System.Timers; +using BaGet.Core; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Timer = System.Timers.Timer; + +namespace BaGet.BackgroundServices +{ + public class ImportLocalPackagesService : BackgroundService + { + private readonly string _localPackages; + private readonly IServiceProvider _serviceProvider; + private readonly Timer _timer; + private IPackageIndexingService _packageIndexingService; + + public ImportLocalPackagesService(IServiceProvider serviceProvider, IConfiguration configuration) + { + _serviceProvider = serviceProvider; + var options = configuration.Get(); + _localPackages = options.LocalPackages; + if (!string.IsNullOrWhiteSpace(_localPackages)) + { + _localPackages = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _localPackages); + + if (!Directory.Exists(_localPackages)) Directory.CreateDirectory(_localPackages); + } + + _timer = new Timer(300); + _timer.Elapsed += Timer_Elapsed; + } + + private IPackageIndexingService PackageIndexingService + { + get => + _packageIndexingService ??= _serviceProvider.CreateScope() + .ServiceProvider + .GetRequiredService(); + set => _packageIndexingService = value; + } + + private async void Timer_Elapsed(object sender, ElapsedEventArgs e) + { + _timer.Stop(); + await ImportPackages(default); + } + + private const string ExtName = ".nupkg"; + + private async Task ImportPackages(CancellationToken stoppingToken) + { + var files = Directory.GetFiles(_localPackages); + foreach (var file in files) + { + if (!ExtName.Equals(Path.GetExtension(file))) + { + continue; + } + using (var stream = File.OpenRead(file)) + { + await PackageIndexingService.IndexAsync(stream, stoppingToken); + } + + File.Delete(file); + } + + PackageIndexingService = null; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + if (!string.IsNullOrWhiteSpace(_localPackages)) + { + await ImportPackages(stoppingToken); + var watcher = new FileSystemWatcher(_localPackages); + watcher.Created += WatcherCreated; + watcher.EnableRaisingEvents = true; + while (stoppingToken.IsCancellationRequested) await Task.Delay(100, stoppingToken); + } + } + + private void WatcherCreated(object sender, FileSystemEventArgs e) + { + _timer.Stop(); + _timer.Start(); + } + } +} diff --git a/src/BaGet/Properties/launchSettings.json b/src/BaGet/Properties/launchSettings.json index 05eeb31cf..1f376570e 100644 --- a/src/BaGet/Properties/launchSettings.json +++ b/src/BaGet/Properties/launchSettings.json @@ -1,12 +1,4 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:50557/", - "sslPort": 0 - } - }, "profiles": { "IIS Express": { "commandName": "IISExpress", @@ -25,5 +17,13 @@ }, "applicationUrl": "http://localhost:50561/" } + }, + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:50557/", + "sslPort": 0 + } } -} +} \ No newline at end of file diff --git a/src/BaGet/Startup.cs b/src/BaGet/Startup.cs index f637267bb..564941914 100644 --- a/src/BaGet/Startup.cs +++ b/src/BaGet/Startup.cs @@ -1,4 +1,5 @@ using System; +using BaGet.BackgroundServices; using BaGet.Core; using BaGet.Web; using Microsoft.AspNetCore.Builder; @@ -51,6 +52,7 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton, ConfigureRazorRuntimeCompilation>(); + services.AddHostedService(); services.AddCors(); } diff --git a/src/BaGet/appsettings.json b/src/BaGet/appsettings.json index f431f367a..a20bdc5cd 100644 --- a/src/BaGet/appsettings.json +++ b/src/BaGet/appsettings.json @@ -3,6 +3,9 @@ "PackageDeletionBehavior": "Unlist", "AllowPackageOverwrites": false, + // Auto Import nupkg files + "LocalPackages": "Sources", + "Database": { "Type": "Sqlite", "ConnectionString": "Data Source=baget.db" diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 919be1428..c237d2d00 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ true - 7.2 + $(NoWarn);1591 @@ -40,7 +40,8 @@ 3.1.18 3.1.18 3.1.18 - 5.10.0 + 6.9.1 + 13.0.3 diff --git a/tests/BaGet.Core.Tests/BaGet.Core.Tests.csproj b/tests/BaGet.Core.Tests/BaGet.Core.Tests.csproj index 50ca5e849..f7f74ed3a 100644 --- a/tests/BaGet.Core.Tests/BaGet.Core.Tests.csproj +++ b/tests/BaGet.Core.Tests/BaGet.Core.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net6.0;net5.0 diff --git a/tests/BaGet.Protocol.Tests/BaGet.Protocol.Tests.csproj b/tests/BaGet.Protocol.Tests/BaGet.Protocol.Tests.csproj index 83f963a35..7ed8b1112 100644 --- a/tests/BaGet.Protocol.Tests/BaGet.Protocol.Tests.csproj +++ b/tests/BaGet.Protocol.Tests/BaGet.Protocol.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net6.0;net5.0 diff --git a/tests/BaGet.Tests/BaGet.Tests.csproj b/tests/BaGet.Tests/BaGet.Tests.csproj index 4f70442a9..e94d60f8e 100644 --- a/tests/BaGet.Tests/BaGet.Tests.csproj +++ b/tests/BaGet.Tests/BaGet.Tests.csproj @@ -1,7 +1,7 @@ - + - netcoreapp3.1 + net6.0;net5.0 8.0 @@ -10,8 +10,8 @@ - - + + diff --git a/tests/BaGet.Web.Tests/BaGet.Web.Tests.csproj b/tests/BaGet.Web.Tests/BaGet.Web.Tests.csproj index fb144a8fc..44d9bfcde 100644 --- a/tests/BaGet.Web.Tests/BaGet.Web.Tests.csproj +++ b/tests/BaGet.Web.Tests/BaGet.Web.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net6.0;net5.0