file_manager.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const fs = require("fs");
  4. const path = require("path");
  5. const binaries_1 = require("../binaries");
  6. const cli_1 = require("../cli");
  7. const config_1 = require("../config");
  8. const downloaded_binary_1 = require("./downloaded_binary");
  9. const downloader_1 = require("./downloader");
  10. let logger = new cli_1.Logger('file_manager');
  11. /**
  12. * The File Manager class is where the webdriver manager will compile a list of
  13. * binaries that could be downloaded and get a list of previously downloaded
  14. * file versions.
  15. */
  16. class FileManager {
  17. /**
  18. * Create a directory if it does not exist.
  19. * @param outputDir The directory to create.
  20. */
  21. static makeOutputDirectory(outputDir) {
  22. try {
  23. fs.statSync(outputDir);
  24. }
  25. catch (e) {
  26. logger.info('creating folder ' + outputDir);
  27. fs.mkdirSync(outputDir);
  28. }
  29. }
  30. /**
  31. * For the operating system, check against the list of operating systems that the
  32. * binary is available for.
  33. * @param osType The operating system.
  34. * @param binary The class type to have access to the static properties.
  35. * @returns If the binary is available for the operating system.
  36. */
  37. static checkOS_(osType, binary) {
  38. for (let os in binary.os) {
  39. if (binaries_1.OS[os] == osType) {
  40. return true;
  41. }
  42. }
  43. return false;
  44. }
  45. /**
  46. * For the operating system, create a list that includes the binaries
  47. * for selenium standalone, chrome, and internet explorer.
  48. * @param osType The operating system.
  49. * @param alternateCDN URL of the alternative CDN to be used instead of the default ones.
  50. * @returns A binary map that are available for the operating system.
  51. */
  52. static compileBinaries_(osType, alternateCDN) {
  53. let binaries = {};
  54. if (FileManager.checkOS_(osType, binaries_1.Standalone)) {
  55. binaries[binaries_1.Standalone.id] = new binaries_1.Standalone(alternateCDN);
  56. }
  57. if (FileManager.checkOS_(osType, binaries_1.ChromeDriver)) {
  58. binaries[binaries_1.ChromeDriver.id] = new binaries_1.ChromeDriver(alternateCDN);
  59. }
  60. if (FileManager.checkOS_(osType, binaries_1.GeckoDriver)) {
  61. binaries[binaries_1.GeckoDriver.id] = new binaries_1.GeckoDriver(alternateCDN);
  62. }
  63. if (FileManager.checkOS_(osType, binaries_1.IEDriver)) {
  64. binaries[binaries_1.IEDriver.id] = new binaries_1.IEDriver(alternateCDN);
  65. }
  66. if (FileManager.checkOS_(osType, binaries_1.AndroidSDK)) {
  67. binaries[binaries_1.AndroidSDK.id] = new binaries_1.AndroidSDK(alternateCDN);
  68. }
  69. if (FileManager.checkOS_(osType, binaries_1.Appium)) {
  70. binaries[binaries_1.Appium.id] = new binaries_1.Appium(alternateCDN);
  71. }
  72. return binaries;
  73. }
  74. /**
  75. * Look up the operating system and compile a list of binaries that are available
  76. * for the system.
  77. * @param alternateCDN URL of the alternative CDN to be used instead of the default ones.
  78. * @returns A binary map that is available for the operating system.
  79. */
  80. static setupBinaries(alternateCDN) {
  81. return FileManager.compileBinaries_(config_1.Config.osType(), alternateCDN);
  82. }
  83. /**
  84. * Get the list of existing files from the output directory
  85. * @param outputDir The directory where binaries are saved
  86. * @returns A list of existing files.
  87. */
  88. static getExistingFiles(outputDir) {
  89. try {
  90. return fs.readdirSync(outputDir);
  91. }
  92. catch (e) {
  93. return [];
  94. }
  95. }
  96. /**
  97. * For the binary, operating system, and system architecture, look through
  98. * the existing files and the downloaded binary
  99. * @param binary The binary of interest
  100. * @param osType The operating system.
  101. * @param existingFiles A list of existing files.
  102. * @returns The downloaded binary with all the versions found.
  103. */
  104. static downloadedVersions_(binary, osType, arch, existingFiles) {
  105. let versions = [];
  106. for (let existPos in existingFiles) {
  107. let existFile = existingFiles[existPos];
  108. // use only files that have a prefix and suffix that we care about
  109. if (existFile.indexOf(binary.prefix()) === 0) {
  110. let editExistFile = existFile.replace(binary.prefix(), '');
  111. // if the suffix matches the executable suffix, add it
  112. if (binary.suffix() === binary.executableSuffix()) {
  113. versions.push(editExistFile.replace(binary.suffix(), ''));
  114. }
  115. else if (!existFile.endsWith('.zip') && !existFile.endsWith('.tar.gz') &&
  116. existFile.indexOf(binary.suffix()) === -1) {
  117. editExistFile = editExistFile.replace(binary.executableSuffix(), '');
  118. editExistFile = editExistFile.indexOf('_') === 0 ?
  119. editExistFile.substring(1, editExistFile.length) :
  120. editExistFile;
  121. versions.push(editExistFile);
  122. }
  123. }
  124. }
  125. if (versions.length === 0) {
  126. return null;
  127. }
  128. let downloadedBinary = new downloaded_binary_1.DownloadedBinary(binary);
  129. downloadedBinary.versions = versions;
  130. return downloadedBinary;
  131. }
  132. /**
  133. * Finds all the downloaded binary versions stored in the output directory.
  134. * @param outputDir The directory where files are downloaded and stored.
  135. * @returns An dictionary map of all the downloaded binaries found in the output folder.
  136. */
  137. static downloadedBinaries(outputDir) {
  138. let ostype = config_1.Config.osType();
  139. let arch = config_1.Config.osArch();
  140. let binaries = FileManager.setupBinaries();
  141. let existingFiles = FileManager.getExistingFiles(outputDir);
  142. let downloaded = {};
  143. for (let bin in binaries) {
  144. let binary = FileManager.downloadedVersions_(binaries[bin], ostype, arch, existingFiles);
  145. if (binary != null) {
  146. downloaded[binary.id()] = binary;
  147. }
  148. }
  149. return downloaded;
  150. }
  151. /**
  152. * Try to download the binary version.
  153. * @param binary The binary of interest.
  154. * @param outputDir The directory where files are downloaded and stored.
  155. * @returns Promise resolved to true for files downloaded, resolved to false for files not
  156. * downloaded because they exist, rejected if there is an error.
  157. */
  158. static downloadFile(binary, outputDir, callback) {
  159. return new Promise((resolve, reject) => {
  160. let outDir = config_1.Config.getSeleniumDir();
  161. let downloaded = FileManager.downloadedBinaries(outputDir);
  162. let contentLength = 0;
  163. // Pass options down to binary to make request to get the latest version to download.
  164. binary.getUrl(binary.version()).then(fileUrl => {
  165. binary.versionCustom = fileUrl.version;
  166. let filePath = path.resolve(outputDir, binary.filename());
  167. let fileName = binary.filename();
  168. // If we have downloaded the file before, check the content length
  169. if (downloaded[binary.id()]) {
  170. let downloadedBinary = downloaded[binary.id()];
  171. let versions = downloadedBinary.versions;
  172. let version = binary.versionCustom;
  173. for (let index in versions) {
  174. let v = versions[index];
  175. if (v === version) {
  176. contentLength = fs.statSync(filePath).size;
  177. downloader_1.Downloader.getFile(binary, fileUrl.url, fileName, outputDir, contentLength, callback)
  178. .then(downloaded => {
  179. resolve(downloaded);
  180. });
  181. }
  182. }
  183. }
  184. // We have not downloaded it before, or the version does not exist. Use the default content
  185. // length of zero and download the file.
  186. downloader_1.Downloader.getFile(binary, fileUrl.url, fileName, outputDir, contentLength, callback)
  187. .then(downloaded => {
  188. resolve(downloaded);
  189. });
  190. });
  191. });
  192. }
  193. /**
  194. * Removes the existing files found in the output directory that match the
  195. * binary prefix names.
  196. * @param outputDir The directory where files are downloaded and stored.
  197. */
  198. static removeExistingFiles(outputDir) {
  199. try {
  200. fs.statSync(outputDir);
  201. }
  202. catch (e) {
  203. logger.warn('path does not exist ' + outputDir);
  204. return;
  205. }
  206. let existingFiles = FileManager.getExistingFiles(outputDir);
  207. if (existingFiles.length === 0) {
  208. logger.warn('no files found in path ' + outputDir);
  209. return;
  210. }
  211. let binaries = FileManager.setupBinaries();
  212. existingFiles.forEach((file) => {
  213. for (let binPos in binaries) {
  214. let bin = binaries[binPos];
  215. if (file.indexOf(bin.prefix()) !== -1) {
  216. bin.remove(path.resolve(outputDir, file));
  217. logger.info('removed ' + file);
  218. }
  219. }
  220. });
  221. let metaFiles = [
  222. 'chrome-response.xml', 'gecko-response.json', 'iedriver-response.xml',
  223. 'standalone-response.xml', 'update-config.json'
  224. ];
  225. for (let metaFile of metaFiles) {
  226. try {
  227. let metaFilePath = path.resolve(outputDir, metaFile);
  228. if (fs.statSync(metaFilePath)) {
  229. fs.unlinkSync(metaFilePath);
  230. logger.info('removed ' + metaFile);
  231. }
  232. }
  233. catch (e) {
  234. }
  235. }
  236. }
  237. }
  238. exports.FileManager = FileManager;
  239. //# sourceMappingURL=file_manager.js.map