示例#1
0
        private Manifest GenerateManifest(string path, string?subdir)
        {
            if (Directory.Exists(path))
            {
                if (!string.IsNullOrEmpty(subdir))
                {
                    throw new OptionException(Resources.TooManyArguments + Environment.NewLine + subdir.EscapeArgument(), null);
                }

                var generator = new ManifestGenerator(path, _algorithm);
                Handler.RunTask(generator);
                return(generator.Manifest);
            }
            else if (File.Exists(path))
            {
                using var tempDir = new TemporaryDirectory("0install");

                using (var extractor = ArchiveExtractor.Create(path, tempDir, Archive.GuessMimeType(path)))
                {
                    extractor.Extract = subdir;
                    Handler.RunTask(extractor);
                }

                var generator = new ManifestGenerator(tempDir, _algorithm);
                Handler.RunTask(generator);
                return(generator.Manifest);
            }
            else
            {
                throw new FileNotFoundException(string.Format(Resources.FileOrDirNotFound, path));
            }
        }
示例#2
0
        /// <inheritdoc/>
        public string AddArchives(IEnumerable <ArchiveFileInfo> archiveInfos, ManifestDigest manifestDigest, ITaskHandler handler)
        {
            #region Sanity checks
            if (archiveInfos == null)
            {
                throw new ArgumentNullException(nameof(archiveInfos));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            if (manifestDigest.Best == null)
            {
                throw new ArgumentException("No known digest method", nameof(manifestDigest));
            }
            #endregion

            if (Contains(manifestDigest))
            {
                throw new ImplementationAlreadyInStoreException(manifestDigest);
            }
            Log.Info("Caching implementation: " + manifestDigest.Best);

            // Extract to temporary directory inside the cache so it can be validated safely (no manipulation of directory while validating)
            string tempDir = GetTempDir();
            try
            {
                // Extract archives "over each other" in order
                foreach (var archiveInfo in archiveInfos)
                {
                    try
                    {
                        using (var extractor = ArchiveExtractor.Create(archiveInfo.Path, tempDir, archiveInfo.MimeType, archiveInfo.StartOffset))
                        {
                            extractor.SubDir      = archiveInfo.SubDir;
                            extractor.Destination = archiveInfo.Destination;
                            extractor.Tag         = manifestDigest;
                            handler.RunTask(extractor);
                        }
                    }
                    #region Error handling
                    catch (IOException ex)
                    {
                        string source = archiveInfo.OriginalSource?.ToStringRfc() ?? archiveInfo.Path;
                        throw new IOException(string.Format(Resources.FailedToExtractArchive, source), ex);
                    }
                    #endregion
                }

                return(VerifyAndAdd(Path.GetFileName(tempDir), manifestDigest, handler));
            }
            finally
            {
                DeleteTempDir(tempDir);
            }
        }
示例#3
0
        /// <summary>
        /// Applies a <see cref="Archive"/> to a <see cref="TemporaryDirectory"/>.
        /// </summary>
        /// <param name="step">The <see cref="Archive"/> to apply.</param>
        /// <param name="localPath">The local path of the archive.</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">The <see cref="ITaskHandler"/> tag used by <paramref name="handler"/>; can be <c>null</c>.</param>
        /// <exception cref="IOException">A path specified in <paramref name="step"/> is illegal.</exception>
        public static void Apply([NotNull] this Archive step, [NotNull] string localPath, [NotNull] TemporaryDirectory workingDir, [NotNull] ITaskHandler handler, [CanBeNull] object tag = null)
        {
            #region Sanity checks
            if (step == null)
            {
                throw new ArgumentNullException(nameof(step));
            }
            if (string.IsNullOrEmpty(localPath))
            {
                throw new ArgumentNullException(nameof(localPath));
            }
            if (workingDir == null)
            {
                throw new ArgumentNullException(nameof(workingDir));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            #region Path validation
            if (!string.IsNullOrEmpty(step.Destination))
            {
                string destination = FileUtils.UnifySlashes(step.Destination);
                if (FileUtils.IsBreakoutPath(destination))
                {
                    throw new IOException(string.Format(Resources.RecipeInvalidPath, destination));
                }
            }
            #endregion

            if (string.IsNullOrEmpty(step.MimeType))
            {
                throw new IOException(Resources.UnknownArchiveType);
            }

            using (var extractor = ArchiveExtractor.Create(localPath, workingDir, step.MimeType))
            {
                extractor.SubDir      = step.Extract;
                extractor.Destination = FileUtils.UnifySlashes(step.Destination);
                extractor.Tag         = tag;
                handler.RunTask(extractor);
            }
        }
示例#4
0
        /// <summary>
        /// Applies a <see cref="Archive"/> to a <see cref="TemporaryDirectory"/>.
        /// </summary>
        /// <param name="step">The <see cref="Archive"/> to apply.</param>
        /// <param name="localPath">The local path of the archive.</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="Archive.Normalize"/> was not called for <paramref name="step"/>.</exception>
        public static void Apply(this Archive step, string localPath, TemporaryDirectory workingDir, ITaskHandler handler, object?tag = null)
        {
            #region Sanity checks
            if (step == null)
            {
                throw new ArgumentNullException(nameof(step));
            }
            if (string.IsNullOrEmpty(localPath))
            {
                throw new ArgumentNullException(nameof(localPath));
            }
            if (workingDir == null)
            {
                throw new ArgumentNullException(nameof(workingDir));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            if (!string.IsNullOrEmpty(step.Destination))
            {
                string destination = FileUtils.UnifySlashes(step.Destination);
                if (FileUtils.IsBreakoutPath(destination))
                {
                    throw new IOException(string.Format(Resources.RecipeInvalidPath, destination));
                }
            }

            using var extractor = ArchiveExtractor.Create(
                      localPath,
                      workingDir,
                      step.MimeType ?? throw new ArgumentException($"{nameof(step.Normalize)} was not called.", nameof(step)),
                      step.StartOffset);
            extractor.Extract      = step.Extract;
            extractor.TargetSuffix = FileUtils.UnifySlashes(step.Destination);
            extractor.Tag          = tag;
            handler.RunTask(extractor);
        }