/// <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); } }
/// <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); }
/// <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); } }