Try to extract sourcePath into directory. If sourcePath is recognized as an archive it will be extracted and true returned; if not recognized then false will be returned. An Error is returned if the extraction command fails.
| 65 | // if not recognized then false will be returned. An Error is |
| 66 | // returned if the extraction command fails. |
| 67 | static Try<bool> extract( |
| 68 | const string& sourcePath, |
| 69 | const string& destinationDirectory) |
| 70 | { |
| 71 | Try<Nothing> result = Nothing(); |
| 72 | |
| 73 | Option<Subprocess::IO> in = None(); |
| 74 | Option<Subprocess::IO> out = None(); |
| 75 | vector<string> command; |
| 76 | |
| 77 | // Extract any .tar, .tgz, tar.gz, tar.bz2 or zip files. |
| 78 | if (strings::endsWith(sourcePath, ".tar") || |
| 79 | strings::endsWith(sourcePath, ".tgz") || |
| 80 | strings::endsWith(sourcePath, ".tar.gz") || |
| 81 | strings::endsWith(sourcePath, ".tbz2") || |
| 82 | strings::endsWith(sourcePath, ".tar.bz2") || |
| 83 | strings::endsWith(sourcePath, ".txz") || |
| 84 | strings::endsWith(sourcePath, ".tar.xz") || |
| 85 | strings::endsWith(sourcePath, ".zip")) { |
| 86 | Try<Nothing> result = archiver::extract(sourcePath, destinationDirectory); |
| 87 | if (result.isError()) { |
| 88 | return Error( |
| 89 | "Failed to extract archive '" + sourcePath + |
| 90 | "' to '" + destinationDirectory + "': " + result.error()); |
| 91 | } |
| 92 | return true; |
| 93 | } else if (strings::endsWith(sourcePath, ".gz")) { |
| 94 | // Unfortunately, libarchive can't extract bare files, so leave this to |
| 95 | // the 'gunzip' program, if it exists. |
| 96 | string pathWithoutExtension = sourcePath.substr(0, sourcePath.length() - 3); |
| 97 | string filename = Path(pathWithoutExtension).basename(); |
| 98 | string destinationPath = path::join(destinationDirectory, filename); |
| 99 | |
| 100 | command = {"gunzip", "-d", "-c"}; |
| 101 | in = Subprocess::PATH(sourcePath); |
| 102 | out = Subprocess::PATH(destinationPath); |
| 103 | } else { |
| 104 | return false; |
| 105 | } |
| 106 | |
| 107 | CHECK_GT(command.size(), 0u); |
| 108 | |
| 109 | Try<Subprocess> extractProcess = subprocess( |
| 110 | command[0], |
| 111 | command, |
| 112 | in.getOrElse(Subprocess::PATH(os::DEV_NULL)), |
| 113 | out.getOrElse(Subprocess::FD(STDOUT_FILENO)), |
| 114 | Subprocess::FD(STDERR_FILENO)); |
| 115 | |
| 116 | if (extractProcess.isError()) { |
| 117 | return Error( |
| 118 | "Failed to extract '" + sourcePath + "': '" + |
| 119 | strings::join(" ", command) + "' failed: " + |
| 120 | extractProcess.error()); |
| 121 | } |
| 122 | |
| 123 | // `status()` never fails or gets discarded. |
| 124 | int status = extractProcess->status()->get(); |
no test coverage detected