示例#1
0
 /// <inheritdoc />
 public virtual void Copy(string uri, string target, IProgress <ProgressChanged> progress = null, IReadOnlyDictionary <string, object> additionalOptions = null)
 {
     FileSystemLocal.EnsureDirectory(Directory.GetParent(target).FullName);
     using (var saved = new FileStream(target, FileMode.CreateNew, FileAccess.Write, FileShare.None, buffer.Length))
     {
         GetRequest(uri, saved, progress, additionalOptions);
     }
 }
示例#2
0
        /// <summary>
        /// extract <paramref name="file"/> to <paramref name="extractPath"/> with unzip command.
        /// </summary>
        protected internal virtual void ExtractWithUnzipCommand(string file, string extractPath, bool isFallback = false)
        {
            // When called after a ZipArchive failed, perhaps
            // there is some files to overwrite
            var overwrite = isFallback ? "-o " : string.Empty;
            var command   = $"unzip -qq {overwrite}{ProcessExecutor.Escape(file)} -d {ProcessExecutor.Escape(extractPath)}";

            FileSystemLocal.EnsureDirectory(extractPath);

            SException processException;

            try
            {
                if (process.Execute(command, out _, out string stderr) == 0)
                {
                    return;
                }

                throw new RuntimeException(
                          $"Failed to execute {command} {Environment.NewLine}{Environment.NewLine} {stderr}");
            }
#pragma warning disable CA1031
            catch (SException ex)
#pragma warning restore CA1031
            {
                processException = ex;
            }

            if (isFallback)
            {
                ExceptionDispatchInfo.Capture(processException).Throw();
            }

            io.WriteError($"    {processException.Message}");
            io.WriteError($"    The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)");
            io.WriteError($"    Unzip with unzip command failed, falling back to {nameof(ZipArchive)}.");

            ExtractWithZipArchive(file, extractPath, true);
        }
示例#3
0
        /// <inheritdoc />
        public override void Install(IPackage package, string cwd, bool output)
        {
            if (output)
            {
                io.WriteError($"  - Installing <info>{package.GetName()}</info> (<comment>{package.GetVersionPrettyFull()}</comment>): Extracting archive");
            }
            else
            {
                io.WriteError("Extracting archive", false);
            }

            fileSystem.Delete(cwd);

            var temporaryDir = Path.Combine(
                GetTempDirectory(),
                "extract",
                Security.Md5(Guid.NewGuid().ToString()).Substring(0, 7));

            var downloadedFilePath = GetDownloadedFilePath(package, cwd);

            try
            {
                FileSystemLocal.EnsureDirectory(temporaryDir);

                try
                {
                    Extract(package, downloadedFilePath, temporaryDir);
                }
                catch
                {
                    // remove cache if the file was corrupted.
                    ClearLastCacheWrite(package);
                    throw;
                }

                // Expand a single top-level directory for a
                // better experience.
                string ExtractSingleDirAtTopLevel(string path)
                {
                    var contents = fileSystem.GetContents(path);
                    var files    = contents.GetFiles();
                    var dirs     = contents.GetDirectories();

                    files = Arr.Filter(files, (file) => !file.EndsWith(".DS_Store", StringComparison.Ordinal));

                    if ((dirs.Length + files.Length) != 1 || files.Length == 1)
                    {
                        return(path);
                    }

                    return(ExtractSingleDirAtTopLevel(dirs[0]));
                }

                fileSystem.Move(ExtractSingleDirAtTopLevel(temporaryDir), cwd);
            }
            catch
            {
                fileSystem.Delete(cwd);
                throw;
            }
            finally
            {
                fileSystem.Delete(temporaryDir);
                fileSystem.Delete(downloadedFilePath);
            }
        }