Skip to content

Commit

Permalink
Remove IFileSystem from *ArtifactRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
shenglol committed Dec 10, 2024
1 parent c4f90f5 commit 6349074
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,9 @@ public OciArtifactRegistryAssertions(OciArtifactRegistry OciArtifactRegistry) :

protected override string Identifier => "OciArtifactRegistry";

public AndConstraint<OciArtifactRegistryAssertions> HaveValidCachedModulesWithSources()
=> HaveValidCachedModules(withSource: true);
public AndConstraint<OciArtifactRegistryAssertions> HaveValidCachedModulesWithoutSources()
=> HaveValidCachedModules(withSource: false);

public AndConstraint<OciArtifactRegistryAssertions> HaveValidCachedModules(bool? withSource = null)
public AndConstraint<OciArtifactRegistryAssertions> HaveValidCachedModules(IFileSystem fileSystem, bool? withSource = null)
{
ShouldHaveValidCachedModules(Subject.FileSystem, Subject.CacheRootDirectory, withSource);
ShouldHaveValidCachedModules(fileSystem, Subject.CacheRootDirectory, withSource);
return new(this);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Bicep.Core.UnitTests/BicepTestConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public static class BicepTestConstants
public static readonly IServiceProvider EmptyServiceProvider = new Mock<IServiceProvider>(MockBehavior.Loose).Object;

public static IArtifactRegistryProvider CreateRegistryProvider(IServiceProvider services) =>
new DefaultArtifactRegistryProvider(services, FileResolver, FileSystem, ClientFactory, TemplateSpecRepositoryFactory, FeatureProviderFactory, BuiltInOnlyConfigurationManager);
new DefaultArtifactRegistryProvider(services, FileResolver, ClientFactory, TemplateSpecRepositoryFactory, FeatureProviderFactory, BuiltInOnlyConfigurationManager);

public static IModuleDispatcher CreateModuleDispatcher(IServiceProvider services) =>
new ModuleDispatcher(CreateRegistryProvider(services), IConfigurationManager.WithStaticConfiguration(BuiltInConfiguration));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ public async Task RestoreModuleWithSource_ShouldRestoreSourceToDisk(bool publish

await RestoreModule(ociRegistry, moduleReference);

ociRegistry.Should().HaveValidCachedModules(withSource: publishSource);
ociRegistry.Should().HaveValidCachedModules(BicepTestConstants.FileSystem, withSource: publishSource);
var actualSourceResult = ociRegistry.TryGetSource(moduleReference);

if (sources is { })
Expand Down
1 change: 0 additions & 1 deletion src/Bicep.Core.UnitTests/Utils/OciRegistryHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ public static (OciArtifactRegistry, MockRegistryBlobClient) CreateModuleRegistry

var registry = new OciArtifactRegistry(
BicepTestConstants.FileResolver,
BicepTestConstants.FileSystem,
clientFactory.Object,
featureProvider,
BicepTestConstants.BuiltInConfiguration,
Expand Down
10 changes: 4 additions & 6 deletions src/Bicep.Core/Registry/DefaultArtifactRegistryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,15 @@ namespace Bicep.Core.Registry
public class DefaultArtifactRegistryProvider : IArtifactRegistryProvider
{
private readonly IFileResolver fileResolver;
private readonly IFileSystem fileSystem;
private readonly IContainerRegistryClientFactory clientFactory;
private readonly ITemplateSpecRepositoryFactory templateSpecRepositoryFactory;
private readonly IFeatureProviderFactory featureProviderFactory;
private readonly IConfigurationManager configurationManager;
private readonly IServiceProvider serviceProvider;

public DefaultArtifactRegistryProvider(IServiceProvider serviceProvider, IFileResolver fileResolver, IFileSystem fileSystem, IContainerRegistryClientFactory clientFactory, ITemplateSpecRepositoryFactory templateSpecRepositoryFactory, IFeatureProviderFactory featureProviderFactory, IConfigurationManager configurationManager)
public DefaultArtifactRegistryProvider(IServiceProvider serviceProvider, IFileResolver fileResolver, IContainerRegistryClientFactory clientFactory, ITemplateSpecRepositoryFactory templateSpecRepositoryFactory, IFeatureProviderFactory featureProviderFactory, IConfigurationManager configurationManager)
{
this.fileResolver = fileResolver;
this.fileSystem = fileSystem;
this.clientFactory = clientFactory;
this.templateSpecRepositoryFactory = templateSpecRepositoryFactory;
this.featureProviderFactory = featureProviderFactory;
Expand All @@ -45,9 +43,9 @@ public ImmutableArray<IArtifactRegistry> Registries(Uri templateUri)
var builder = ImmutableArray.CreateBuilder<IArtifactRegistry>();

// Using IServiceProvider instead of constructor injection due to a dependency cycle
builder.Add(new LocalModuleRegistry(fileResolver, fileSystem, features, templateUri));
builder.Add(new OciArtifactRegistry(this.fileResolver, this.fileSystem, this.clientFactory, features, configuration, serviceProvider.GetRequiredService<IPublicRegistryModuleMetadataProvider>(), templateUri));
builder.Add(new TemplateSpecModuleRegistry(this.fileResolver, this.fileSystem, this.templateSpecRepositoryFactory, features, configuration, templateUri));
builder.Add(new LocalModuleRegistry(fileResolver, features, templateUri));
builder.Add(new OciArtifactRegistry(this.fileResolver, this.clientFactory, features, configuration, serviceProvider.GetRequiredService<IPublicRegistryModuleMetadataProvider>(), templateUri));
builder.Add(new TemplateSpecModuleRegistry(this.fileResolver, this.templateSpecRepositoryFactory, features, configuration, templateUri));

return builder.ToImmutableArray();
}
Expand Down
5 changes: 1 addition & 4 deletions src/Bicep.Core/Registry/ExternalArtifactRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,9 @@ public abstract class ExternalArtifactRegistry<TArtifactReference, TArtifactEnti
// interval at which we will retry acquiring the lock on the artifact directory in the cache
private static readonly TimeSpan ArtifactDirectoryContentionRetryInterval = TimeSpan.FromMilliseconds(300);

public IFileSystem FileSystem { get; }

protected ExternalArtifactRegistry(IFileResolver fileResolver, IFileSystem fileSystem)
protected ExternalArtifactRegistry(IFileResolver fileResolver)
{
this.FileResolver = fileResolver;
this.FileSystem = fileSystem;
}

protected IFileResolver FileResolver { get; }
Expand Down
64 changes: 25 additions & 39 deletions src/Bicep.Core/Registry/LocalModuleRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public class LocalModuleRegistry : ExternalArtifactRegistry<LocalModuleReference
private readonly IFeatureProvider featureProvider;
private readonly Uri parentModuleUri;

public LocalModuleRegistry(IFileResolver fileResolver, IFileSystem fileSystem, IFeatureProvider featureProvider, Uri parentModuleUri)
: base(fileResolver, fileSystem)
public LocalModuleRegistry(IFileResolver fileResolver, IFeatureProvider featureProvider, Uri parentModuleUri)
: base(fileResolver)
{
this.featureProvider = featureProvider;
this.parentModuleUri = parentModuleUri;
Expand Down Expand Up @@ -67,12 +67,12 @@ public override ResultWithDiagnosticBuilder<Uri> TryGetLocalArtifactEntryPointUr

if (reference.ArtifactType == ArtifactType.Extension)
{
if (TryGetTypesTgzUri(reference) is null)
if (this.TryGetTypesTgzFile(reference) is not { } tgzFile)
{
return new(x => x.FilePathCouldNotBeResolved(reference.Path, reference.ParentModuleUri.LocalPath));
}

return new(GetTypesTgzUri(reference));
return new(tgzFile.Uri.ToUri());
}

return new(localUri);
Expand Down Expand Up @@ -100,23 +100,14 @@ public override ResultWithDiagnosticBuilder<Uri> TryGetLocalArtifactEntryPointUr
return statuses;
}

public override async Task<IDictionary<ArtifactReference, DiagnosticBuilder.DiagnosticBuilderDelegate>> InvalidateArtifactsCache(IEnumerable<LocalModuleReference> references)
{
return await base.InvalidateArtifactsCacheInternal(references);
}

public override bool IsArtifactRestoreRequired(LocalModuleReference reference)
{
if (reference.ArtifactType != ArtifactType.Extension)
{
return false;
}
public override Task<IDictionary<ArtifactReference, DiagnosticBuilder.DiagnosticBuilderDelegate>> InvalidateArtifactsCache(IEnumerable<LocalModuleReference> references) =>
base.InvalidateArtifactsCacheInternal(references);

return !this.FileResolver.FileExists(this.GetTypesTgzUri(reference));
}
public override bool IsArtifactRestoreRequired(LocalModuleReference reference) =>
reference.ArtifactType == ArtifactType.Extension && !this.GetTypesTgzFile(reference).Exists();

public override Task PublishModule(LocalModuleReference moduleReference, BinaryData compiledArmTemplate, BinaryData? bicepSources, string? documentationUri, string? description)
=> throw new NotSupportedException("Local modules cannot be published.");
public override Task PublishModule(LocalModuleReference moduleReference, BinaryData compiledArmTemplate, BinaryData? bicepSources, string? documentationUri, string? description) =>
throw new NotSupportedException("Local modules cannot be published.");

public override async Task PublishExtension(LocalModuleReference reference, ExtensionPackage package)
{
Expand Down Expand Up @@ -151,8 +142,7 @@ public override ResultWithException<SourceArchive> TryGetSource(LocalModuleRefer
return new(new SourceNotAvailableException());
}

public override Uri? TryGetExtensionBinary(LocalModuleReference reference)
=> GetExtensionBinaryUri(reference);
public override Uri? TryGetExtensionBinary(LocalModuleReference reference) => GetExtensionBinaryFile(reference).Uri.ToUri();

protected override void WriteArtifactContentToCache(LocalModuleReference reference, LocalModuleEntity entity)
{
Expand All @@ -168,16 +158,14 @@ protected override void WriteArtifactContentToCache(LocalModuleReference referen
throw new InvalidOperationException($"The extension \"{reference}\" does not support architecture {architecture.Name}.");
}

var binaryUri = GetExtensionBinaryUri(reference);
this.FileResolver.Write(binaryUri, binary.Data.ToStream());
if (!OperatingSystem.IsWindows())
{
this.FileSystem.File.SetUnixFileMode(binaryUri.LocalPath, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
}
var binaryFile = GetExtensionBinaryFile(reference);

binary.Data.WriteTo(binaryFile);
binaryFile.MakeExecutable();
}

var typesUri = this.GetTypesTgzUri(reference);
this.FileResolver.Write(typesUri, entity.Package.Types.ToStream());
var typesTgzFile = this.GetTypesTgzFile(reference);
entity.Package.Types.WriteTo(typesTgzFile);
}

private IDirectoryHandle? TryGetArtifactDirectory(LocalModuleReference reference)
Expand Down Expand Up @@ -215,20 +203,18 @@ protected override IDirectoryHandle GetArtifactDirectory(LocalModuleReference re
return binaryData;
}

private Uri GetTypesTgzUri(LocalModuleReference reference) => GetFileUri(reference, "types.tgz");
private IFileHandle GetTypesTgzFile(LocalModuleReference reference) => this.GetFile(reference, "types.tgz");

private Uri? TryGetTypesTgzUri(LocalModuleReference reference) => TryGetFileUri(reference, "types.tgz");
private IFileHandle? TryGetTypesTgzFile(LocalModuleReference reference) => this.TryGetFile(reference, "types.tgz");

private Uri GetExtensionBinaryUri(LocalModuleReference reference) => GetFileUri(reference, "extension.bin");
private IFileHandle GetExtensionBinaryFile(LocalModuleReference reference) => this.GetFile(reference, "extension.bin");

protected override IFileHandle GetArtifactLockFile(LocalModuleReference reference) =>
this.TryGetArtifactDirectory(reference)?.GetFile("lock") ?? throw new InvalidOperationException("Failed to get artifact lock file.");
protected override IFileHandle GetArtifactLockFile(LocalModuleReference reference) => this.GetFile(reference, "lock");

private Uri GetFileUri(LocalModuleReference reference, string path)
=> TryGetFileUri(reference, path) ?? throw new InvalidOperationException($"Failed to resolve file path for {reference.FullyQualifiedReference}");
private IFileHandle GetFile(LocalModuleReference reference, string path) =>
this.TryGetFile(reference, path) ??
throw new InvalidOperationException($"Failed to resolve file for {reference.FullyQualifiedReference}.");

private Uri? TryGetFileUri(LocalModuleReference reference, string path) => TryGetArtifactDirectory(reference) is { } directory
? directory.GetFile(path).Uri.ToUri()
: null;
private IFileHandle? TryGetFile(LocalModuleReference reference, string path) => this.TryGetArtifactDirectory(reference)?.GetFile(path);
}
}
9 changes: 2 additions & 7 deletions src/Bicep.Core/Registry/OciArtifactRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@ public sealed class OciArtifactRegistry : ExternalArtifactRegistry<OciArtifactRe

public OciArtifactRegistry(
IFileResolver FileResolver,
IFileSystem fileSystem,
IContainerRegistryClientFactory clientFactory,
IFeatureProvider features,
RootConfiguration configuration,
IPublicRegistryModuleMetadataProvider publicRegistryModuleMetadataProvider,
Uri parentModuleUri)
: base(FileResolver, fileSystem)
: base(FileResolver)
{
this.cacheDirectory = features.CacheRootDirectory.GetDirectory(ArtifactReferenceSchemes.Oci);
this.client = new AzureContainerRegistryManager(clientFactory);
Expand Down Expand Up @@ -434,11 +433,7 @@ protected override void WriteArtifactContentToCache(OciArtifactReference referen

var file = this.GetArtifactFile(reference, ArtifactFileType.ExtensionBinary);
sourceData.WriteTo(file);

if (!OperatingSystem.IsWindows())
{
file.SetUnixFileMode(UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
}
file.MakeExecutable();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Bicep.Core/Registry/TemplateSpecModuleRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public class TemplateSpecModuleRegistry : ExternalArtifactRegistry<TemplateSpecM

private readonly Uri parentModuleUri;

public TemplateSpecModuleRegistry(IFileResolver fileResolver, IFileSystem fileSystem, ITemplateSpecRepositoryFactory repositoryFactory, IFeatureProvider featureProvider, RootConfiguration configuration, Uri parentModuleUri)
: base(fileResolver, fileSystem)
public TemplateSpecModuleRegistry(IFileResolver fileResolver, ITemplateSpecRepositoryFactory repositoryFactory, IFeatureProvider featureProvider, RootConfiguration configuration, Uri parentModuleUri)
: base(fileResolver)
{
this.repositoryFactory = repositoryFactory;
this.featureProvider = featureProvider;
Expand Down
3 changes: 1 addition & 2 deletions src/Bicep.IO/Abstraction/IFileHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ public interface IFileHandle : IIOHandle

void Delete();

[UnsupportedOSPlatform("windows")]
void SetUnixFileMode(UnixFileMode fileMode);
void MakeExecutable();

IFileLock? TryLock();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Bicep.IO/Abstraction/IOUri.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Bicep.IO.Abstraction
{
public static class GlobalSettings
{
public static bool LocalFilePathCaseSensitive { get; set; } = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
public static bool LocalFilePathCaseSensitive { get; set; } = OperatingSystem.IsLinux();

public static StringComparer LocalFilePathComparer => LocalFilePathCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;

Expand Down
9 changes: 7 additions & 2 deletions src/Bicep.IO/FileSystem/FileSystemFileHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,13 @@ public Stream OpenWrite()

public void Delete() => this.FileSystem.File.Delete(this.Uri.GetFileSystemPath());

[UnsupportedOSPlatform("windows")]
public void SetUnixFileMode(UnixFileMode fileMode) => this.FileSystem.File.SetUnixFileMode(this.Uri.GetFileSystemPath(), fileMode);
public void MakeExecutable()
{
if (!OperatingSystem.IsWindows())
{
this.FileSystem.File.SetUnixFileMode(this.Uri.GetFileSystemPath(), UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
}
}

public IFileLock? TryLock() => FileSystemStreamLock.TryCreate(this.FileSystem, this.Uri.GetFileSystemPath());
}
Expand Down

0 comments on commit 6349074

Please sign in to comment.