/// <summary>
    /// Copies files or directories from another implementation fetched by an external 0install process.
    /// </summary>
    /// <param name="builder">The builder.</param>
    /// <param name="metadata">The path of the source and destination file or directory.</param>
    /// <param name="handler">A callback object used when the the user needs to be informed about IO tasks.</param>
    /// <exception cref="UnauthorizedAccessException">Access to a resource was denied.</exception>
    /// <exception cref="IOException">An IO operation failed.</exception>
    public static void CopyFrom(this IBuilder builder, CopyFromStep metadata, ITaskHandler handler)
    {
        if (metadata.Implementation == null)
        {
            throw new ArgumentException($"Must call {nameof(IRecipeStep.Normalize)}() first.", nameof(metadata));
        }

        handler.RunTask(new SimpleTask(string.Format(Resources.FetchingExternal, metadata.ID),
                                       () => ZeroInstallClient.Detect.FetchAsync(metadata.Implementation).Wait()));

        string path = ImplementationStores.Default().GetPath(metadata.Implementation);

        builder.CopyFrom(metadata, path, handler);
    }
Beispiel #2
0
 /// <summary>
 /// Copies files or directories from another implementation.
 /// </summary>
 /// <param name="builder">The builder.</param>
 /// <param name="metadata">The path of the source and destination file or directory.</param>
 /// <param name="path">The path of the implementation referenced by <paramref name="metadata"/>.</param>
 /// <param name="handler">A callback object used when the the user needs to be informed about IO tasks.</param>
 /// <exception cref="UnauthorizedAccessException">Access to a resource was denied.</exception>
 /// <exception cref="IOException">An IO operation failed.</exception>
 public static void CopyFrom(this IBuilder builder, CopyFromStep metadata, string path, ITaskHandler handler)
 => handler.RunTask(new ReadDirectory(path, builder.BuildDirectory(metadata.Destination)));
        /// <summary>
        /// Applies a <see cref="CopyFromStep"/> to a <see cref="TemporaryDirectory"/>. <see cref="FetchHandle.Register"/> must be called first on the same thread.
        /// </summary>
        /// <param name="step">The <see cref="Archive"/> to apply.</param>
        /// <param name="workingDir">The <see cref="TemporaryDirectory"/> to apply the changes to.</param>
        /// <param name="handler">A callback object used when the the user needs to be informed about progress.</param>
        /// <param name="tag">A tag used to associate composite task with a specific operation; can be null.</param>
        /// <exception cref="IOException">A path specified in <paramref name="step"/> is illegal.</exception>
        /// <exception cref="ArgumentException"><see cref="CopyFromStep.Implementation"/> is <c>null</c>. Please call <see cref="Feed.ResolveInternalReferences"/> first.</exception>
        /// <exception cref="InvalidOperationException"><see cref="FetchHandle.Register"/> was not called first.</exception>
        public static void Apply(this CopyFromStep step, TemporaryDirectory workingDir, ITaskHandler handler, object?tag = null)
        {
            #region Sanity checks
            if (step == null)
            {
                throw new ArgumentNullException(nameof(step));
            }
            if (workingDir == null)
            {
                throw new ArgumentNullException(nameof(workingDir));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            string source      = FileUtils.UnifySlashes(step.Source ?? "");
            string destination = FileUtils.UnifySlashes(step.Destination ?? "");
            if (FileUtils.IsBreakoutPath(source))
            {
                throw new IOException(string.Format(Resources.RecipeInvalidPath, source));
            }
            if (FileUtils.IsBreakoutPath(destination))
            {
                throw new IOException(string.Format(Resources.RecipeInvalidPath, destination));
            }

            if (step.Implementation == null)
            {
                throw new ArgumentException(string.Format(Resources.UnableToResolveRecipeReference, step, ""));
            }

            string sourcePath = Path.Combine(FetchHandle.Use(step.Implementation), source);
            if (Directory.Exists(sourcePath))
            {
                handler.RunTask(new CloneDirectory(sourcePath, workingDir)
                {
                    TargetSuffix = destination,
                    UseHardlinks = true,
                    Tag          = tag
                });
            }
            else if (File.Exists(sourcePath))
            {
                if (string.IsNullOrEmpty(destination))
                {
                    throw new IOException(string.Format(Resources.RecipeCopyFromDestinationMissing, step));
                }
                handler.RunTask(new CloneFile(sourcePath, workingDir)
                {
                    TargetSuffix   = Path.GetDirectoryName(destination),
                    TargetFileName = Path.GetFileName(destination),
                    UseHardlinks   = true,
                    Tag            = tag
                });
            }
            else
            {
                throw new IOException(string.Format(Resources.RecipeCopyFromSourceMissing, step));
            }
        }