Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.18.0 #11

Merged
merged 14 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions src/Downloader/KuboDistributionArchitecture.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
namespace OwlCore.Kubo;

/// <summary>
/// Represents an architecture for a Kubo distribution.
/// </summary>
public class KuboDistributionArchitecture
{
/// <summary>
/// A relative download link for this architecture binary.
/// </summary>
public string? Link { get; set; }

/// <summary>
/// The Cid for this architecture binary.
/// </summary>
public string? Cid { get; set; }

/// <summary>
/// A hash that can be used to verify the downloaded data.
/// </summary>
public string? Sha512 { get; set; }
}
39 changes: 35 additions & 4 deletions src/Downloader/KuboDistributionData.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,47 @@
using System;
using System.Collections.Generic;

namespace OwlCore.Kubo;
namespace OwlCore.Kubo;

/// <summary>
/// Represents data about a Kubo distribution.
/// </summary>
public class KuboDistributionData
{
/// <summary>
/// A unique identifier for this distribution.
/// </summary>
public string? Id { get; set; }

/// <summary>
/// The version for this distribution.
/// </summary>
public string? Version { get; set; }

/// <summary>
/// The release link for this distribution.
/// </summary>
public string? ReleaseLink { get; set; }

/// <summary>
/// The name of this distribution.
/// </summary>
public string? Name { get; set; }

/// <summary>
/// The owner of this distribution.
/// </summary>
public string? Owner { get; set; }

/// <summary>
/// A description of this distribution.
/// </summary>
public string? Description { get; set; }

/// <summary>
/// The published date.
/// </summary>
public string? Date { get; set; }

/// <summary>
/// The platforms for this distribution.
/// </summary>
public Dictionary<string, KuboDistributionPlatform>? Platforms { get; set; }
}
3 changes: 3 additions & 0 deletions src/Downloader/KuboDistributionJsonContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace OwlCore.Kubo;

/// <summary>
/// Json context for serializing and deserializing <see cref="KuboDistributionData"/>.
/// </summary>
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(KuboDistributionData))]
public partial class KuboDistributionJsonContext : JsonSerializerContext
Expand Down
14 changes: 11 additions & 3 deletions src/Downloader/KuboDistributionPlatform.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
using System.Collections.Generic;

namespace OwlCore.Kubo;
namespace OwlCore.Kubo;

/// <summary>
/// Represents a distribution platform for Kubo.
/// </summary>
public class KuboDistributionPlatform
{
/// <summary>
/// The name of the distribution platform.
/// </summary>
public string? Name { get; set; }

/// <summary>
/// The architectures available for this distribution.
/// </summary>
public Dictionary<string, KuboDistributionArchitecture>? Archs { get; set; }
}
2 changes: 1 addition & 1 deletion src/Extensions/GenericKuboExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ public static async Task<IKey> GetOrCreateKeyAsync(this IKeyApi keyApi, string k
/// <param name="client">The client to use for communicating with the ipfs network.</param>
/// <param name="keyName">The name of the key to get or create.</param>
/// <param name="ipnsLifetime">The lifetime this ipns key should stay alive before needing to be rebroadcast by this node.</param>
/// <param name="nocache">Whether to use Kubo's cache when resolving ipns keys.</param>
/// <param name="size">The size of the key to create.</param>
/// <param name="cancellationToken">A token that can be used to cancel the ongoing task.</param>
/// <param name="getDefaultValue">Given the created ipns key, provides the default value to be published to it.</param>
/// <returns></returns>
public static async Task<(IKey Key, TResult Value)> GetOrCreateKeyAsync<TResult>(this ICoreApi client, string keyName, Func<IKey, TResult> getDefaultValue, TimeSpan ipnsLifetime, bool nocache, int size = 4096, CancellationToken cancellationToken = default)
{
// Get or create ipns key
Expand Down
7 changes: 3 additions & 4 deletions src/IpfsFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,12 @@ public virtual async Task<Stream> OpenStreamAsync(FileAccess accessMode = FileAc
if (accessMode.HasFlag(FileAccess.Write))
throw new NotSupportedException("Attempted to write data to an immutable file on IPFS.");

var fileData = await Client.Mfs.StatAsync($"/ipfs/{Id}", cancellationToken);
// Open and wrap ipfs stream
var stream = await Client.FileSystem.ReadFileAsync(Id, cancellationToken);

var fileData = await Client.Mfs.StatAsync($"/ipfs/{Id}", cancellationToken);
var streamWithLength = new LengthOverrideStream(stream, fileData.Size);

// Return in lazy seek-able wrapper.
return new LazySeekStream(streamWithLength);
return new ReadOnlyOverrideStream(streamWithLength);
}

/// <inheritdoc/>
Expand Down
6 changes: 4 additions & 2 deletions src/KuboBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -483,13 +483,14 @@ public virtual async Task ApplySettingsAsync(CancellationToken cancellationToken
/// Initializes the local node with the provided startup profile settings.
/// </summary>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
protected virtual async Task ApplyStartupProfileSettingsAsync(CancellationToken cancellationToken)
protected virtual Task ApplyStartupProfileSettingsAsync(CancellationToken cancellationToken)
{
Guard.IsNotNullOrWhiteSpace(_kuboBinaryFile?.Path);

// Startup profiles
foreach (var profile in StartupProfiles)
RunExecutable(_kuboBinaryFile, $"config --repo-dir \"{RepoPath}\" profile apply {profile}", throwOnError: true);
return Task.CompletedTask;
}

/// <summary>
Expand Down Expand Up @@ -526,13 +527,14 @@ protected virtual async Task ApplyPortSettingsAsync(CancellationToken cancellati
/// Initializes the local node with the provided routing settings.
/// </summary>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
protected virtual async Task ApplyRoutingSettingsAsync(CancellationToken cancellationToken)
protected virtual Task ApplyRoutingSettingsAsync(CancellationToken cancellationToken)
{
Guard.IsNotNullOrWhiteSpace(_kuboBinaryFile?.Path);

RunExecutable(_kuboBinaryFile, $"config Routing.Type {RoutingMode.ToString().ToLowerInvariant()} --repo-dir \"{RepoPath}\"", throwOnError: true);

RunExecutable(_kuboBinaryFile, $"config Routing.AcceleratedDHTClient \"{UseAcceleratedDHTClient.ToString().ToLower()}\" --json --repo-dir \"{RepoPath}\"", throwOnError: true);
return Task.CompletedTask;
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/MfsFolder.Modifiable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public virtual async Task<IChildFolder> CreateFolderAsync(string name, bool over
/// <inheritdoc/>
public virtual async Task<IChildFile> CreateFileAsync(string name, bool overwrite = false, CancellationToken cancellationToken = default)
{
await Client.Mfs.WriteAsync($"{Path}{name}", new MemoryStream(), new() { Create = true, Truncate = overwrite });
await Client.Mfs.WriteAsync($"{Path}{name}", new MemoryStream(), new() { Create = true, Truncate = overwrite }, cancellationToken);

return new MfsFile($"{Path}{name}", Client);
}
Expand Down
2 changes: 1 addition & 1 deletion src/MfsFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public virtual async IAsyncEnumerable<IStorableChild> GetItemsAsync(StorableType
}

/// <inheritdoc/>
public virtual async Task<IStorableChild> GetFirstByNameAsync(string name, CancellationToken cancellationToken = new CancellationToken())
public virtual async Task<IStorableChild> GetFirstByNameAsync(string name, CancellationToken cancellationToken = default)
{
var mfsPath = $"{Id}{name}";

Expand Down
19 changes: 11 additions & 8 deletions src/MfsStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace OwlCore.Kubo;
/// </summary>
public class MfsStream : Stream
{
private readonly string _path;
private long _length;

/// <summary>
Expand All @@ -22,7 +21,7 @@ public class MfsStream : Stream
/// <param name="client">The client to use for interacting with IPFS.</param>
public MfsStream(string path, long length, ICoreApi client)
{
_path = path;
Path = path;
_length = length;
Client = client;
}
Expand All @@ -31,6 +30,11 @@ public MfsStream(string path, long length, ICoreApi client)
/// The IPFS Client to use for retrieving the content.
/// </summary>
public ICoreApi Client { get; }

/// <summary>
/// The MFS path to the file. Relative to the root of MFS.
/// </summary>
public string Path { get; }

/// <inheritdoc/>
public override bool CanRead => true;
Expand All @@ -53,13 +57,13 @@ public MfsStream(string path, long length, ICoreApi client)
/// <inheritdoc/>
public override void Flush()
{
_ = Client.Mfs.FlushAsync(_path).Result;
_ = Client.Mfs.FlushAsync(Path).Result;
}

/// <inheritdoc/>
public override Task FlushAsync(CancellationToken cancellationToken)
{
return Client.Mfs.FlushAsync(_path, cancellationToken);
return Client.Mfs.FlushAsync(Path, cancellationToken);
}

/// <inheritdoc/>
Expand All @@ -71,10 +75,9 @@ public override int Read(byte[] buffer, int offset, int count)
/// <inheritdoc/>
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
Guard.IsLessThanOrEqualTo(offset + count, Length);
Guard.IsGreaterThanOrEqualTo(offset, 0);

var result = await Client.Mfs.ReadFileStreamAsync(_path, offset: Position + offset, count: count, cancellationToken);
var result = await Client.Mfs.ReadFileStreamAsync(Path, offset: Position, count: count, cancellationToken);
var bytes = await result.ToBytesAsync(cancellationToken);

for (var i = 0; i < bytes.Length; i++)
Expand Down Expand Up @@ -150,13 +153,13 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc
SetLength(Position + count);
}

await Client.Mfs.WriteAsync(_path, buffer, new() { Offset = Position, Count = count, Create = true }, cancellationToken);
await Client.Mfs.WriteAsync(Path, buffer, new() { Offset = Position, Count = count, Create = true }, cancellationToken);
Position += count;
}

static string GetFileName(string path)
{
var dirName = Path.GetDirectoryName(path);
var dirName = System.IO.Path.GetDirectoryName(path);
return path.Replace('/', '\\').Replace(dirName ?? string.Empty, string.Empty).Trim('/').Trim('\\');
}
}
33 changes: 24 additions & 9 deletions src/OwlCore.Kubo.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0;</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net8.0;</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>12.0</LangVersion>
<WarningsAsErrors>nullable</WarningsAsErrors>
Expand All @@ -14,13 +14,28 @@
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>

<Author>Arlo Godfrey</Author>
<Version>0.17.2</Version>
<Version>0.18.0</Version>
<Product>OwlCore</Product>
<Description>
An essential toolkit for Kubo, IPFS and the distributed web.
</Description>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<PackageReleaseNotes>
--- 0.18.0 ---
[Breaking]
Inherited breaking changes from OwlCore.Storage 0.12.0 and OwlCore.ComponentModel 0.9.0.
OwlCore.Kubo is no longer referencing the OwlCore meta-package, and is referencing required transient packages directly. Removes some uneeded transient dependencies that weren't required.
Removed support for net6.0 and net7.0, as they are out of support. Only netstandard2.0 and net8.0 are supported.
IpfsFile (and subsequently IpnsFile) no longer wraps the returned Stream in the LazySeekStream from OwlCore.ComponentModel. This can be applied separately if needed, but data larger than 2.1GB requires providing a custom backing stream.

[Fixes]
Inherited fixes from OwlCore.Storage 0.12.0 and OwlCore.ComponentModel 0.9.0.
Fixed CancellationToken not being passed to underlying API in MfsFolder.CreateFileAsync.

[Improvements]
Refactor MfsStream class to use Path property instead of private field.
Add missing code documentation to KuboDownloader json models.

--- 0.17.2 ---
[Fixes]
Fixed an issue where CachedNameApi was using the 'nocache' parameter to determine whether to use the cache layer, instead of simply delegating to the underlying API. 'nocache' has nothing to do with the caching layer, the parameter is only used by the Kubo API.
Expand Down Expand Up @@ -428,16 +443,16 @@ Added unit tests.
</ItemGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Common" Version="8.2.2" />
<PackageReference Include="CommunityToolkit.Diagnostics" Version="8.2.2" />
<PackageReference Include="CommunityToolkit.Common" Version="8.3.0" />
<PackageReference Include="CommunityToolkit.Diagnostics" Version="8.3.0" />
<PackageReference Include="IpfsShipyard.Ipfs.Http.Client" Version="0.5.0" />
<PackageReference Include="OwlCore" Version="0.6.0" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="OwlCore.ComponentModel" Version="0.8.1" />
<PackageReference Include="OwlCore.ComponentModel.Settings" Version="0.0.0" />
<PackageReference Include="OwlCore.Extensions" Version="0.8.0" />
<PackageReference Include="OwlCore.Storage" Version="0.11.3" />
<PackageReference Include="OwlCore.ComponentModel.Settings" Version="0.1.0" />
<PackageReference Include="OwlCore.Diagnostics" Version="0.0.0" />
<PackageReference Include="OwlCore.ComponentModel" Version="0.9.0" />
<PackageReference Include="OwlCore.Extensions" Version="0.9.0" />
<PackageReference Include="OwlCore.Storage" Version="0.12.0" />
<PackageReference Include="OwlCore.Storage.SharpCompress" Version="0.1.0" />
<PackageReference Include="PolySharp" Version="1.14.1">
<PrivateAssets>all</PrivateAssets>
Expand Down
Loading
Loading