/// <nodoc/> public CompositeSharedOpaqueSealDirectory( AbsolutePath directoryRoot, IReadOnlyList <DirectoryArtifact> composedDirectories, PipProvenance provenance, ReadOnlyArray <StringId> tags, SealDirectoryContentFilter?contentFilter, SealDirectoryCompositionActionKind compositionAction) : base( directoryRoot, CollectionUtilities.EmptySortedReadOnlyArray <FileArtifact, OrdinalFileArtifactComparer>(OrdinalFileArtifactComparer.Instance), CollectionUtilities.EmptySortedReadOnlyArray <DirectoryArtifact, OrdinalDirectoryArtifactComparer>(OrdinalDirectoryArtifactComparer.Instance), SealDirectoryKind.SharedOpaque, provenance, tags, CollectionUtilities.EmptyArray <StringId>().ToReadOnlyArray()) { Contract.Requires(composedDirectories != null); Contract.Requires(compositionAction != SealDirectoryCompositionActionKind.None); Contract.Assert(compositionAction != SealDirectoryCompositionActionKind.NarrowDirectoryCone || (composedDirectories.Count == 1), "When action is NarrowDirectoryCone, exactly one directory must be provided."); ComposedDirectories = composedDirectories; CompositionActionKind = compositionAction; m_contentFilter = contentFilter; }
/// <nodoc/> public bool TryComposeSharedOpaqueDirectory( AbsolutePath directoryRoot, IReadOnlyList <DirectoryArtifact> contents, SealDirectoryCompositionActionKind actionKind, SealDirectoryContentFilter?contentFilter, [CanBeNull] string description, [CanBeNull] string[] tags, out DirectoryArtifact sharedOpaqueDirectory) { Contract.Requires(directoryRoot.IsValid); Contract.Requires(contents != null); Contract.Requires(actionKind.IsComposite()); if (PipGraph == null) { sharedOpaqueDirectory = DirectoryArtifact.CreateWithZeroPartialSealId(directoryRoot); return(true); } PipData usage = PipDataBuilder.CreatePipData(Context.StringTable, string.Empty, PipDataFragmentEscaping.NoEscaping, description != null ? new PipDataAtom[] { description } : generatePipDescription()); sharedOpaqueDirectory = PipGraph.ReserveSharedOpaqueDirectory(directoryRoot); var pip = new CompositeSharedOpaqueSealDirectory( directoryRoot, contents, CreatePipProvenance(usage), ToStringIds(tags), contentFilter, actionKind); // The seal directory is ready to be initialized, since the directory artifact has been reserved already pip.SetDirectoryArtifact(sharedOpaqueDirectory); sharedOpaqueDirectory = PipGraph.AddSealDirectory(pip, GetValuePipId()); if (!sharedOpaqueDirectory.IsValid) { return(false); } return(true); PipDataAtom[] generatePipDescription() { switch (actionKind) { case SealDirectoryCompositionActionKind.WidenDirectoryCone: return(new PipDataAtom[] { "'", directoryRoot, "' [", contents.Count.ToString(CultureInfo.InvariantCulture), " shared opaque directories, filter: ", contentFilter.HasValue ? $"'{contentFilter.Value.Regex}' (kind: {Enum.GetName(typeof(SealDirectoryContentFilter.ContentFilterKind), contentFilter.Value.Kind)})" : "''", "]" }); case SealDirectoryCompositionActionKind.NarrowDirectoryCone: return(new PipDataAtom[] { "'", directoryRoot, "' [ subdirectory of a shared opaque '", contents.FirstOrDefault().ToString(), "', filter: ", contentFilter.HasValue ? $"'{contentFilter.Value.Regex}' (kind: {Enum.GetName(typeof(SealDirectoryContentFilter.ContentFilterKind), contentFilter.Value.Kind)})" : "''", "]" }); default: throw new Exception($"Cannot create description for a CompositeSharedOpaqueSealDirectory with action kind {actionKind}"); } } }
/// <summary> /// Whether an action describes a composite shared opaque seal directory /// </summary> public static bool IsComposite(this SealDirectoryCompositionActionKind actionKind) => actionKind != SealDirectoryCompositionActionKind.None;