dotnet package resolution

This commit is contained in:
2024-10-20 19:47:49 +01:00
parent c615886a4c
commit 5f1dca3d61
19 changed files with 777 additions and 84 deletions

2
.vscode/tasks.json vendored
View File

@ -84,7 +84,7 @@
} }
}, },
"problemMatcher": "$msCompile", "problemMatcher": "$msCompile",
"group": "test" "group": "none"
} }
] ]
} }

11
src/Directory.Build.props Normal file
View File

@ -0,0 +1,11 @@
<Project>
<PropertyGroup>
<Version>1.0.8</Version>
<Authors>paul</Authors>
<Copyright>WFPL</Copyright>
<PackageLicenseExpression></PackageLicenseExpression>
<ProjectUrl></ProjectUrl>
<RepositoryUrl></RepositoryUrl>
<RepositoryType>git</RepositoryType>
</PropertyGroup>
</Project>

View File

@ -13,7 +13,7 @@ namespace isnd.Entities
public const string Registration = "/registration"; public const string Registration = "/registration";
public const string Nuspec = "/nuspec"; public const string Nuspec = "/nuspec";
public const string Content = "/content"; public const string ContentBase = "/content";
public const string Nuget = "/nuget"; public const string Nuget = "/nuget";
public const string PackageDetailUriTemplate = Package+"/{id}/{version}"; public const string PackageDetailUriTemplate = Package+"/{id}/{version}";

View File

@ -1,13 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<PackageVersion>1.0.1</PackageVersion>
<Version>1.0.7</Version>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks> <TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<NoWarn>NETSDK1138</NoWarn> </PropertyGroup>
<AssemblyVersion>1.0.7.0</AssemblyVersion>
<FileVersion>1.0.7.0</FileVersion>
<InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup> </ItemGroup>

View File

@ -4,14 +4,11 @@
<TargetFrameworks>net8.0</TargetFrameworks> <TargetFrameworks>net8.0</TargetFrameworks>
<RootNamespace>nuget_cli</RootNamespace> <RootNamespace>nuget_cli</RootNamespace>
<UserSecretsId>45b74c62-05bc-4603-95b4-3e80ae2fdf50</UserSecretsId> <UserSecretsId>45b74c62-05bc-4603-95b4-3e80ae2fdf50</UserSecretsId>
<Version>1.0.7</Version>
<PackageVersion>1.0.1</PackageVersion>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<PackageLicenseExpression>WTFPL</PackageLicenseExpression> <PackageLicenseExpression>WTFPL</PackageLicenseExpression>
<IsTool>true</IsTool> <IsTool>true</IsTool>
<NoWarn>NETSDK1138</NoWarn> <NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>1.0.7.0</AssemblyVersion>
<FileVersion>1.0.7.0</FileVersion>
<InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion> <InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -16,8 +16,9 @@ namespace isnd.Controllers
} }
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Content + "/{id}/{version}.json")]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Registration + "/{id}/{version}.json")]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Registration + "/{id}/{version}.json")]
public async Task<IActionResult> CatalogRegistration(string id, string version) public async Task<IActionResult> CatalogRegistration(string id, string version)
{ {
if ("index" == version) if ("index" == version)

View File

@ -9,18 +9,16 @@ namespace isnd.Controllers
{ {
public partial class PackagesController public partial class PackagesController
{ {
// Web get the paquet
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Nuget + "/{id}/{lower}/{idf}-{lowerFromName}." [HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.ContentBase + "/{id}/{version}/{idf}.{versionFromName}."
+ Constants.PacketFileExtension)]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Content + "/{id}/{lower}/{idf}-{lowerFromName}."
+ Constants.PacketFileExtension)] + Constants.PacketFileExtension)]
public IActionResult GetPackage( public IActionResult GetPackage(
[FromRoute][SafeName][Required] string id, [FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower, [FromRoute][SafeName][Required] string version,
[FromRoute] string idf, [FromRoute] string lowerFromName) [FromRoute] string idf, [FromRoute] string versionFromName)
{ {
var pkgPath = Path.Combine(isndSettings.PackagesRootDir, var pkgPath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}-{lower}." + Constants.PacketFileExtension id, version, $"{id}-{version}." + Constants.PacketFileExtension
); );
FileInfo pkgFileInfo = new FileInfo(pkgPath); FileInfo pkgFileInfo = new FileInfo(pkgPath);
@ -33,7 +31,7 @@ namespace isnd.Controllers
} }
// Web get spec // Web get spec
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Nuspec + "/{id}/{lower}/{idf}-{lowerFromName}." [HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.ContentBase + "/{id}/{lower}/{idf}-{lowerFromName}."
+ Constants.SpecFileExtension)] + Constants.SpecFileExtension)]
public IActionResult GetNuspec( public IActionResult GetNuspec(
[FromRoute][SafeName][Required] string id, [FromRoute][SafeName][Required] string id,

View File

@ -1,28 +1,37 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NuGet.Versioning; using NuGet.Versioning;
using isnd.Entities; using isnd.Entities;
using isn.abst;
namespace isnd.Controllers namespace isnd.Controllers
{ {
public partial class PackagesController public partial class PackagesController
{ {
[HttpGet("~" + ApiConfig.V2Find)] [HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.ContentBase + "/{id}/{version}.json")]
public IActionResult GetVersions( public IActionResult GetVersions(
string id, string id,
string lower, string version,
bool prerelease = false, bool prerelease = false,
string packageType = null, string packageType = null,
int skip = 0, int skip = 0,
int take = 25) int take = 50)
{ {
NuGetVersion parsedVersion=null;
if (take > maxTake) if (take > maxTake)
{ {
ModelState.AddModelError("take", "Maximum exceeded"); ModelState.AddModelError("take", "Maximum exceeded");
} }
// NugetVersion if ("index"==version)
if (!NuGetVersion.TryParse(lower, out NuGetVersion parsedVersion))
{ {
ModelState.AddModelError("lower", "invalid version string"); version=null;
}
if (version!=null)
{
if (!NuGetVersion.TryParse(version, out parsedVersion))
{
ModelState.AddModelError("version", "invalid version string");
}
} }
if (!ModelState.IsValid) if (!ModelState.IsValid)
{ {

View File

@ -37,6 +37,9 @@ namespace isnd.Data.Catalog
{ {
DependencySets = pkg.DependencyGroups; DependencySets = pkg.DependencyGroups;
} }
Description = pkg.Description;
Owners = pkg.Package.Owner.Email;
// TODO Licence Project Urls, Summary, Title, Owners, etc ... // TODO Licence Project Urls, Summary, Title, Owners, etc ...
} }
@ -127,11 +130,8 @@ namespace isnd.Data.Catalog
[JsonProperty("id")] [JsonProperty("id")]
public string PackageId { get; set; } public string PackageId { get; set; }
public long? DownloadCount { get; set; } public long? DownloadCount { get; set; }
public PackageIdentity Identity{ get; set; }
public Uri ReadmeUrl { get; set; } public Uri ReadmeUrl { get; set; }
public Uri ReportAbuseUrl { get; set; } public Uri ReportAbuseUrl { get; set; }
@ -140,8 +140,6 @@ namespace isnd.Data.Catalog
public bool Listed { get; set; } public bool Listed { get; set; }
public bool PrefixReserved { get; set; }
public LicenseMetadata LicenseMetadata { get; set; } public LicenseMetadata LicenseMetadata { get; set; }

View File

@ -32,8 +32,11 @@ namespace isnd.Data
public virtual PackageDependencyGroup Group{ get; set; } public virtual PackageDependencyGroup Group{ get; set; }
// TODO Version Range // TODO Version Range
[JsonProperty("range")] [JsonProperty("range")][StringLength(1024)]
public string Version { get; set; } public string Version { get; set; }
[JsonProperty("exclude")][StringLength(2048)]
public string Exclude { get; set; }
} }
} }

View File

@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
using System.Linq; using System.Linq;
using isnd.Interfaces; using isnd.Interfaces;
using Newtonsoft.Json; using Newtonsoft.Json;
using NuGet.Versioning;
namespace isnd.Data.Packages namespace isnd.Data.Packages
{ {
@ -48,9 +49,10 @@ namespace isnd.Data.Packages
public virtual Commit LatestCommit { get; set; } public virtual Commit LatestCommit { get; set; }
internal string GetLatestVersion() public PackageVersion GetLatestVersion()
{ {
return Versions.Max(v => v.NugetVersion)?.ToFullString(); var latest = Versions.Max(v => v.NugetVersion);
return Versions.First(v=> v.NugetVersion == latest);
} }
} }
} }

View File

@ -80,5 +80,11 @@ namespace isnd.Data
} }
public bool IsDeleted => LatestCommit?.Action == PackageAction.DeletePackage; public bool IsDeleted => LatestCommit?.Action == PackageAction.DeletePackage;
[StringLength(1024)]
public string Authors { get; set; }
[StringLength(1024)]
public string Description { get; set; }
} }
} }

View File

@ -0,0 +1,545 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using isnd.Data;
#nullable disable
namespace isnd.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20241020181446_Authors")]
partial class Authors
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("ProviderKey")
.HasColumnType("text");
b.Property<string>("ProviderDisplayName")
.HasColumnType("text");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("text");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("text");
b.Property<string>("RoleId")
.HasColumnType("text");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("text");
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Value")
.HasColumnType("text");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("text");
b.Property<DateTimeOffset>("CreationDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("text");
b.Property<int>("ValidityPeriodInDays")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ApiKeys");
});
modelBuilder.Entity("isnd.Data.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("AccessFailedCount")
.HasColumnType("integer");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("LockoutEnabled")
.HasColumnType("boolean");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("timestamp with time zone");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.HasColumnType("text");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("boolean");
b.Property<string>("SecurityStamp")
.HasColumnType("text");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("boolean");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("isnd.Data.Dependency", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("text");
b.Property<string>("DependencyGroupId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Exclude")
.HasMaxLength(2048)
.HasColumnType("character varying(2048)");
b.Property<string>("PackageId")
.HasColumnType("text");
b.Property<string>("Version")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.HasKey("Id");
b.HasIndex("DependencyGroupId");
b.ToTable("Dependencies");
});
modelBuilder.Entity("isnd.Data.PackageDependencyGroup", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("text");
b.Property<string>("PackageId")
.IsRequired()
.HasColumnType("character varying(1024)");
b.Property<string>("PackageVersionFullString")
.IsRequired()
.HasColumnType("character varying(256)");
b.Property<string>("TargetFramework")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("PackageId", "PackageVersionFullString");
b.ToTable("PackageDependencyGroups");
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.Property<string>("PackageId")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<string>("FullString")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("Authors")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<long>("CommitNId")
.HasColumnType("bigint");
b.Property<string>("Description")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<bool>("IsPrerelease")
.HasColumnType("boolean");
b.Property<int>("Major")
.HasColumnType("integer");
b.Property<int>("Minor")
.HasColumnType("integer");
b.Property<int>("Patch")
.HasColumnType("integer");
b.Property<int>("Revision")
.HasColumnType("integer");
b.Property<string>("Type")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("PackageId", "FullString");
b.HasIndex("CommitNId");
b.ToTable("PackageVersions");
});
modelBuilder.Entity("isnd.Data.Packages.Commit", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<int>("Action")
.HasColumnType("integer");
b.Property<DateTimeOffset>("TimeStamp")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.ToTable("Commits");
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.Property<string>("Id")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<long>("CommitNId")
.HasColumnType("bigint");
b.Property<string>("Description")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<string>("OwnerId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("Public")
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("CommitNId");
b.HasIndex("OwnerId");
b.ToTable("Packages");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("isnd.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isnd.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("isnd.Data.Dependency", b =>
{
b.HasOne("isnd.Data.PackageDependencyGroup", "Group")
.WithMany("Dependencies")
.HasForeignKey("DependencyGroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Group");
});
modelBuilder.Entity("isnd.Data.PackageDependencyGroup", b =>
{
b.HasOne("isnd.Data.PackageVersion", "PackageVersion")
.WithMany("DependencyGroups")
.HasForeignKey("PackageId", "PackageVersionFullString")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("PackageVersion");
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestCommit")
.WithMany("Versions")
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("isnd.Data.Packages.Package", "Package")
.WithMany("Versions")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LatestCommit");
b.Navigation("Package");
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestCommit")
.WithMany()
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("isnd.Data.ApplicationUser", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LatestCommit");
b.Navigation("Owner");
});
modelBuilder.Entity("isnd.Data.PackageDependencyGroup", b =>
{
b.Navigation("Dependencies");
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.Navigation("DependencyGroups");
});
modelBuilder.Entity("isnd.Data.Packages.Commit", b =>
{
b.Navigation("Versions");
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.Navigation("Versions");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,80 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace isnd.Migrations
{
/// <inheritdoc />
public partial class Authors : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Authors",
table: "PackageVersions",
type: "character varying(1024)",
maxLength: 1024,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Description",
table: "PackageVersions",
type: "character varying(1024)",
maxLength: 1024,
nullable: true);
migrationBuilder.AlterColumn<string>(
name: "Version",
table: "Dependencies",
type: "character varying(1024)",
maxLength: 1024,
nullable: true,
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "Exclude",
table: "Dependencies",
type: "character varying(2048)",
maxLength: 2048,
nullable: true,
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Authors",
table: "PackageVersions");
migrationBuilder.DropColumn(
name: "Description",
table: "PackageVersions");
migrationBuilder.AlterColumn<string>(
name: "Version",
table: "Dependencies",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(1024)",
oldMaxLength: 1024,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "Exclude",
table: "Dependencies",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(2048)",
oldMaxLength: 2048,
oldNullable: true);
}
}
}

View File

@ -17,7 +17,7 @@ namespace isnd.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "8.0.3") .HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@ -258,13 +258,15 @@ namespace isnd.Migrations
.HasColumnType("text"); .HasColumnType("text");
b.Property<string>("Exclude") b.Property<string>("Exclude")
.HasColumnType("text"); .HasMaxLength(2048)
.HasColumnType("character varying(2048)");
b.Property<string>("PackageId") b.Property<string>("PackageId")
.HasColumnType("text"); .HasColumnType("text");
b.Property<string>("Version") b.Property<string>("Version")
.HasColumnType("text"); .HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.HasKey("Id"); b.HasKey("Id");
@ -308,9 +310,17 @@ namespace isnd.Migrations
.HasMaxLength(256) .HasMaxLength(256)
.HasColumnType("character varying(256)"); .HasColumnType("character varying(256)");
b.Property<string>("Authors")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<long>("CommitNId") b.Property<long>("CommitNId")
.HasColumnType("bigint"); .HasColumnType("bigint");
b.Property<string>("Description")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<bool>("IsPrerelease") b.Property<bool>("IsPrerelease")
.HasColumnType("boolean"); .HasColumnType("boolean");

View File

@ -19,6 +19,7 @@ using NuGet.Versioning;
using System.Xml; using System.Xml;
using System.Xml.Linq; using System.Xml.Linq;
using NuGet.Protocol; using NuGet.Protocol;
using System.ComponentModel;
namespace isnd.Services namespace isnd.Services
{ {
@ -53,7 +54,7 @@ namespace isnd.Services
Comment = "URI template used by NuGet Client to construct details URL for packages" Comment = "URI template used by NuGet Client to construct details URL for packages"
}, },
new Resource(apiBase + ApiConfig.Content, new Resource(apiBase + ApiConfig.ContentBase + "/",
"PackageBaseAddress/3.0.0") "PackageBaseAddress/3.0.0")
{ {
Comment = "Package Base Address service - " + Comment = "Package Base Address service - " +
@ -124,16 +125,39 @@ namespace isnd.Services
int skip = 0, int skip = 0,
int take = 25) int take = 25)
{ {
return dbContext.PackageVersions.Where( IQueryable<PackageVersion> results =
v => v.PackageId == id (parsedVersion != null)?
&& (prerelease || !v.IsPrerelease) (packageType == null) ?
&& (packageType == null || v.Type == packageType) dbContext.PackageVersions.Where(
&& (parsedVersion == null || parsedVersion.CompareTo v => v.PackageId == id
(new SemanticVersion(v.Major, v.Minor, v.Patch)) < 0) && (prerelease || !v.IsPrerelease)
) && (parsedVersion.CompareTo(new SemanticVersion(v.Major, v.Minor, v.Patch)) < 0)
.OrderBy(v => v.NugetVersion) )
.Select(v => v.FullString) :
.Skip(skip).Take(take).ToArray(); dbContext.PackageVersions.Where(
v => v.PackageId == id
&& (prerelease || !v.IsPrerelease)
&& (v.Type == packageType)
&& (parsedVersion.CompareTo(new SemanticVersion(v.Major, v.Minor, v.Patch)) < 0)
)
:
(packageType == null) ?
dbContext.PackageVersions.Where(
v => v.PackageId == id
&& (prerelease || !v.IsPrerelease)
)
:
dbContext.PackageVersions.Where(
v => v.PackageId == id
&& (prerelease || !v.IsPrerelease)
&& (v.Type == packageType)
)
;
return [.. results
.Select(v => v.FullString)
.Skip(skip).Take(take)];
} }
public string CatalogBaseUrl => apiBase; public string CatalogBaseUrl => apiBase;
@ -218,16 +242,16 @@ namespace isnd.Services
(string pkgId, string version, string type) (string pkgId, string version, string type)
{ {
var pkg = await dbContext.PackageVersions var pkg = await dbContext.PackageVersions
.Include(v=>v.Package) .Include(v => v.Package)
.Include(v=>v.Package.Owner) .Include(v => v.Package.Owner)
.Include(v=>v.LatestCommit) .Include(v => v.LatestCommit)
.Include(v=>v.DependencyGroups) .Include(v => v.DependencyGroups)
.SingleOrDefaultAsync( .SingleOrDefaultAsync(
v => v.PackageId == pkgId && v => v.PackageId == pkgId &&
v.FullString == version && v.FullString == version &&
(type==null || v.Type == type)) (type == null || v.Type == type))
; ;
if (pkg == null) return null; if (pkg == null) return null;
foreach (var g in pkg.DependencyGroups) foreach (var g in pkg.DependencyGroups)
{ {
g.Dependencies = dbContext.Dependencies.Where(d => d.DependencyGroupId == g.Id).ToList(); g.Dependencies = dbContext.Dependencies.Where(d => d.DependencyGroupId == g.Id).ToList();
@ -249,7 +273,7 @@ namespace isnd.Services
&& v.LatestCommit != null && v.LatestCommit != null
&& (pkgType == null || pkgType == v.Type) && (pkgType == null || pkgType == v.Type)
).SingleOrDefaultAsync(); ).SingleOrDefaultAsync();
if (version==null) return null; if (version == null) return null;
foreach (var g in version.DependencyGroups) foreach (var g in version.DependencyGroups)
{ {
g.Dependencies = dbContext.Dependencies.Where(d => d.DependencyGroupId == g.Id).ToList(); g.Dependencies = dbContext.Dependencies.Where(d => d.DependencyGroupId == g.Id).ToList();
@ -263,7 +287,7 @@ namespace isnd.Services
PackageVersion packageVersion = await dbContext.PackageVersions PackageVersion packageVersion = await dbContext.PackageVersions
.Include(pv => pv.Package) .Include(pv => pv.Package)
.FirstOrDefaultAsync(m => m.PackageId == id .FirstOrDefaultAsync(m => m.PackageId == id
&& m.FullString == lower && (type==null || m.Type == type)); && m.FullString == lower && (type == null || m.Type == type));
if (packageVersion == null) return null; if (packageVersion == null) return null;
if (packageVersion.Package.OwnerId != uid) return null; if (packageVersion.Package.OwnerId != uid) return null;
return new PackageDeletionReport { Deleted = true, DeletedVersion = packageVersion }; return new PackageDeletionReport { Deleted = true, DeletedVersion = packageVersion };
@ -327,10 +351,10 @@ namespace isnd.Services
query.Query = ""; query.Query = "";
var packages = await dbContext.Packages var packages = await dbContext.Packages
.Include(g => g.Versions).OrderBy(v=>v.CommitNId) .Include(g => g.Versions).OrderBy(v => v.CommitNId)
.Where(d => d.Id.StartsWith(query.Query) .Where(d => d.Id.StartsWith(query.Query)
&& (query.Prerelease || d.Versions.Any(v => !v.IsPrerelease))) && (query.Prerelease || d.Versions.Any(v => !v.IsPrerelease)))
.Where(p=>p.Versions.Count>=0) .Where(p => p.Versions.Count >= 0)
.Skip(query.Skip).Take(query.Take).ToArrayAsync(); .Skip(query.Skip).Take(query.Take).ToArrayAsync();
foreach (var package in packages) foreach (var package in packages)
foreach (var version in package.Versions) foreach (var version in package.Versions)
@ -363,11 +387,13 @@ namespace isnd.Services
var xMeta = XElement.Load(xmlReader, LoadOptions.None).Descendants().First(); var xMeta = XElement.Load(xmlReader, LoadOptions.None).Descendants().First();
string packageDescription = xMeta.Descendants().FirstOrDefault(x => x.Name.LocalName == "description")?.Value; var xMetaElts = xMeta.Descendants();
string description = xMetaElts.FirstOrDefault(x => x.Name.LocalName == "description")?.Value;
var dependencies = xMeta var dependencies = xMeta
.Descendants().FirstOrDefault(x => x.Name.LocalName == "dependencies"); .Descendants().FirstOrDefault(x => x.Name.LocalName == "dependencies");
var frameworkReferences= xMeta var frameworkReferences = xMeta
.Descendants().FirstOrDefault(x => x.Name.LocalName == "frameworkReferences"); .Descendants().FirstOrDefault(x => x.Name.LocalName == "frameworkReferences");
var frameWorks = (dependencies ?? frameworkReferences) var frameWorks = (dependencies ?? frameworkReferences)
@ -375,8 +401,8 @@ namespace isnd.Services
.Select(x => NewFrameworkDependencyGroup(x)).ToArray(); .Select(x => NewFrameworkDependencyGroup(x)).ToArray();
// FIXME default package type or null // FIXME default package type or null
var types = "Dependency"; var types = "Dependency";
pkgId = xMeta.Descendants().FirstOrDefault(x => x.Name.LocalName == "id")?.Value; pkgId = xMetaElts.FirstOrDefault(x => x.Name.LocalName == "id")?.Value;
string pkgVersion = xMeta.Descendants().FirstOrDefault(x => x.Name.LocalName == "version")?.Value; string pkgVersion = xMetaElts.FirstOrDefault(x => x.Name.LocalName == "version")?.Value;
if (!NuGetVersion.TryParse(pkgVersion, out nugetVersion)) if (!NuGetVersion.TryParse(pkgVersion, out nugetVersion))
throw new InvalidPackageException("metadata/version"); throw new InvalidPackageException("metadata/version");
@ -387,6 +413,8 @@ namespace isnd.Services
string name = $"{pkgId}-{nugetVersion}." + Constants.PacketFileExtension; string name = $"{pkgId}-{nugetVersion}." + Constants.PacketFileExtension;
fullPath = Path.Combine(pkgPath, name); fullPath = Path.Combine(pkgPath, name);
var authors = xMetaElts.FirstOrDefault(x => x.Name.LocalName == "authors")?.Value;
var packageIdPathInfo = new DirectoryInfo(packageIdPath); var packageIdPathInfo = new DirectoryInfo(packageIdPath);
Data.Packages.Package pkg = dbContext.Packages.SingleOrDefault(p => p.Id == pkgId); Data.Packages.Package pkg = dbContext.Packages.SingleOrDefault(p => p.Id == pkgId);
Commit commit = new Commit Commit commit = new Commit
@ -405,12 +433,11 @@ namespace isnd.Services
{ {
Id = pkgId, Id = pkgId,
OwnerId = ownerId, OwnerId = ownerId,
Public = true,
}; };
dbContext.Packages.Add(pkg); dbContext.Packages.Add(pkg);
} }
pkg.Public = true;
pkg.LatestCommit = commit; pkg.LatestCommit = commit;
pkg.Description = packageDescription;
// here, the package is or new, or owned by the key owner // here, the package is or new, or owned by the key owner
if (!packageIdPathInfo.Exists) packageIdPathInfo.Create(); if (!packageIdPathInfo.Exists) packageIdPathInfo.Create();
@ -447,7 +474,9 @@ namespace isnd.Services
IsPrerelease = nugetVersion.IsPrerelease, IsPrerelease = nugetVersion.IsPrerelease,
FullString = versionFullString, FullString = versionFullString,
Type = types, Type = types,
LatestCommit = commit LatestCommit = commit,
Authors = authors,
Description = description
}); });
dbContext.Commits.Add(commit); dbContext.Commits.Add(commit);
@ -514,10 +543,10 @@ namespace isnd.Services
var frameworkReferences = x.Descendants(); var frameworkReferences = x.Descendants();
var framework = x.Attribute("targetFramework").Value; var framework = x.Attribute("targetFramework").Value;
var deps = frameworkReferences.Select(r => new ShortDependencyInfo var deps = frameworkReferences.Select(r => new ShortDependencyInfo
{ {
PackageId = (r.Attribute("name") ?? r.Attribute("id")).Value, PackageId = (r.Attribute("name") ?? r.Attribute("id")).Value,
PackageVersion = r.Attribute("version")?.Value PackageVersion = r.Attribute("version")?.Value
}); });
return new FrameworkDependencyGroup return new FrameworkDependencyGroup
{ {

View File

@ -34,18 +34,20 @@ namespace isnd.ViewModels
private static PackageHit NewPackageHit(string apiBase, Package package) private static PackageHit NewPackageHit(string apiBase, Package package)
{ {
string regId = $"{apiBase}{ApiConfig.Registration}/{package.Id}/index.json"; string regId = $"{apiBase}{ApiConfig.Registration}/{package.Id}/index.json";
var latest = package.GetLatestVersion();
if (latest==null) return null;
var pkgHit = new PackageHit(regId, package.Id) var pkgHit = new PackageHit(regId, package.Id)
{ {
version = package.GetLatestVersion(), version = latest.NugetVersion.ToString(),
description = package.Description, description = latest.Description,
}; };
if (package.Versions!=null) if (package.Versions!=null)
{ {
pkgHit.versions = package.Versions pkgHit.versions = package.Versions
.Select(v => new SearchVersionInfo(apiBase, v)).ToArray(); .Select(v => new SearchVersionInfo(apiBase, v)).ToArray();
pkgHit.packageTypes = package.Versions pkgHit.packageTypes = package.Versions.Where(v=> v.Type!=null)
.Select(v=>new PackageType(v.Type ?? "Legacy", new System.Version(v.Major,v.Minor,v.Patch, v.Revision)))?.ToArray(); .Select(v=>new PackageType(v.Type, new System.Version(v.Major,v.Minor,v.Patch, v.Revision)))?.ToArray();
} }
return pkgHit; return pkgHit;
} }

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<RootNamespace>test_isn</RootNamespace> <RootNamespace>test_isn</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@ -9,7 +9,11 @@
<FileVersion>1.0.7.0</FileVersion> <FileVersion>1.0.7.0</FileVersion>
<InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion> <InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion>
<Version>1.0.7</Version> <Version>1.0.7</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="isn.abst" Version="1.0.24" />
</ItemGroup>
</Project> </Project>

View File

@ -94,7 +94,7 @@ namespace isnd.host.tests
} }
[Fact] [Fact]
public void TrueTestRegistrationV3Resource() public async Task TrueTestRegistrationV3Resource()
{ {
using (var serviceScope = server.Host.Services.CreateScope()) using (var serviceScope = server.Host.Services.CreateScope())
{ {
@ -103,7 +103,10 @@ namespace isnd.host.tests
var prov = new RegistrationResourceV3Provider(); var prov = new RegistrationResourceV3Provider();
var source = new PackageSource(pkgSourceUrl); var source = new PackageSource(pkgSourceUrl);
var repo = new SourceRepository(source, new INuGetResourceProvider[] { prov }); var repo = new SourceRepository(source, new INuGetResourceProvider[] { prov });
prov.TryCreate(repo, CancellationToken.None); (bool ok, INuGetResource res) = await prov.TryCreate(repo, CancellationToken.None);
// FIXME FALSE Assert.True(ok);
// FIXME FALSE Assert.NotNull(res);
} }
} }
@ -167,7 +170,8 @@ namespace isnd.host.tests
{ {
Console.WriteLine($"Found package {result.Identity.Id} {result.Identity.Version}"); Console.WriteLine($"Found package {result.Identity.Id} {result.Identity.Version}");
} }
Assert.NotEmpty( meta.Where(result => result.DependencySets.Any()));
Assert.True( meta.Where(result => result.DependencySets.Any()).Count()>0);
} }
[Fact] [Fact]
@ -179,13 +183,13 @@ namespace isnd.host.tests
PackageUpdateResource pushRes = await repository.GetResourceAsync<PackageUpdateResource>(); PackageUpdateResource pushRes = await repository.GetResourceAsync<PackageUpdateResource>();
SymbolPackageUpdateResourceV3 symbolPackageResource = await repository.GetResourceAsync<SymbolPackageUpdateResourceV3>(); SymbolPackageUpdateResourceV3 symbolPackageResource = await repository.GetResourceAsync<SymbolPackageUpdateResourceV3>();
await pushRes.Push(new List<string>{ "../../../../../src/isn.abst/bin/Release/isn.abst.1.0.24.nupkg" }, null, await pushRes.Push(new List<string>{ "../../../../../src/isn.abst/bin/Release/isn.abst.1.0.1.nupkg" }, null,
5000, false, GetApiKey, GetSymbolsApiKey, false, false, symbolPackageResource, logger); 5000, false, GetApiKey, GetSymbolsApiKey, false, false, symbolPackageResource, logger);
} }
// not yet from testing url a [Fact] // not yet from testing url a [Fact]
public async Task TestGetPackageUri() public async Task TestShouldGetPackageUri()
{ {
PackageSource source = new PackageSource("https://isn.pschneider.fr/v3/index.json"); PackageSource source = new PackageSource("https://isn.pschneider.fr/v3/index.json");
source.ProtocolVersion=3; source.ProtocolVersion=3;