winget.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. const crypto = require('crypto');
  2. const fs = require('fs');
  3. const http = require('http');
  4. const https = require('https');
  5. const path = require('path');
  6. const manifestDir = process.argv[2];
  7. const configuration = require('../package.json');
  8. const get = (url, timeout) => {
  9. return new Promise((resolve, reject) => {
  10. const httpModule = url.split(':').shift() === 'https' ? https : http;
  11. const request = httpModule.request(url, {}, (response) => {
  12. if (response.statusCode === 200) {
  13. const data = [];
  14. let position = 0;
  15. response.on('data', (chunk) => {
  16. data.push(chunk);
  17. position += chunk.length;
  18. process.stdout.write(' ' + position + ' bytes\r');
  19. });
  20. response.on('err', (err) => {
  21. reject(err);
  22. });
  23. response.on('end', () => {
  24. resolve(Buffer.concat(data));
  25. });
  26. }
  27. else if (response.statusCode === 302) {
  28. get(response.headers.location).then((data) => {
  29. resolve(data);
  30. }).catch((err) => {
  31. reject(err);
  32. });
  33. }
  34. else {
  35. const err = new Error("The web request failed with status code " + response.statusCode + " at '" + url + "'.");
  36. err.type = 'error';
  37. err.url = url;
  38. err.status = response.statusCode;
  39. reject(err);
  40. }
  41. });
  42. request.on("error", (err) => {
  43. reject(err);
  44. });
  45. if (timeout) {
  46. request.setTimeout(timeout, () => {
  47. request.destroy();
  48. const err = new Error("The web request timed out at '" + url + "'.");
  49. err.type = 'timeout';
  50. err.url = url;
  51. reject(err);
  52. });
  53. }
  54. request.end();
  55. });
  56. };
  57. const name = configuration.name;
  58. const version = configuration.version;
  59. const productName = configuration.productName;
  60. const publisher = configuration.author.name;
  61. const packageIdentifier = publisher.replace(' ', '') + '.' + productName;
  62. const copyright = 'Copyright (c) ' + publisher;
  63. const repository = 'https://github.com/' + configuration.repository;
  64. const url = repository + '/releases/download/v' + version + '/' + productName + '-Setup-' + version + '.exe';
  65. const extensions = configuration.build.fileAssociations.map((entry) => '- ' + entry.ext).sort().join('\n');
  66. get(url).then((data) => {
  67. const sha256 = crypto.createHash('sha256').update(data).digest('hex').toUpperCase();
  68. const versionDir = path.join(manifestDir, publisher[0].toLowerCase(), publisher.replace(' ', ''), productName, version);
  69. if (!fs.existsSync(versionDir)) {
  70. fs.mkdirSync(versionDir, { recursive: true });
  71. }
  72. const manifestFile = path.join(versionDir, packageIdentifier);
  73. fs.writeFileSync(manifestFile + '.yaml', [
  74. '# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.2.0.schema.json',
  75. 'PackageIdentifier: ' + packageIdentifier,
  76. 'PackageVersion: ' + version,
  77. 'DefaultLocale: en-US',
  78. 'ManifestType: version',
  79. 'ManifestVersion: 1.2.0',
  80. ''
  81. ].join('\n'));
  82. fs.writeFileSync(manifestFile + '.installer.yaml', [
  83. '# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.2.0.schema.json',
  84. 'PackageIdentifier: ' + packageIdentifier,
  85. 'PackageVersion: ' + version,
  86. 'Platform:',
  87. '- Windows.Desktop',
  88. 'InstallModes:',
  89. '- silent',
  90. '- silentWithProgress',
  91. 'Installers:',
  92. '- Architecture: x86',
  93. ' Scope: user',
  94. ' InstallerType: nullsoft',
  95. ' InstallerUrl: ' + url,
  96. ' InstallerSha256: ' + sha256,
  97. ' InstallerLocale: en-US',
  98. ' InstallerSwitches:',
  99. ' Custom: /NORESTART',
  100. ' UpgradeBehavior: install',
  101. '- Architecture: arm64',
  102. ' Scope: user',
  103. ' InstallerType: nullsoft',
  104. ' InstallerUrl: ' + url,
  105. ' InstallerSha256: ' + sha256,
  106. ' InstallerLocale: en-US',
  107. ' InstallerSwitches:',
  108. ' Custom: /NORESTART',
  109. ' UpgradeBehavior: install',
  110. 'FileExtensions:',
  111. extensions,
  112. 'ManifestType: installer',
  113. 'ManifestVersion: 1.2.0',
  114. ''
  115. ].join('\n'));
  116. fs.writeFileSync(manifestFile + '.locale.en-US.yaml', [
  117. '# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.2.0.schema.json',
  118. 'PackageIdentifier: ' + packageIdentifier,
  119. 'PackageVersion: ' + version,
  120. 'PackageName: ' + productName,
  121. 'PackageLocale: en-US',
  122. 'PackageUrl: ' + repository,
  123. 'Publisher: ' + publisher,
  124. 'PublisherUrl: ' + repository,
  125. 'PublisherSupportUrl: ' + repository + '/issues',
  126. 'Author: ' + publisher,
  127. 'License: ' + configuration.license,
  128. 'Copyright: ' + copyright,
  129. 'CopyrightUrl: ' + repository + '/blob/main/LICENSE',
  130. 'ShortDescription: ' + configuration.description,
  131. 'Description: ' + configuration.description,
  132. 'Moniker: ' + name,
  133. 'Tags:',
  134. '- machine-learning',
  135. '- deep-learning',
  136. '- neural-network',
  137. 'ManifestType: defaultLocale',
  138. 'ManifestVersion: 1.2.0',
  139. ''
  140. ].join('\n'));
  141. }).catch((err) => {
  142. /* eslint-disable */
  143. console.log(err.message);
  144. /* eslint-enable */
  145. });