diff --git a/DEBUGGING.md b/DEBUGGING.md new file mode 100644 index 0000000..f5b5303 --- /dev/null +++ b/DEBUGGING.md @@ -0,0 +1,51 @@ +# Debugging + +## Local Debugging + +To test the repochecker and debug into the script under vscode: + +1. Clone the repository to your local machine.\ + Best is that the directory is on the same level than your adapter repository. + +2. run npm install in the repochecker directory. + +3. switch to your adapter repository and create a new launch configuration: + +```json5 + { + "name": "Launch Program", + "program": "../iobroker.repochecker/index.js", // path to the repochecker repo + // args as entered on the commandline, arguments as a array + "args": ["https://github.com/klein0r/ioBroker.luftdaten","--local"], + "request": "launch", + "stopOnEntry": true, + "runtimeExecutable": "", //optional if needed + "skipFiles": [ + "/**" + ], + "type": "node" + }, +``` + +## Local Testing without debugging + +To test the repochecker under vscode: + +1. Clone the repository to your local machine.\ + Best is that the directory is on the same level than your adapter repository. + +2. run npm install in the repochecker directory. + +3. switch to your adapter repository and enter the following commandline in a new terminal + +```bash +node ..\ioBroker.repochecker\index.js https://github.com/klein0r/ioBroker.luftdaten --local +``` + +## Testing without installing + +The following command should be entered in the root of your repository: + +```bash +npx github:oweitman/iobroker.repochecker https://github.com/oweitman/ioBroker.luftdaten --local +``` diff --git a/README.md b/README.md index b87543e..dac7a86 100644 --- a/README.md +++ b/README.md @@ -1,215 +1,275 @@ # Adapter repository checker -This is a code for frontend and back-end of the service https://adapter-check.iobroker.in/ + +This is a code for frontend and back-end of the service If you want to add your adapter to the public ioBroker repository, all tests on this page must be OK. ## How to test via cli + You can pass your repository as a parameter to test -``npx @iobroker/repochecker [branch]`` +`npx @iobroker/repochecker [branch]` -``` +```bash npx @iobroker/repochecker https://github.com/ioBroker/ioBroker.javascript master ``` Branch (`master/main/dev`) is optional. +For extra debugging outputs you can pass the `--debug` parameter. + +For a local test you can pass the `--local` parameter. Most of the files are read localy. +The link to the github repository is still necessary because data from the project settings on github is also checked. + +Example: + +```bash +npx @iobroker/repochecker https://github.com/ioBroker/ioBroker.javascript --local +``` + ## Changelog + +### 3.2.0 (2024-10-27) + +- (oweitman) extension that the script also uses the local data for checking. + ### 3.1.4 (2024-10-26) -* (mcm1957) linter has been activated and issues reported have been fixed. -* (mcm1957) Blacklist for package/dependencies has been extended. -* (mcm1957) Recommend adapter-core 3.2.2 now. -* (mcm1957) Clearify test for "[E952] .npmignore not found". [#320] -* (mcm1957) Abort processing if iobroker.live not reachable. [#321] + +- (mcm1957) linter has been activated and issues reported have been fixed. +- (mcm1957) Blacklist for package/dependencies has been extended. +- (mcm1957) Recommend adapter-core 3.2.2 now. +- (mcm1957) Clearify test for "[E952] .npmignore not found". [#320] +- (mcm1957) Abort processing if iobroker.live not reachable. [#321] ### 3.1.3 (2024-10-11) -* (mcm1957) Checker no longer crash id no npm package exists. + +- (mcm1957) Checker no longer crash id no npm package exists. ### 3.1.2 (2024-10-04) -* (mcm1957) Require node 18 minimum as engines clause. + +- (mcm1957) Require node 18 minimum as engines clause. ### 3.1.1 (2024-10-04) -* (mcm1957) "[E166] 'common.mode: extension' is unknown" has been fixed [#308] -* (mcm1957) "[E904] file iob_npm.done found in repository, but not found in .gitignore" removed as covered by [E503]. [#309] -* (mcm1957) "[E500] node_modules found" has been retricted to adapetr root. [#297] -* (mcm1957) Do not check main entry if common.mode none or extension. -* (mcm1957) Change "[W113] Adapter should support compact mode" text and honor common.compact set to false. [#300] + +- (mcm1957) "[E166] 'common.mode: extension' is unknown" has been fixed [#308] +- (mcm1957) "[E904] file iob_npm.done found in repository, but not found in .gitignore" removed as covered by [E503]. [#309] +- (mcm1957) "[E500] node_modules found" has been retricted to adapetr root. [#297] +- (mcm1957) Do not check main entry if common.mode none or extension. +- (mcm1957) Change "[W113] Adapter should support compact mode" text and honor common.compact set to false. [#300] ### 3.1.0 (2024-09-29) -* (mcm1957) "@iobroker/plugin-sentry" blacklisted as dependency [#301] -* (mcm1957) Accept .ts files as main file too. [#303] -* (mcm1957) [E405] and [E426] incorrect path has been corrected. [#299] + +- (mcm1957) "@iobroker/plugin-sentry" blacklisted as dependency [#301] +- (mcm1957) Accept .ts files as main file too. [#303] +- (mcm1957) [E405] and [E426] incorrect path has been corrected. [#299] ### 3.0.7 (2024-09-19) -* (mcm1957) "[W523] 'package-lock.json"'not found in repo!" reduced to suggestion. [#298] + +- (mcm1957) "[W523] 'package-lock.json"'not found in repo!" reduced to suggestion. [#298] ### 3.0.6 (2024-09-13) -* (mcm1957) "[E124] Main file not found" no longer raised if common.nogit is set -* (mcm1957) 'Text of "common.main" is deprecated' has been adapted. [#266] -* (mcm1957) Ignore errors caused by complex .gitignor/.npmignore. [#288] + +- (mcm1957) "[E124] Main file not found" no longer raised if common.nogit is set +- (mcm1957) 'Text of "common.main" is deprecated' has been adapted. [#266] +- (mcm1957) Ignore errors caused by complex .gitignor/.npmignore. [#288] ### 3.0.5 (2024-09-13) -* (mcm1957) '@iobroker/dev-server' is valid as dev-dependency. [#260] + +- (mcm1957) '@iobroker/dev-server' is valid as dev-dependency. [#260] ### 3.0.4 (2024-09-12) -* (mcm1957) Abort with incorrect dependency definition fixed [#287] -* (mcm1957) Improve handling of malformed dependency definitions [#284] -* (mcm1957) Improve handling of malformed .releaseconfig.json files [#283] -* (mcm1957) Missing mandatory translations are considered an error now. [#277, #278] -* (mcm1957) '.npmignore found but "files" is used' is a warning now. [#274] -* (mcm1957) '@iobroker/dev-server' has been blacklisted as any dependency. [#260] -* (mcm1957) Do no longer require a js-controller dependecy for wwwOnly adapters. [#250] + +- (mcm1957) Abort with incorrect dependency definition fixed [#287] +- (mcm1957) Improve handling of malformed dependency definitions [#284] +- (mcm1957) Improve handling of malformed .releaseconfig.json files [#283] +- (mcm1957) Missing mandatory translations are considered an error now. [#277, #278] +- (mcm1957) '.npmignore found but "files" is used' is a warning now. [#274] +- (mcm1957) '@iobroker/dev-server' has been blacklisted as any dependency. [#260] +- (mcm1957) Do no longer require a js-controller dependecy for wwwOnly adapters. [#250] ### 3.0.3 (2024-09-12) -* (mcm1957) Check for iob_npm.done at .npmignore has been removed [#294] + +- (mcm1957) Check for iob_npm.done at .npmignore has been removed [#294] ### 3.0.2 (2024-09-11) -* (mcm1957) Handling of missing LICENSE file corrected. [#282] -* (mcm1957) [W126] Missing mandatory translation is error now. [#293] -* (mcm1957) Record repochcker version used for tests. -* (mcm1957) Record github commit-sha of last commit used for tests. + +- (mcm1957) Handling of missing LICENSE file corrected. [#282] +- (mcm1957) [W126] Missing mandatory translation is error now. [#293] +- (mcm1957) Record repochcker version used for tests. +- (mcm1957) Record github commit-sha of last commit used for tests. ### 3.0.0 (2024-09-10) -* (mcm1957) Error and warning numbering has been reviewed and duplicates removed. -* (mcm1957) index.js has been split into seperated modules. + +- (mcm1957) Error and warning numbering has been reviewed and duplicates removed. +- (mcm1957) index.js has been split into seperated modules. ### 2.10.0 (2024-08-19) -* (mcm1957) Suggestions ([Sxxx] have been added). + +- (mcm1957) Suggestions ([Sxxx] have been added). ### 2.9.1 (2024-08-12) -* (mcm1957) E162 - correct dependency check for js-controller. [#267]. -* (mcm1957) E605 - copyright year range including whitespaces is now accepted. [#269]. -* (mcm1957) E016 - missing vaiableexpansion has been added. [#263]. -* (mcm1957) E114 - typo at error message has been fixed [#261]. + +- (mcm1957) E162 - correct dependency check for js-controller. [#267]. +- (mcm1957) E605 - copyright year range including whitespaces is now accepted. [#269]. +- (mcm1957) E016 - missing vaiableexpansion has been added. [#263]. +- (mcm1957) E114 - typo at error message has been fixed [#261]. ### 2.9.0 (2024-07-29) -* (mcm1957) Adapt text if sources-dist(-stable).json need a correction [#97]. -* (mcm1957) Missing "common.mode" error text corrected [#249]. -* (mcm1957) Files "iob" and "iobroker" are disallowed now [#248]. -* (mcm1957) Checks related to @alcalzone/releasescript modified [#71]. -* (mcm1957) Text of E114 (missing adminUI) adapted. + +- (mcm1957) Adapt text if sources-dist(-stable).json need a correction [#97]. +- (mcm1957) Missing "common.mode" error text corrected [#249]. +- (mcm1957) Files "iob" and "iobroker" are disallowed now [#248]. +- (mcm1957) Checks related to @alcalzone/releasescript modified [#71]. +- (mcm1957) Text of E114 (missing adminUI) adapted. ### 2.8.1 (2024-07-28) -* (mcm1957) Check of js-controller version has been corrected [#247]. -* (mcm1957) Honor '>' at dependency checks too [#246]. + +- (mcm1957) Check of js-controller version has been corrected [#247]. +- (mcm1957) Honor '>' at dependency checks too [#246]. ### 2.8.0 (2024-07-28) -* (mcm1957) Copyright year check has been fixed for single year entries. -* (mcm1957) js-controller version check added [#233]. -* (mcm1957) Check for fixed version dependencies and for github dependencies [#233]. -* (mcm1957) Missing language files reduced to warning [#203]. -* (mcm1957) Missing .gitignore is considered an error now. -* (mcm1957) "common.noConfig" no longer reported as error if "common.adminUI" is present [#245]. -* (mcm1957) "common.noConfig" must match "common.adminUI" setting [#170]. + +- (mcm1957) Copyright year check has been fixed for single year entries. +- (mcm1957) js-controller version check added [#233]. +- (mcm1957) Check for fixed version dependencies and for github dependencies [#233]. +- (mcm1957) Missing language files reduced to warning [#203]. +- (mcm1957) Missing .gitignore is considered an error now. +- (mcm1957) "common.noConfig" no longer reported as error if "common.adminUI" is present [#245]. +- (mcm1957) "common.noConfig" must match "common.adminUI" setting [#170]. ### 2.7.2 (2024-07-26) -* (mcm1957) package-lock.json check fixed. + +- (mcm1957) package-lock.json check fixed. ### 2.7.1 (2024-07-26) -* (mcm1957) Reduce setTimeout/setInterval error to warning temporary. + +- (mcm1957) Reduce setTimeout/setInterval error to warning temporary. ### 2.7.0 (2024-07-26) -* (mcm1957) Some non trivial keywords related to adapter are enforced now [#234]. -* (mcm1957) Severity if [E105] / [W105] has been corrected [#204]. -* (mcm1957) Disallow 'globalDependencies' at package.json [#204]. -* (mcm1957) Several false positives for wwwOnly widgetadapters have been fixed [#230, #222]. -* (mcm1957) Missing .npmignore is now considered an error [#229]. -* (mcm1957) Usage of package.json 'files' section is now recommended. -* (mcm1957) If more than 7 common.news entries are present a warning is issued now [#232]. -* (mcm1957) Versions listed at common.news are checked to exist at npm now [#226]. -* (mcm1957) 'package-lock.json' is checked to exist at GitHub now [#188]. -* (mcm1957) travis checks have been removed [#237]. -* (mcm1957) Copyright year now honors commit year and npm publish year too [#237]. + +- (mcm1957) Some non trivial keywords related to adapter are enforced now [#234]. +- (mcm1957) Severity if [E105] / [W105] has been corrected [#204]. +- (mcm1957) Disallow 'globalDependencies' at package.json [#204]. +- (mcm1957) Several false positives for wwwOnly widgetadapters have been fixed [#230, #222]. +- (mcm1957) Missing .npmignore is now considered an error [#229]. +- (mcm1957) Usage of package.json 'files' section is now recommended. +- (mcm1957) If more than 7 common.news entries are present a warning is issued now [#232]. +- (mcm1957) Versions listed at common.news are checked to exist at npm now [#226]. +- (mcm1957) 'package-lock.json' is checked to exist at GitHub now [#188]. +- (mcm1957) travis checks have been removed [#237]. +- (mcm1957) Copyright year now honors commit year and npm publish year too [#237]. ### 2.6.1 (2024-06-24) -* (mcm1957) Check "[W156] Adapter should support admin 5 UI (jsonConfig)" checks for reactUi now. + +- (mcm1957) Check "[W156] Adapter should support admin 5 UI (jsonConfig)" checks for reactUi now. ### 2.6.0 (2024-06-24) -* (mcm1957) Check has been aded to ensure keywords and common.keywords are present. [#200] -* (mcm1957) Detection of react has been added, gulpfile.js is accepted for react based UIs now. [#223] + +- (mcm1957) Check has been aded to ensure keywords and common.keywords are present. [#200] +- (mcm1957) Detection of react has been added, gulpfile.js is accepted for react based UIs now. [#223] ### 2.5.1 (2024-06-24) -* (mcm1957) Suggestion to update dependencies to recommended version added. -* (mcm1957) Adapter-core recommended set to 3.1.6 [#220] + +- (mcm1957) Suggestion to update dependencies to recommended version added. +- (mcm1957) Adapter-core recommended set to 3.1.6 [#220] ### 2.5.0 (2024-05-30) -* (mcm1957) Check to ensure that dependency revisions are available at repository added. [#180] + +- (mcm1957) Check to ensure that dependency revisions are available at repository added. [#180] ### 2.4.0 (2024-05-30) -* (mcm1957) Add check to protect sensitive data. [#195] -* (mcm1957) Add check to verify that dependencies and globalDepencies are of type array. [#90] + +- (mcm1957) Add check to protect sensitive data. [#195] +- (mcm1957) Add check to verify that dependencies and globalDepencies are of type array. [#90] ### 2.3.1 (2024-05-07) -* (mcm1957) Reduce number of missing translation warnings. -* (mcm1957) Seperate between required and recommended translations. -* (mcm1957) Log missing translations in detail. + +- (mcm1957) Reduce number of missing translation warnings. +- (mcm1957) Seperate between required and recommended translations. +- (mcm1957) Log missing translations in detail. ### 2.3.0 (2024-05-07) -* (mcm1957) Elements marked as deprectaed added to blacklist. -* (mcm1957) Blacklist added to block elements at package.json and io-package.json. -* (mcm1957) Error [E000] will be raised now if repository cannot be accessed at all [#194]. -* (mcm1957) Reading of package.json and io-package.json has been moved to head of tests. -* (mcm1957) Check minimum and recommended node version at package.json (#160) -* (mcm1957) Raise an error if version at package.json is lower than latest release at npmjs [#192] + +- (mcm1957) Elements marked as deprectaed added to blacklist. +- (mcm1957) Blacklist added to block elements at package.json and io-package.json. +- (mcm1957) Error [E000] will be raised now if repository cannot be accessed at all [#194]. +- (mcm1957) Reading of package.json and io-package.json has been moved to head of tests. +- (mcm1957) Check minimum and recommended node version at package.json (#160) +- (mcm1957) Raise an error if version at package.json is lower than latest release at npmjs [#192] ### 2.2.3 (2024-03-29) -* (mcm1957) Checking of license has been improved -### 2.2.2 (2024-03-29) -* (mcm1957) Checking of adapter-core has been fixed -* (mcm1957) Load all potential interesting files, fixes [#149] +- (mcm1957) Checking of license has been improved + +### 2.2.2 (2024-03-29) + +- (mcm1957) Checking of adapter-core has been fixed +- (mcm1957) Load all potential interesting files, fixes [#149] ### 2.2.1 (2024-03-26) -* (mcm1957) Added check that own adapter is not listed at common.restartAdapters -* (mcm1957) Added check of version strings at common.news -* (mcm1957) Added check for recommended node version (node 18 for now) -* (mcm1957) Disallow common.mode == subscribe -* (mcm1957) Deprecate common.wakeup -* (mcm1957) Added check for adapter-core version (>= 3.0.6) + +- (mcm1957) Added check that own adapter is not listed at common.restartAdapters +- (mcm1957) Added check of version strings at common.news +- (mcm1957) Added check for recommended node version (node 18 for now) +- (mcm1957) Disallow common.mode == subscribe +- (mcm1957) Deprecate common.wakeup +- (mcm1957) Added check for adapter-core version (>= 3.0.6) ### 2.2.0 (2024-03-24) -* (klein0r) Added check for licenseInformation -* (klein0r) Added check for deprecated license -* (klein0r) Added check for required attribute common.tier -* (klein0r) Added check for disallowed attribute common.automaticUpgrade + +- (klein0r) Added check for licenseInformation +- (klein0r) Added check for deprecated license +- (klein0r) Added check for required attribute common.tier +- (klein0r) Added check for disallowed attribute common.automaticUpgrade ### 2.1.13 (2024-01-02) -* (bluefox) Corrected rule W156: adminUI.config === 'none' is allowed + +- (bluefox) Corrected rule W156: adminUI.config === 'none' is allowed ### 2.1.12 (2023-09-21) -* (bluefox) Added check of using '_' in adapter name + +- (bluefox) Added check of using '\_' in adapter name ### 2.1.11 (2023-09-05) -* (bluefox) Added check of iobroker.js-controller in dependencies + +- (bluefox) Added check of iobroker.js-controller in dependencies ### 2.1.7 (2023-08-14) -* (mcm57) Update index.js - fix typo in error message (packet.json) -* (mcm57) Update index.js - renumber E504/1 to 519 - fixes #112 + +- (mcm57) Update index.js - fix typo in error message (packet.json) +- (mcm57) Update index.js - renumber E504/1 to 519 - fixes #112 ### 2.1.6 (2022-12-08) -* (bluefox) added better error logging + +- (bluefox) added better error logging ### 2.1.5 (2022-12-07) -* (bluefox) added check of `.releaseconfig.json` file + +- (bluefox) added check of `.releaseconfig.json` file ### 2.1.4 (2022-08-19) -* (bluefox) Added check for adapter name: it may not start with '_' + +- (bluefox) Added check for adapter name: it may not start with '\_' ### 2.1.2 (2022-07-14) -* (bluefox) Fixed some errors + +- (bluefox) Fixed some errors ### 2.1.0 (2022-05-26) -* (bluefox) Added support for jsonConfig.json5 and jsonCustom.json5 + +- (bluefox) Added support for jsonConfig.json5 and jsonCustom.json5 ### 2.0.5 (2022-05-22) -* (bluefox) Made it possible to run with npx + +- (bluefox) Made it possible to run with npx ## License + The MIT License (MIT) Copyright (c) 2014-2024 Denis Haev diff --git a/index.js b/index.js index d5a3aa0..4c98089 100644 --- a/index.js +++ b/index.js @@ -111,11 +111,11 @@ function makeResponse(code, data) { } function check(request, ctx, callback) { -// console.log('PROCESS: ' + JSON.stringify(request)); + // console.log('PROCESS: ' + JSON.stringify(request)); if (!request.queryStringParameters.url) { - return callback(null, makeResponse(500, {error: 'No github URL provided'})); + return callback(null, makeResponse(500, { error: 'No github URL provided' })); } else { - const context = {checks: [], errors: [], warnings: []}; + const context = { checks: [], errors: [], warnings: [] }; let githubUrl = request.queryStringParameters.url; const githubBranch = request.queryStringParameters.branch; @@ -191,14 +191,22 @@ function getText(text, lang) { return text; } -common.setDebug(true); /* DEBUG*/ - if (typeof module !== 'undefined' && module.parent) { exports.handler = check; } else { let repoUrl = 'https://github.com/klein0r/ioBroker.luftdaten'; let repoBranch = null; + // check for local check + if (process.argv.includes('--local')) { + process.argv.splice(process.argv.indexOf('--local'), 1); + common.setLocal(true); + } + + if (process.argv.includes('--debug')) { + process.argv.splice(process.argv.indexOf('--debug'), 1); + common.setDebug(true); + } // Get url from parameters if possible if (process.argv.length > 2) { repoUrl = process.argv[2]; diff --git a/lib/M000_PackageJson.js b/lib/M000_PackageJson.js index d0f8f93..15dd712 100644 --- a/lib/M000_PackageJson.js +++ b/lib/M000_PackageJson.js @@ -271,7 +271,7 @@ async function checkPackageJson(context) { if (context.packageJson.dependencies) { for (const blacklist in blacklistedDependenciesPackageJson) { if (context.packageJson.dependencies[blacklist]) { - if (blacklistedDependenciesPackageJson[blacklist].err){ + if (blacklistedDependenciesPackageJson[blacklist].err) { context.errors.push(`[E050] ${blacklistedDependenciesPackageJson[blacklist].msg}`); } else { context.warnings.push(`[W051] ${blacklistedDependenciesPackageJson[blacklist].msg}`); @@ -283,7 +283,7 @@ async function checkPackageJson(context) { if (context.packageJson.devDependencies) { for (const blacklist in blacklistedDevDependenciesPackageJson) { if (context.packageJson.devDependencies[blacklist]) { - if (blacklistedDevDependenciesPackageJson[blacklist].err){ + if (blacklistedDevDependenciesPackageJson[blacklist].err) { context.errors.push(`[E052] ${blacklistedDevDependenciesPackageJson[blacklist].msg}`); } else { context.warnings.push(`[W053] ${blacklistedDevDependenciesPackageJson[blacklist].msg}`); @@ -328,16 +328,16 @@ async function checkPackageJson(context) { // 'engines': { 'node': '>= 18.1.2 < 19' } const nodeVal = context.packageJson.engines.node; const match = nodeVal.match(/^(?[<>=~]+)?\s*(?\d+(\.\d+(\.\d+)?)?(-\w+\.\d+)?)/m); - if ( ! match ) { + if (!match) { context.warnings.push(`[W027] Engines clause at at package.json ({'engines' : { 'node' : '${nodeVal}' } }") is not parseable.`); } else { - common.debug( `node check: ${JSON.stringify(match.groups)}`); - if ( match.groups.cmp !== '>' && match.groups.cmp !== '>=' ) { + common.debug(`node check: ${JSON.stringify(match.groups)}`); + if (match.groups.cmp !== '>' && match.groups.cmp !== '>=') { context.warnings.push(`[W028] Minimum node.js version ${recommendedNodeVersion} recommended. Please adapt "{'engines' : { 'node' >= '${match.groups.vers}' } }" at package.json.`); } else { - if ( ! compareVersions.compare( match.groups.vers, requiredNodeVersion, '>=')) { + if (!compareVersions.compare(match.groups.vers, requiredNodeVersion, '>=')) { context.errors.push(`[E029] Node.js ${requiredNodeVersion} is required as minimum, node.js ${recommendedNodeVersion} is recommended. Please adapt "{'engines' : { 'node' >= '${match.groups.vers}' } }" at package.json.`); - } else if ( ! compareVersions.compare( match.groups.vers, recommendedNodeVersion, '>=')) { + } else if (!compareVersions.compare(match.groups.vers, recommendedNodeVersion, '>=')) { context.warnings.push(`[W028] Minimum node.js version ${recommendedNodeVersion} recommended. Please adapt "{'engines' : { 'node' >= '${match.groups.vers}' } }" at package.json.`); } else { context.checks.push(`Correct node.js version ${match.groups.vers} requested by "engines" attribute at package.json.`); @@ -355,12 +355,12 @@ async function checkPackageJson(context) { const requiredVersion = dependenciesPackageJson[dependency].required; const recommendedVersion = dependenciesPackageJson[dependency].recommended; let dependencyVersion = context.packageJson.dependencies[`${dependency}`] || ''; - dependencyVersion = dependencyVersion.replace(/[\^~]/,'' ); + dependencyVersion = dependencyVersion.replace(/[\^~]/, ''); if (!dependencyVersion) { context.errors.push(`[E032] No dependency declared for ${dependency}. Please add "${dependency}":"${recommendedVersion}" to dependencies at package.json`); - } else if (! compareVersions.compare( dependencyVersion, requiredVersion, '>=' )) { + } else if (!compareVersions.compare(dependencyVersion, requiredVersion, '>=')) { context.errors.push(`[E033] ${dependency} ${dependencyVersion} specified. ${requiredVersion} is required as minimum, ${recommendedVersion} is recommended. Please update dependencies at package.json`); - } else if (! compareVersions.compare( dependencyVersion, recommendedVersion, '>=' )) { + } else if (!compareVersions.compare(dependencyVersion, recommendedVersion, '>=')) { context.warnings.push(`[W034] ${dependency} ${dependencyVersion} specified. ${recommendedVersion} is recommended. Please consider updating dependencies at package.json`); } else { context.checks.push('dependency ${dependency} ${dependencyVersion} is ok'); @@ -376,12 +376,12 @@ async function checkPackageJson(context) { const requiredVersion = devDependenciesPackageJson[dependency].required; const recommendedVersion = devDependenciesPackageJson[dependency].recommended; let dependencyVersion = context.packageJson.devDependencies[`${dependency}`] || ''; - dependencyVersion = dependencyVersion.replace(/[\^~]/,'' ); + dependencyVersion = dependencyVersion.replace(/[\^~]/, ''); if (!dependencyVersion) { context.errors.push(`[E035] No devDependency declared for ${dependency}. Please add "${dependency}":"${recommendedVersion}" to devDependencies at package.json`); - } else if (! compareVersions.compare( dependencyVersion, requiredVersion, '>=' )) { + } else if (!compareVersions.compare(dependencyVersion, requiredVersion, '>=')) { context.errors.push(`[E036] ${dependency} ${dependencyVersion} specified. ${requiredVersion} is required as minimum, ${recommendedVersion} is recommended. Please update devDependencies at package.json`); - } else if (! compareVersions.compare( dependencyVersion, recommendedVersion, '>=' )) { + } else if (!compareVersions.compare(dependencyVersion, recommendedVersion, '>=')) { context.warnings.push(`[W037] ${dependency} ${dependencyVersion} specified. ${recommendedVersion} is recommended. Please consider updating devDependencies at package.json`); } else { context.checks.push('devDependency ${dependency} ${dependencyVersion} is ok'); @@ -400,8 +400,8 @@ async function checkPackageJson(context) { ]; for (const dependency in context.packageJson.dependencies) { if (!context.packageJson.dependencies[dependency].startsWith('^') && - !context.packageJson.dependencies[dependency].startsWith('~') && - !context.packageJson.dependencies[dependency].startsWith('>') + !context.packageJson.dependencies[dependency].startsWith('~') && + !context.packageJson.dependencies[dependency].startsWith('>') ) { if (context.packageJson.dependencies[dependency].toLowerCase().includes('github.com')) { context.warnings.push(`[W043] dependency should not require a github version. Please change "${dependency}:${context.packageJson.dependencies[dependency]}"`); @@ -415,8 +415,8 @@ async function checkPackageJson(context) { for (const dependency in context.packageJson.devDependencies) { if (!context.packageJson.devDependencies[dependency].startsWith('^') && - !context.packageJson.devDependencies[dependency].startsWith('~') && - !context.packageJson.devDependencies[dependency].startsWith('>') + !context.packageJson.devDependencies[dependency].startsWith('~') && + !context.packageJson.devDependencies[dependency].startsWith('>') ) { if (context.packageJson.devDependencies[dependency].toLowerCase().includes('github.com')) { context.warnings.push(`[W045] devDependency should not require github versions. Please change "${dependency}:${context.packageJson.devDependencies[dependency]}"`); @@ -437,7 +437,7 @@ async function checkPackageJson(context) { //console.log(` check ${log}`); tmp = tmp[element]; if (!tmp) { - //console.log(` ${log} does not exist`); + //console.log(` ${log} does not exist`); break; } } @@ -448,9 +448,9 @@ async function checkPackageJson(context) { context.warnings.push(`[W038] ${blacklistPackageJson[blacklist].msg}`); } } - // else { - // console.log(`blacklist ${blacklist} no match`); - // } + // else { + // console.log(`blacklist ${blacklist} no match`); + // } } context.checks.push('"blacklist (package)" checked.'); @@ -462,10 +462,10 @@ async function checkPackageJson(context) { const recommendedKeywords = ['ioBroker']; common.debug(`package.keywords: "${context.packageJson.keywords.join(', ')}"`); common.debug(`filtered: "${context.packageJson.keywords.filter(keyword => !ignoredKeywords.includes(keyword.toLowerCase()))}"`); - if (context.packageJson.keywords.filter(keyword => !ignoredKeywords.includes(keyword.toLowerCase())).length === 0 ) { + if (context.packageJson.keywords.filter(keyword => !ignoredKeywords.includes(keyword.toLowerCase())).length === 0) { context.errors.push(`[E049] "keywords" within package.json must contain some keywords besides "${context.packageJson.keywords.join(', ')}" related to adapter`); } - if (! recommendedKeywords.filter(keyword => context.packageJson.keywords.includes(keyword)).length > 0) { + if (!recommendedKeywords.filter(keyword => context.packageJson.keywords.includes(keyword)).length > 0) { context.warnings.push(`[W040] "keywords" within package.json should contain "${recommendedKeywords.join(', ')}"`); } if (forbiddenKeywords.filter(keyword => context.packageJson.keywords.map(k => k.toLowerCase()).includes(keyword)).length > 0) { diff --git a/lib/M100_IOPackageJson.js b/lib/M100_IOPackageJson.js index ab4684b..ed07496 100644 --- a/lib/M100_IOPackageJson.js +++ b/lib/M100_IOPackageJson.js @@ -33,39 +33,39 @@ let requiredJsControllerVersion = '4.0.24'; const blacklistIOPackageJson = { installedFrom: { msg: '"installedFrom" is invalid at io-package.json. Please remove.', - err:true + err: true }, 'common.installedFrom': { msg: '"common.installedFrom" is invalid. Please remove from io-package.json.', - err:true + err: true }, 'common.title': { msg: '"common.title" is deprecated and replaced by "common.titleLang". Please remove from io-package.json.', - err:false + err: false }, 'common.main': { msg: '"common.main" is deprecated and ignored. Please remove from io-package.json. Executable is defined by entry "main" at package.json.', - err:false + err: false }, 'common.materialize': { msg: '"common.materialize" is deprecated for admin >= 5 at io-package.json. Please use property "adminUI".', - err:false + err: false }, 'common.materializeTab': { msg: '"common.materializeTab" is deprecated for admin >= 5 at io-package.json. Please use property "adminUI".', - err:false + err: false }, 'common.noConfig': { msg: '"common.noConfig" is deprecated for admin >= 5 at io-package.json. Please use property "adminUI.config":"none".', - err:false + err: false }, 'common.subscribe': { msg: '"common.subscribe" will be removed with js-controller >= 6. Please remove from io-package.json and adapt code if required.', - err:true + err: true }, 'common.wakeup': { msg: '"common.wakeup" is deprecated and ignored. Please remove from io-package.json.', - err:true + err: true }, }; @@ -99,22 +99,22 @@ async function checkIOPackageJson(context) { let suspiciousKeys = Object.keys(context.ioPackageJson.native) || []; // console.log(`native keys: ${suspiciousKeys.join()}`); //suspiciousKeys = suspiciousKeys.filter( key => regex.test(key)); - suspiciousKeys = suspiciousKeys.filter( key => suspiciousPhrases.includes(key.toLowerCase())); + suspiciousKeys = suspiciousKeys.filter(key => suspiciousPhrases.includes(key.toLowerCase())); // console.log(`suspicious keys: ${suspiciousKeys.join()}`); - if ( suspiciousKeys.length) { + if (suspiciousKeys.length) { if (context.ioPackageJson.protectedNative) { - const missingProtected = suspiciousKeys.filter( key => !context.ioPackageJson.protectedNative.includes(key)); - if (missingProtected.length) context.warnings.push( `[W173] Potential sensitive data "${missingProtected.join()}" not listed at "protectedNative" in io-package.json`); + const missingProtected = suspiciousKeys.filter(key => !context.ioPackageJson.protectedNative.includes(key)); + if (missingProtected.length) context.warnings.push(`[W173] Potential sensitive data "${missingProtected.join()}" not listed at "protectedNative" in io-package.json`); } else { - context.warnings.push( `[W173] Potential sensitive data "${suspiciousKeys.join()}" not listed at "protectedNative" in io-package.json`); + context.warnings.push(`[W173] Potential sensitive data "${suspiciousKeys.join()}" not listed at "protectedNative" in io-package.json`); } if (context.ioPackageJson.encryptedNative) { - const missingProtected = suspiciousKeys.filter( key => !context.ioPackageJson.encryptedNative.includes(key)); - if (missingProtected.length) context.warnings.push( `[W174] Potential sensitive data "${missingProtected.join()}" not listed at "encryptedNative" in io-package.json`); + const missingProtected = suspiciousKeys.filter(key => !context.ioPackageJson.encryptedNative.includes(key)); + if (missingProtected.length) context.warnings.push(`[W174] Potential sensitive data "${missingProtected.join()}" not listed at "encryptedNative" in io-package.json`); } else { - context.warnings.push( `[W174] Potential sensitive data "${suspiciousKeys.join()}" not listed at "encryptedNative" in io-package.json`); + context.warnings.push(`[W174] Potential sensitive data "${suspiciousKeys.join()}" not listed at "encryptedNative" in io-package.json`); } } } @@ -165,7 +165,7 @@ async function checkIOPackageJson(context) { } missingLang = common.checkLanguages(context.ioPackageJson.common.titleLang, context.cfg.allowedLanguages); - missingLang = missingLang.filter( lang => !context.cfg.requiredLanguages.includes(lang)); + missingLang = missingLang.filter(lang => !context.cfg.requiredLanguages.includes(lang)); if (missingLang.length) { missingLang = [... new Set(missingLang)]; // make unique context.warnings.push(`[W127] Missing suggested translation into ${missingLang.join()} of "common.titleLang" in io-package.json.`); @@ -215,7 +215,7 @@ async function checkIOPackageJson(context) { } missingLang = common.checkLanguages(context.ioPackageJson.common.desc, context.cfg.allowedLanguages); - missingLang = missingLang.filter( lang => !context.cfg.requiredLanguages.includes(lang)); + missingLang = missingLang.filter(lang => !context.cfg.requiredLanguages.includes(lang)); if (missingLang.length) { missingLang = [... new Set(missingLang)]; // make unique context.warnings.push(`[W134] Missing suggested translation into ${missingLang.join()} of "common.desc" in io-package.json.`); @@ -223,7 +223,7 @@ async function checkIOPackageJson(context) { } } - if (! context.ioPackageJson.common.keywords) { + if (!context.ioPackageJson.common.keywords) { context.errors.push('[E169] "common.keywords" must be an array within io-package.json and contain some useful keywords'); } else { const forbiddenKeywords = ['iobroker', 'adapter', 'smart home']; @@ -267,7 +267,7 @@ async function checkIOPackageJson(context) { } if (!context.ioPackageJson.common.compact && !context.ioPackageJson.common.onlyWWW) { - if (context.ioPackageJson.common.compact === undefined ) { + if (context.ioPackageJson.common.compact === undefined) { context.warnings.push('[W113] Please test whether adapter can support compact mode, if not set "common.compact:false" at io-package.json'); } else { context.warnings.push('[S139] Please evaluate whether adapter can be modified to support compact mode'); @@ -277,15 +277,15 @@ async function checkIOPackageJson(context) { } if (context.ioPackageJson.common.noConfig && - (context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config !== 'none') + (context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config !== 'none') ) { - context.errors.push('[E114] "common.noConfig=true" requires "common.adminUI.config" to be set to "none"' ); + context.errors.push('[E114] "common.noConfig=true" requires "common.adminUI.config" to be set to "none"'); } if (!context.ioPackageJson.common.materialize && - !(context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config === 'json') && - !(context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config === 'materialize') && - !(context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config === 'html') && - !(context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config === 'none') + !(context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config === 'json') && + !(context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config === 'materialize') && + !(context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config === 'html') && + !(context.ioPackageJson.common.adminUI && context.ioPackageJson.common.adminUI.config === 'none') ) { context.errors.push('[E129] Admin support not specified. Please add "common.adminUI.config = json|materialize|html|none"'); } else { @@ -332,7 +332,7 @@ async function checkIOPackageJson(context) { } if (!context.packageJson || - context.ioPackageJson.common?.licenseInformation?.license !== context.packageJson.license) { + context.ioPackageJson.common?.licenseInformation?.license !== context.packageJson.license) { context.errors.push('[E117] Licenses in package.json and in io-package.json are different'); } else { context.checks.push('"common.licenseInformation.license" is equal in package.json and in io-package.json'); @@ -416,20 +416,20 @@ async function checkIOPackageJson(context) { context.errors.push(`[E136] No "common.news" found for actual version ${context.ioPackageJson.common.version} in io-package.json`); } - let missingLang =[]; + let missingLang = []; Object.keys(context.ioPackageJson.common.news).forEach(version => { - missingLang = missingLang.concat( common.checkLanguages(context.ioPackageJson.common.news[version], context.cfg.requiredLanguages) ); + missingLang = missingLang.concat(common.checkLanguages(context.ioPackageJson.common.news[version], context.cfg.requiredLanguages)); }); if (missingLang.length) { missingLang = [... new Set(missingLang)]; // make unique context.errors.push(`[E145] Missing mandatory translation into ${missingLang.join()} of some "common.news" in io-package.json.`); } - missingLang =[]; + missingLang = []; Object.keys(context.ioPackageJson.common.news).forEach(version => { missingLang = missingLang.concat(common.checkLanguages(context.ioPackageJson.common.news[version], context.cfg.allowedLanguages)); }); - missingLang = missingLang.filter( lang => !context.cfg.requiredLanguages.includes(lang)); + missingLang = missingLang.filter(lang => !context.cfg.requiredLanguages.includes(lang)); if (missingLang.length) { missingLang = [... new Set(missingLang)]; // make unique context.warnings.push(`[W154] Missing suggested translation into ${missingLang.join()} of some "common.news" in io-package.json.`); @@ -529,16 +529,16 @@ async function checkIOPackageJson(context) { increase dependency as required by addition features */ if (context.ioPackageJson && context.ioPackageJson.common && context.ioPackageJson.common.supportedMessges) { - requiredJsControllerVersion = common.maxVersion( requiredJsControllerVersion, '5.0.18'); + requiredJsControllerVersion = common.maxVersion(requiredJsControllerVersion, '5.0.18'); } if (context.ioPackageJson && context.ioPackageJson.common && context.ioPackageJson.common.nodeProcessParams) { - requiredJsControllerVersion = common.maxVersion( requiredJsControllerVersion, '5.0.18'); + requiredJsControllerVersion = common.maxVersion(requiredJsControllerVersion, '5.0.18'); } - if ( currentJsControllerVersion && compareVersions.compare( requiredJsControllerVersion, currentJsControllerVersion, '>' )) { + if (currentJsControllerVersion && compareVersions.compare(requiredJsControllerVersion, currentJsControllerVersion, '>')) { context.errors.push(`[E157] js-controller ${currentJsControllerVersion} listed as dependency but ${requiredJsControllerVersion} is required as minimum, ${recommendedJsControllerVersion} is recommended. Please update dependency at io-package.json.`); - } else if ( currentJsControllerVersion && compareVersions.compare( recommendedJsControllerVersion, currentJsControllerVersion, '>' )) { + } else if (currentJsControllerVersion && compareVersions.compare(recommendedJsControllerVersion, currentJsControllerVersion, '>')) { context.warnings.push(`[W156] js-controller ${currentJsControllerVersion} listed as dependency but ${recommendedJsControllerVersion} is recommended. Please consider updating dependency at io-package.json.`); } @@ -589,15 +589,15 @@ async function checkIOPackageJson(context) { } for (const blacklist in blacklistIOPackageJson) { - //console.log(`checking blacklist ${blacklist}`); + //console.log(`checking blacklist ${blacklist}`); let tmp = context.ioPackageJson; let log = ''; for (const element of blacklist.split('.')) { log = `${log}.${element}`; //console.log(` check ${log}`); tmp = tmp[element]; - if ( !tmp ) { - //console.log(` ${log} does not exist`); + if (!tmp) { + //console.log(` ${log} does not exist`); break; } } @@ -608,15 +608,21 @@ async function checkIOPackageJson(context) { context.warnings.push(`[W184] ${blacklistIOPackageJson[blacklist].msg}`); } } - //else { - // console.log(`blacklist ${blacklist} no match`); - //} + //else { + // console.log(`blacklist ${blacklist} no match`); + //} } context.checks.push('"blacklist (io-package)" checked.'); if (context.ioPackageJson.common.extIcon) { try { - const icon = await common.downloadFile(context.ioPackageJson.common.extIcon, null, true); + let icon = null; + if (common.isLocal()) { + const url = context.ioPackageJson.common.extIcon.replace(context.githubUrl, ''); + icon = await common.downloadFile(null, url, true); + } else { + icon = await common.downloadFile(context.ioPackageJson.common.extIcon, null, true); + } context.checks.push('"extIcon" could be downloaded'); const image = sizeOf(icon); @@ -631,7 +637,7 @@ async function checkIOPackageJson(context) { } } } catch (e) { - common.debug (e); + common.debug(e); context.errors.push(`[E125] External icon not found under URL: ${context.ioPackageJson.common.extIcon}`); } } @@ -641,7 +647,7 @@ async function checkIOPackageJson(context) { await common.downloadFile(context.githubUrl, `/${context.packageJson.main}`); context.checks.push(`${context.packageJson.main} could be downloaded`); } catch (e) { - common.debug (e); + common.debug(e); if (!context.ioPackageJson.common.nogit) { context.errors.push(`[E124] Main file not found under URL: ${context.githubUrl}/${context.packageJson.main}.`); } else if (!context.packageJson.main.startsWith('build/')) { diff --git a/lib/M250_Npm.js b/lib/M250_Npm.js index ef76aca..a35ec3a 100644 --- a/lib/M250_Npm.js +++ b/lib/M250_Npm.js @@ -64,12 +64,10 @@ async function checkNpm(context) { if (!body['dist-tags'] || context.packageJson.version !== body['dist-tags'].latest ) { - if ( compareVersions.compare( body['dist-tags'].latest, context.packageJson.version, '>=' )) { - context.errors.push(`[E253] Version of package.json (${context.packageJson.version}) lower than latest version on NPM (${ - (body['dist-tags'] && body['dist-tags'].latest) || JSON.stringify(body)})`); + if (compareVersions.compare(body['dist-tags'].latest, context.packageJson.version, '>=')) { + context.errors.push(`[E253] Version of package.json (${context.packageJson.version}) lower than latest version on NPM (${(body['dist-tags'] && body['dist-tags'].latest) || JSON.stringify(body)})`); } else { - context.warnings.push(`[W252] Version of package.json (${context.packageJson.version}) doesn't match latest version on NPM (${ - (body['dist-tags'] && body['dist-tags'].latest) || JSON.stringify(body)})`); + context.warnings.push(`[W252] Version of package.json (${context.packageJson.version}) doesn't match latest version on NPM (${(body['dist-tags'] && body['dist-tags'].latest) || JSON.stringify(body)})`); } } else { context.checks.push(`Version of package.json ${context.packageJson.version} matches latest version on NPM`); diff --git a/lib/M400_Repository.js b/lib/M400_Repository.js index 949e388..93717e3 100644 --- a/lib/M400_Repository.js +++ b/lib/M400_Repository.js @@ -155,9 +155,9 @@ async function checkRepository(context) { if (context.latestRepo && context.latestRepoLive && context.stableRepo && context.stableRepoLive) { if (context.ioPackageJson.common.dependencies) { const dependencies = common.getDependencies(context.ioPackageJson.common.dependencies); - for ( const dependency in dependencies ) { + for (const dependency in dependencies) { - if ( !context.latestRepoLive[dependency] ) { + if (!context.latestRepoLive[dependency]) { context.errors.push(`[E431] Dependency '${dependency}':'${dependencies[dependency]}' not available at latest repository`); } else { const versDependency = dependencies[dependency]; @@ -167,7 +167,7 @@ async function checkRepository(context) { context.warnings.push(`[W432] Dependency '${dependency}':'${dependencies[dependency]}' should specify '>='`); } else { try { - if ( !compareVersions.compare( versRepository, versDependency.replace('>=','').trim(), '>=')) { + if (!compareVersions.compare(versRepository, versDependency.replace('>=', '').trim(), '>=')) { context.errors.push(`[E431] Dependency '${dependency}':'${dependencies[dependency]}' not available at latest repository`); } else { context.checks.push(`Dependency '${dependency}':'${dependencies[dependency]}' available at latest repository`); @@ -178,7 +178,7 @@ async function checkRepository(context) { } } - if ( !context.stableRepoLive[dependency] ) { + if (!context.stableRepoLive[dependency]) { context.warnings.push(`[W433] Dependency '${dependency}':'${dependencies[dependency]}' not available at stable repository`); } else { const versDependency = dependencies[dependency]; @@ -188,7 +188,7 @@ async function checkRepository(context) { context.warnings.push(`[W434] Dependency '${dependency}':'${dependencies[dependency]}' should specify '>='`); } else { try { - if ( !compareVersions.compare( versRepository, versDependency.replace('>=','').trim(), '>=')) { + if (!compareVersions.compare(versRepository, versDependency.replace('>=', '').trim(), '>=')) { context.errors.push(`[E433] Dependency '${dependency}':'${dependencies[dependency]}' not available at stable repository`); } else { context.checks.push(`Dependency '${dependency}':'${dependencies[dependency]}' available at stable repository`); @@ -206,9 +206,9 @@ async function checkRepository(context) { if (context.ioPackageJson.common.globalDependencies) { const dependencies = common.getDependencies(context.ioPackageJson.common.globalDependencies); - for ( const dependency in dependencies ) { + for (const dependency in dependencies) { - if ( !context.latestRepoLive[dependency] ) { + if (!context.latestRepoLive[dependency]) { context.errors.push(`[E431] Dependency '${dependency}':'${dependencies[dependency]}' not available at latest repository`); } else { const versDependency = dependencies[dependency]; @@ -218,7 +218,7 @@ async function checkRepository(context) { context.warnings.push(`[W432] Dependency '${dependency}':'${dependencies[dependency]}' should specify '>='`); } else { try { - if ( !compareVersions.compare( versRepository, versDependency.replace('>=','').trim(), '>=')) { + if (!compareVersions.compare(versRepository, versDependency.replace('>=', '').trim(), '>=')) { context.errors.push(`[E431] Dependency '${dependency}':'${dependencies[dependency]}' not available at latest repository`); } else { context.checks.push(`Dependency '${dependency}':'${dependencies[dependency]}' available at latest repository`); @@ -229,7 +229,7 @@ async function checkRepository(context) { } } - if ( !context.stableRepoLive[dependency] ) { + if (!context.stableRepoLive[dependency]) { context.warnings.push(`[W433] Dependency '${dependency}':'${dependencies[dependency]}' not available at stable repository`); } else { const versDependency = dependencies[dependency]; @@ -239,7 +239,7 @@ async function checkRepository(context) { context.warnings.push(`[W434] Dependency '${dependency}':'${dependencies[dependency]}' should specify '>='`); } else { try { - if ( !compareVersions.compare( versRepository, versDependency.replace('>=','').trim(), '>=')) { + if (!compareVersions.compare(versRepository, versDependency.replace('>=', '').trim(), '>=')) { context.errors.push(`[E433] Dependency '${dependency}':'${dependencies[dependency]}' not available at stable repository`); } else { context.checks.push(`Dependency '${dependency}':'${dependencies[dependency]}' available at stable repository`); diff --git a/lib/M500_Code.js b/lib/M500_Code.js index a68053b..f9f8e25 100644 --- a/lib/M500_Code.js +++ b/lib/M500_Code.js @@ -14,6 +14,8 @@ const unzipper = require('unzipper'); const util = require('node:util'); const Writable = stream.Writable; +const fs = require('node:fs'); +const path = require('node:path'); const common = require('./common.js'); @@ -73,10 +75,36 @@ function extractWords(words) { } } +function getAllFiles(context, dirPath, root, filesList) { + const skipDirectories = [ + '.dev-server', + 'node_modules', + '.git', + '.vscode' + ]; + const files = fs.readdirSync(dirPath); + filesList = filesList || []; + files.forEach(file => { + if (fs.statSync(path.join(dirPath, file)).isDirectory()) { + if (!skipDirectories.includes(file)) { + filesList = getAllFiles(context, path.join(dirPath, file), [root, file].join('/'), filesList); + } + } else { + filesList.push([root, file].join('/').slice(1)); + if (context.readFiles.includes([root, file].join('/').slice(1))) { + context[[root, file].join('/')] = fs.readFileSync(path.join(dirPath, file), 'utf8'); + } + + } + }); + return filesList; +} + // E5xx async function checkCode(context) { console.log('\ncheckCode [E5xx]'); + const readFiles = [ '.npmignore', '.gitignore', @@ -138,82 +166,93 @@ async function checkCode(context) { // } // https://github.com/userName/ioBroker.adaptername/archive/${context.branch}.zip - const data = await common.downloadFile(context.githubUrlOriginal, `/archive/${context.branch}.zip`, true); - console.log(`${context.branch}.zip ${data.length} bytes`); - - let found = false; - const bufferStream = new stream.PassThrough(); - bufferStream.end(data); - context.filesList = []; - - // parse zip file - const promises = []; - await (function () { return new Promise(_resolve => { - common.debug('init bufferstream'); - let root=''; - bufferStream - .pipe(unzipper.Parse()) - .on('entry', entry => { - common.debug('on.entry ' + entry.path); - if (root === '') { - root=entry.path; - console.log(`Directory root set to ${root}`); - } - //if (!found && entry.type === 'Directory' && entry.path.match(/\/node_modules\/$/)) { - if (!found && entry.type === 'Directory' && entry.path === `${root}node_modules/`) { - console.log(`Found ${entry.path}`); - found = true; - context.errors.push('[E500] Directory node_modules found in root of repository. Please delete directory.'); - } - // Get a list of all files and `.npmignore` + `.gitignore` - const name = entry.path.replace(/^[^/]+\//, ''); - context.filesList.push(name); - - if (readFiles.includes(name)) { - promises.push(new Promise(resolve => { - const wstream = new WMStrm(name); - wstream.on('finish', () => { - context[`/${name}`] = memStore[name].toString(); - resolve(context[`/${name}`]); - }); - entry.pipe(wstream); - })); - } else { - entry.autodrain(); - } - }) - .on('error', () => { - common.debug('on.error'); - context.errors.push(`[E501] Cannot get ${context.branch}.zip on github`); - return Promise.all(promises).then(() => _resolve(context)); - }) - .on('close', () => { - common.debug('on.close'); - return Promise.all(promises).then(() => _resolve(context)); + if (common.isLocal()) { + // check a list of all files in the current path and all subdirectories + context.readFiles = readFiles; + context.filesList = []; + getAllFiles(context, process.cwd(), '', context.filesList); + + } else { + const data = await common.downloadFile(context.githubUrlOriginal, `/archive/${context.branch}.zip`, true); + console.log(`${context.branch}.zip ${data.length} bytes`); + + let found = false; + const bufferStream = new stream.PassThrough(); + bufferStream.end(data); + context.filesList = []; + + // parse zip file + const promises = []; + await (function () { + return new Promise(_resolve => { + common.debug('init bufferstream'); + let root = ''; + bufferStream + .pipe(unzipper.Parse()) + .on('entry', entry => { + common.debug('on.entry ' + entry.path); + if (root === '') { + root = entry.path; + console.log(`Directory root set to ${root}`); + } + //if (!found && entry.type === 'Directory' && entry.path.match(/\/node_modules\/$/)) { + if (!found && entry.type === 'Directory' && entry.path === `${root}node_modules/`) { + console.log(`Found ${entry.path}`); + found = true; + context.errors.push('[E500] Directory node_modules found in root of repository. Please delete directory.'); + } + + // Get a list of all files and `.npmignore` + `.gitignore` + const name = entry.path.replace(/^[^/]+\//, ''); + context.filesList.push(name); + + if (readFiles.includes(name)) { + promises.push(new Promise(resolve => { + const wstream = new WMStrm(name); + wstream.on('finish', () => { + context[`/${name}`] = memStore[name].toString(); + resolve(context[`/${name}`]); + }); + entry.pipe(wstream); + })); + } else { + entry.autodrain(); + } + }) + .on('error', () => { + common.debug('on.error'); + context.errors.push(`[E501] Cannot get ${context.branch}.zip on github`); + return Promise.all(promises).then(() => _resolve(context)); + }) + .on('close', () => { + common.debug('on.close'); + return Promise.all(promises).then(() => _resolve(context)); + }); }); - }); - })(); + })(); + } + let usesReact = false; if (context.packageJson.devDependencies && - (context.packageJson.devDependencies['@iobroker/adapter-react-v5'] || context.packageJson.devDependencies['react'])) { + (context.packageJson.devDependencies['@iobroker/adapter-react-v5'] || context.packageJson.devDependencies['react'])) { console.log('REACT detected at package devDependencies'); usesReact = true; } if (context.packageJson.dependencies && - (context.packageJson.dependencies['@iobroker/adapter-react-v5'] || context.packageJson.dependencies['react'])) { + (context.packageJson.dependencies['@iobroker/adapter-react-v5'] || context.packageJson.dependencies['react'])) { console.log('REACT detected at package dependencies'); usesReact = true; } if (context['/src-admin/package.json']) { //console.log('"src-admin/package.json" exists'); const packageJson = JSON.parse(context['/src-admin/package.json']); - if (packageJson.devDependencies && packageJson.devDependencies['@iobroker/adapter-react-v5'] ) { + if (packageJson.devDependencies && packageJson.devDependencies['@iobroker/adapter-react-v5']) { console.log('REACT detected at src-admin/package devDependencies'); usesReact = true; } - if (packageJson.dependencies && packageJson.dependencies['@iobroker/adapter-react-v5'] ) { + if (packageJson.dependencies && packageJson.dependencies['@iobroker/adapter-react-v5']) { console.log('REACT detected at src-admin/package dependencies'); usesReact = true; } @@ -235,20 +274,20 @@ async function checkCode(context) { if (context['/src/package.json']) { //console.log('"src/package.json" exists'); const packageJson = JSON.parse(context['/src/package.json']); - if (packageJson.devDependencies && packageJson.devDependencies['@iobroker/adapter-react-v5'] ) { + if (packageJson.devDependencies && packageJson.devDependencies['@iobroker/adapter-react-v5']) { // console.log('REACT detected'); usesReact = true; } - if (packageJson.dependencies && packageJson.dependencies['@iobroker/adapter-react-v5'] ) { + if (packageJson.dependencies && packageJson.dependencies['@iobroker/adapter-react-v5']) { // console.log('REACT detected'); usesReact = true; } } - if (! usesReact && !context.ioPackageJson.common.noConfig && - (!context.ioPackageJson.common.adminUI || - (context.ioPackageJson.common.adminUI.config !== 'json' && context.ioPackageJson.common.adminUI.config !== 'none') - )) { + if (!usesReact && !context.ioPackageJson.common.noConfig && + (!context.ioPackageJson.common.adminUI || + (context.ioPackageJson.common.adminUI.config !== 'json' && context.ioPackageJson.common.adminUI.config !== 'none') + )) { context.warnings.push('[S522] Please consider migrating to admin 5 UI (jsonConfig).'); } @@ -347,7 +386,7 @@ async function checkCode(context) { 'iobroker' ]; - forbiddenFiles.forEach( file => { + forbiddenFiles.forEach(file => { if (context.filesList.includes(file)) { context.errors.push(`[E503] File "${file}" found in repo! Please remove file.`); } @@ -374,13 +413,13 @@ async function checkCode(context) { } } - if (context.packageJson.devDependencies && context.packageJson.devDependencies['@alcalzone/release-script'] ) { + if (context.packageJson.devDependencies && context.packageJson.devDependencies['@alcalzone/release-script']) { const version = context.packageJson.devDependencies['@alcalzone/release-script']; - if ( compareVersions.compareVersions( version, '3.0.0' ) >= 0) { + if (compareVersions.compareVersions(version, '3.0.0') >= 0) { if (!context['/.releaseconfig.json']) { context.errors.push('[E518] "@alcalzone/release-script" (>=3.0.0) is used, but ".releaseconfig.json" not found. Please create.'); } else { - console.log('context[/.releaseconfig.json: '+ context['/.releaseconfig.json']); + console.log('context[/.releaseconfig.json: ' + context['/.releaseconfig.json']); try { const releaseConfigJson = JSON.parse(context['/.releaseconfig.json']); console.log(`releaseConfigJson: ${releaseConfigJson}`); diff --git a/lib/M700_License.js b/lib/M700_License.js index c48443a..776a71d 100644 --- a/lib/M700_License.js +++ b/lib/M700_License.js @@ -29,7 +29,7 @@ async function checkLicenseFile(context) { } catch (e) { if (e.status == 404) { context.errors.push('[E700] File LICENSE not found. Please add.'); - } else{ + } else { context.errors.push(`[E702] Cannot read LICENSE file. Please check. (Status ${e.status})`); } } @@ -61,7 +61,7 @@ async function checkLicenseFile(context) { } m = text.match(/(\d\d\d\d)/); if (m) { - if (Number(m[1])>licenseYear) { + if (Number(m[1]) > licenseYear) { licenseYear = Number(m[1]); } } @@ -71,7 +71,7 @@ async function checkLicenseFile(context) { console.log(`Commit year ${commitYear}`); console.log(`NPM year ${npmYear}`); - const valid = (licenseYear === year || licenseYear >= commitYear || licenseYear >=npmYear); + const valid = (licenseYear === year || licenseYear >= commitYear || licenseYear >= npmYear); if (!valid) { const m = text.match(/(\d\d\d\d)-\d\d\d\d/); if (m) { diff --git a/lib/M800_Github.js b/lib/M800_Github.js index 1eb1236..36aefba 100644 --- a/lib/M800_Github.js +++ b/lib/M800_Github.js @@ -57,8 +57,8 @@ async function getCommitInfos(context) { const lastCommitDate = new Date(lastCommit.commit.author.date); context.lastCommitYear = lastCommitDate.getUTCFullYear().toString(); - common.debug (`lastCommitSha : ${context.lastCommitSha}`); - common.debug (`lastCommitYear: ${context.lastCommitYear}`); + common.debug(`lastCommitSha : ${context.lastCommitSha}`); + common.debug(`lastCommitYear: ${context.lastCommitYear}`); return context; } diff --git a/lib/M900_GitNpmIgnore.js b/lib/M900_GitNpmIgnore.js index 610e43a..1489f20 100644 --- a/lib/M900_GitNpmIgnore.js +++ b/lib/M900_GitNpmIgnore.js @@ -34,7 +34,7 @@ async function checkGitIgnore(context) { console.log('\ncheckGitIgnore [E9xx]'); if (!context.filesList) { - throw('FATAL:context.fileslist is undefined'); + throw ('FATAL:context.fileslist is undefined'); } if (!context.filesList.includes('.gitignore')) { diff --git a/lib/common.js b/lib/common.js index 8eda1f2..cca0949 100644 --- a/lib/common.js +++ b/lib/common.js @@ -4,6 +4,7 @@ */ const axios = require('axios'); +const fs = require('node:fs/promises'); const compareVersions = require('compare-versions'); // disable axios caching @@ -14,38 +15,49 @@ axios.defaults.headers = { }; let gDebug = false; -function setDebug(flag){ +function setDebug(flag) { gDebug = flag; } function debug(msg) { - console.log(`[DEBUG] ${msg}`); + gDebug && console.log(`[DEBUG] ${msg}`); } +let gLocal = false; +function setLocal(flag) { + gLocal = flag; +} +function isLocal() { + return gLocal; +} function checkLanguages(langObj, languages) { return languages.filter(lang => !langObj[lang]); } async function downloadFile(githubUrl, path, binary, noError) { - console.log(`Download ${githubUrl}${path || ''}`); - - const options = {}; - if (binary) { - options.responseType = 'arraybuffer'; - } - - try { - const response = await axios(githubUrl + (path || ''), options); - debug(`download succeded`); - return(response.data); - } catch (e) { - (!noError || gDebug) && console.error(`Cannot download ${githubUrl}${path || ''} ${e}`); - throw e; + if (!isLocal()) { + console.log(`Download ${githubUrl}${path || ''}`); + const options = {}; + if (binary) { + options.responseType = 'arraybuffer'; + } + try { + const response = await axios(githubUrl + (path || ''), options); + debug(`download succeded`); + return (response.data); + } catch (e) { + (!noError || gDebug) && console.error(`Cannot download ${githubUrl}${path || ''} ${e}`); + throw e; + } + } else { + console.log(`Download local ${path || ''}`); + // remove first / from path + path = path.replace(/^\/+/, ''); + const file = await fs.readFile(path, binary ? null : 'utf8'); + return file; } - } - function getDependencyArray(deps) { return deps .map(dep => typeof dep === 'object' ? Object.keys(dep) : [dep]) @@ -77,13 +89,13 @@ function getDependencies(deps) { const ret = {}; console.log(`deps: ${JSON.stringify(deps)}, type ${typeof deps}`); if (deps instanceof Array) { - for (const dep of deps ) { + for (const dep of deps) { if (typeof dep === 'object') { - for (const key in dep ) { + for (const key in dep) { ret[key] = dep[key]; } } else { - ret[ dep ] = '>=0'; + ret[dep] = '>=0'; } } } @@ -101,12 +113,14 @@ function maxVersion(v1, v2) { return v2; } -exports.setDebug=setDebug; -exports.debug=debug; +exports.setDebug = setDebug; +exports.debug = debug; +exports.setLocal = setLocal; +exports.isLocal = isLocal; -exports.checkLanguages=checkLanguages; -exports.downloadFile=downloadFile; -exports.getDependencyArray=getDependencyArray; -exports.getDependencies=getDependencies; -exports.maxVersion=maxVersion; +exports.checkLanguages = checkLanguages; +exports.downloadFile = downloadFile; +exports.getDependencyArray = getDependencyArray; +exports.getDependencies = getDependencies; +exports.maxVersion = maxVersion; diff --git a/package.json b/package.json index a293fe7..f8c610b 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "3.1.4", + "version": "3.2.0", "name": "@iobroker/repochecker", "dependencies": { "axios": "^1.7.7", diff --git a/scripts/createIssuesForAdapter.js b/scripts/createIssuesForAdapter.js index 809b79a..56525e5 100644 --- a/scripts/createIssuesForAdapter.js +++ b/scripts/createIssuesForAdapter.js @@ -1,3 +1,4 @@ +/* global $,jQuery */ const githubToken = ''; //https://github.com/settings/tokens let issueTitle = 'Verify Compact mode for your adapter'; const issueBody = 'We have detected that your adapter supports the compact mode. Please use the latest js-controller 2.0 and verify that everything works.\r\n\r\nSome more information what is important to check can be found at ioBroker/ioBroker.js-controller#512 \r\n\r\nOn questions please answer to the linked issue. Please close this issue after your test and add the version number that you have tested please as a comment.\r\n\r\nThank you for your support.'; @@ -23,7 +24,7 @@ const start = async function () { async function asyncForEach(array, callback) { for (let index = 0; index < array.length; index++) { - await callback(array [index], index, array); + await callback(array[index], index, array); } } @@ -118,7 +119,7 @@ async function filterList(array) { async function getAdapterList() { const link = 'https://raw.githubusercontent.com/ioBrokerChecker/testData/master/data.json'; try { - const result = await fetch(link, {cache: 'no-cache'}); + const result = await fetch(link, { cache: 'no-cache' }); return await result.json(); } catch (e) { return null; diff --git a/scripts/updateAllIssues.js b/scripts/updateAllIssues.js index 08a1ffd..5d41cc0 100644 --- a/scripts/updateAllIssues.js +++ b/scripts/updateAllIssues.js @@ -1,40 +1,41 @@ -const githubToken = ""; // https://github.com/settings/tokens +/* global $,jQuery */ +const githubToken = ''; // https://github.com/settings/tokens const test = false; -const toGet = "checkError2"; -const toSet = "checkError"; +const toGet = 'checkError2'; +const toSet = 'checkError'; const checkOkCheck = true; -const issueTitle = "Think about to fix the issues found by adapter checker"; +const issueTitle = 'Think about to fix the issues found by adapter checker'; -const adapterTestLink = "https://e7tj1cpjna.execute-api.eu-west-1.amazonaws.com/?url="; +const adapterTestLink = 'https://e7tj1cpjna.execute-api.eu-west-1.amazonaws.com/?url='; -let adapterList, dicoveryList; +let adapterList/* , dicoveryList */; const start = async function () { - console.log("Adapter Liste wird geladen..."); + console.log('Adapter Liste wird geladen...'); adapterList = await getAdapterList(); - console.log("Adapter Liste geladen!") + console.log('Adapter Liste geladen!'); if (adapterList) { - if(!adapterList[toSet]) adapterList[toSet] = {}; - if(!adapterList.dependVISwwwOnly) adapterList.dependVISwwwOnly = []; - if(!adapterList.dependVIS) adapterList.dependVIS = []; - if(!adapterList.noRestartVIS2) adapterList.noRestartVIS2 = []; - - $('#listeSuccess').append("
  • ignored: " + adapterList["ignore"].length + "/
  • "); - $('#listeSuccess').append("
  • noIoPackage: " + adapterList["noIoPackage"].length + "/
  • "); - $('#listeSuccess').append("
  • checkErrorOld: " + Object.keys(adapterList["checkErrorOld"]).length + "/
  • "); - $('#listeSuccess').append("
  • " + toGet + ": " + Object.keys(adapterList[toGet]).length + "/
  • "); - $('#listeSuccess').append("
  • " + toSet + ": " + Object.keys(adapterList[toSet]).length + "/
  • "); + if (!adapterList[toSet]) adapterList[toSet] = {}; + if (!adapterList.dependVISwwwOnly) adapterList.dependVISwwwOnly = []; + if (!adapterList.dependVIS) adapterList.dependVIS = []; + if (!adapterList.noRestartVIS2) adapterList.noRestartVIS2 = []; + + $('#listeSuccess').append("
  • ignored: " + adapterList['ignore'].length + "/
  • "); + $('#listeSuccess').append("
  • noIoPackage: " + adapterList['noIoPackage'].length + "/
  • "); + $('#listeSuccess').append("
  • checkErrorOld: " + Object.keys(adapterList['checkErrorOld']).length + "/
  • "); + $('#listeSuccess').append("
  • " + toGet + ': ' + Object.keys(adapterList[toGet]).length + "/
  • "); + $('#listeSuccess').append("
  • " + toSet + ': ' + Object.keys(adapterList[toSet]).length + "/
  • "); $('#listeSuccess').append("
  • checkOk: " + adapterList.checkOk.length + "/
  • "); $('#listeSuccess').append("
  • dependVISwwwOnly: " + adapterList.dependVISwwwOnly.length + "/
  • "); $('#listeSuccess').append("
  • dependVIS: " + adapterList.dependVIS.length + "/
  • "); $('#listeSuccess').append("
  • noRestartVIS2: " + adapterList.noRestartVIS2.length + "/
  • "); - console.log("Die Arbeit beginnt"); + console.log('Die Arbeit beginnt'); await startFunc(); await delay(10000); - console.log("Die Arbeit ist fertig!!"); + console.log('Die Arbeit ist fertig!!'); console.log(JSON.stringify(adapterList)); $('#ignore').text(adapterList.ignore.length); @@ -48,7 +49,7 @@ const start = async function () { $('#' + toGet).text(Object.keys(adapterList[toGet]).length); $('#result').text(JSON.stringify(adapterList)); } else { - $('#liste').append("
  • ERROR " + Object.keys(adapterList[toGet]).length + " " + Object.keys(adapterList[toSet]).length + "
  • "); + $('#liste').append("
  • ERROR " + Object.keys(adapterList[toGet]).length + ' ' + Object.keys(adapterList[toSet]).length + '
  • '); } }; @@ -70,7 +71,7 @@ const start = async function () { } // confirm array is populated if (arr) { - var len = arr.length; + const len = arr.length; i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0; elem = elem.toLowerCase(); for (; i < len; i++) { @@ -91,13 +92,13 @@ const startFunc = async function () { if (adapterList) { - console.log("Suche neue Adapter"); + console.log('Suche neue Adapter'); const oldGet = Object.keys(adapterList[toGet]).length; - await findAllAdapters("asc"); - await findAllAdapters("desc"); - console.log("Suche neuer Adapter beendet - " + (Object.keys(adapterList[toGet]).length - oldGet) + " Adapter gefunden"); + await findAllAdapters('asc'); + await findAllAdapters('desc'); + console.log('Suche neuer Adapter beendet - ' + (Object.keys(adapterList[toGet]).length - oldGet) + ' Adapter gefunden'); - if(checkOkCheck){ + if (checkOkCheck) { adapterList.checkOk.forEach(function (full_name) { adapterList[toGet][full_name] = {}; adapterList[toGet][full_name].issue = null; @@ -111,18 +112,18 @@ const startFunc = async function () { for (const origfullname in adapterList[toGet]) { const full_name = await getFullname(origfullname); - if(full_name) { - console.log("Teste " + full_name + " ..."); - const testLink = "https://raw.githubusercontent.com/" + full_name; + if (full_name) { + console.log('Teste ' + full_name + ' ...'); + const testLink = 'https://raw.githubusercontent.com/' + full_name; const testResult = await doTheTest(testLink); - console.log("Teste io-Package vis" + full_name + " ..."); - let check = await checkVis("https://raw.githubusercontent.com/" + full_name + "/master/io-package.json", full_name); - if(!check){ - await checkVis("https://raw.githubusercontent.com/" + full_name + "/main/io-package.json", full_name); + console.log('Teste io-Package vis' + full_name + ' ...'); + const check = await checkVis('https://raw.githubusercontent.com/' + full_name + '/master/io-package.json', full_name); + if (!check) { + await checkVis('https://raw.githubusercontent.com/' + full_name + '/main/io-package.json', full_name); } - let issueNr = adapterList[toGet][origfullname].issue; + const issueNr = adapterList[toGet][origfullname].issue; let issuesList = []; if (issueNr) { issuesList = adapterList[toGet][origfullname].errorList; @@ -130,38 +131,38 @@ const startFunc = async function () { if ((testResult && testResult.errors && testResult.errors.length > 0) || adapterList.noRestartVIS2.includes(full_name) || adapterList.dependVIS.includes(full_name) || adapterList.dependVISwwwOnly.includes(full_name)) { try { - console.log("Issue wird angelegt " + full_name + " ..."); - let issueBody = "I am an automatic service that looks for possible errors in ioBroker and creates an issue for it. The link below leads directly to the test:\r\n\r\n"; - issueBody += "https://adapter-check.iobroker.in/?q=" + testLink + "\r\n\r\n"; + console.log('Issue wird angelegt ' + full_name + ' ...'); + let issueBody = 'I am an automatic service that looks for possible errors in ioBroker and creates an issue for it. The link below leads directly to the test:\r\n\r\n'; + issueBody += 'https://adapter-check.iobroker.in/?q=' + testLink + '\r\n\r\n'; const errorList = []; const warningList = []; - if(testResult) { + if (testResult) { testResult.errors.forEach(function (issue) { - issueBody += "- [ ] " + issue + "\r\n"; + issueBody += '- [ ] ' + issue + '\r\n'; errorList.push(issue.substring(1, 5)); }); if (testResult.warnings && testResult.warnings.length > 0) { - issueBody += "\r\nI have also found warnings that may be fixed if possible.\r\n\r\n"; + issueBody += '\r\nI have also found warnings that may be fixed if possible.\r\n\r\n'; testResult.warnings.forEach(function (issue) { - issueBody += "- [ ] " + issue + "\r\n"; + issueBody += '- [ ] ' + issue + '\r\n'; warningList.push(issue.substring(1, 5)); }); } } - if(adapterList.noRestartVIS2.includes(full_name)){ - issueBody += "\r\nI noticed that in the io-package under “restartAdapters” only vis is available. If your widget also runs with vis-2, you might want to add “vis-2” to the list too.\r\n\r\n"; + if (adapterList.noRestartVIS2.includes(full_name)) { + issueBody += '\r\nI noticed that in the io-package under “restartAdapters” only vis is available. If your widget also runs with vis-2, you might want to add “vis-2” to the list too.\r\n\r\n'; } - if(adapterList.dependVIS.includes(full_name)){ - issueBody += "\r\nI found vis as “dependencies” in the io package. Please remove this dependency.\r\n\r\n"; + if (adapterList.dependVIS.includes(full_name)) { + issueBody += '\r\nI found vis as “dependencies” in the io package. Please remove this dependency.\r\n\r\n'; } - if(adapterList.dependVISwwwOnly.includes(full_name)){ - issueBody += "\r\nI found vis as “dependencies” in the io package. If your widget also runs with vis-2, then remove that.\r\n\r\n"; + if (adapterList.dependVISwwwOnly.includes(full_name)) { + issueBody += '\r\nI found vis as “dependencies” in the io package. If your widget also runs with vis-2, then remove that.\r\n\r\n'; } - issueBody += "\r\nThanks,\r\nyour automatic adapter checker."; + issueBody += '\r\nThanks,\r\nyour automatic adapter checker.'; issueBody += addComminityText(full_name); const errorNotChanged = issueNr !== null && (errorList.length === issuesList.length && errorList.sort().every(function (value, index) { @@ -175,7 +176,7 @@ const startFunc = async function () { } else if (githubToken && errorNotChanged) { let dateIssue = adapterList[toGet][origfullname].createdDate; if (!dateIssue) { - dateIssue = "2019-02-01T15:08:12Z"; + dateIssue = '2019-02-01T15:08:12Z'; adapterList[toGet][origfullname].createdDate = dateIssue; } @@ -185,18 +186,18 @@ const startFunc = async function () { adapterList[toSet][full_name] = adapterList[toGet][origfullname]; delete adapterList[toGet][origfullname]; } - $('#liste').append("
  • " + (full_name === origfullname ? full_name : origfullname + " => " + full_name) + " no error changes
  • "); + $('#liste').append("
  • " + (full_name === origfullname ? full_name : origfullname + ' => ' + full_name) + ' no error changes
  • '); } else { - testIssueCreation("NO TOKEN - " + full_name, "NO TOKEN - " + full_name, testResult.errors.length); + testIssueCreation('NO TOKEN - ' + full_name, 'NO TOKEN - ' + full_name, testResult.errors.length); } } catch (e) { - console.error(full_name + " - " + e); + console.error(full_name + ' - ' + e); } } else if (testResult && testResult.errors && testResult.errors.length === 0) { if (!test && githubToken) { closeIssue(origfullname, full_name, issueNr); } - $('#liste').append("
  • " + (full_name === origfullname ? full_name : origfullname + " => " + full_name) + " fixed - checked but no error found
  • "); + $('#liste').append("
  • " + (full_name === origfullname ? full_name : origfullname + ' => ' + full_name) + ' fixed - checked but no error found
  • '); } } } @@ -204,15 +205,15 @@ const startFunc = async function () { } }; -$("button").on("click", function () { +$('button').on('click', function () { start(); }); function addComminityText(full_name) { - if (!full_name.startsWith("ioBroker/") && !full_name.startsWith("iobroker-community-adapters/")) { - return "\r\n\r\nP.S.: There is a community in Github, which supports the maintenance and further development of adapters. There you will find many experienced developers who are always ready to assist anyone. New developers are always welcome there. For more informations visit: https://github.com/iobroker-community-adapters/info"; + if (!full_name.startsWith('ioBroker/') && !full_name.startsWith('iobroker-community-adapters/')) { + return '\r\n\r\nP.S.: There is a community in Github, which supports the maintenance and further development of adapters. There you will find many experienced developers who are always ready to assist anyone. New developers are always welcome there. For more informations visit: https://github.com/iobroker-community-adapters/info'; } else { - return ""; + return ''; } } @@ -225,14 +226,14 @@ const interactor = new GithubInteractor(githubToken); function createIssue(orgRepo, repo, issueBody, count, issueNr, errorList, warningList) { if (issueNr) { - const url = "https://api.github.com/repos/" + repo + "/issues/" + issueNr; + const url = 'https://api.github.com/repos/' + repo + '/issues/' + issueNr; $.ajax({ url: url, - type: "PATCH", + type: 'PATCH', beforeSend: function (xhr) { - xhr.setRequestHeader("Authorization", "token " + interactor.token); + xhr.setRequestHeader('Authorization', 'token ' + interactor.token); }, - error: function (xhr, status, error) { + error: function (/* xhr, status, error */) { createIssue(orgRepo, repo, issueBody, count, null, errorList, warningList); }, success: function (issue) { @@ -245,24 +246,24 @@ function createIssue(orgRepo, repo, issueBody, count, issueNr, errorList, warnin adapterList[toSet][repo].createdDate = (adapterList[toGet][orgRepo].createdDate ? adapterList[toGet][orgRepo].createdDate : issue.created_at); adapterList[toSet][repo].help = adapterList[toGet][orgRepo].help === true; delete adapterList[toGet][orgRepo]; - $('#listeSuccess').append("
  • " + (repo === orgRepo ? repo : orgRepo + " => " + repo) + " (" + count + " errors) - issue updated
  • "); + $('#listeSuccess').append('
  • ' + (repo === orgRepo ? repo : orgRepo + ' => ' + repo) + ' (' + count + ' errors) - issue updated
  • '); }, data: JSON.stringify({ body: issueBody, - state: "open" + state: 'open' }) }); } else { - const url = "https://api.github.com/repos/" + repo + "/issues"; + const url = 'https://api.github.com/repos/' + repo + '/issues'; $.ajax({ url: url, - type: "POST", + type: 'POST', beforeSend: function (xhr) { - xhr.setRequestHeader("Authorization", "token " + interactor.token); + xhr.setRequestHeader('Authorization', 'token ' + interactor.token); }, error: function (xhr, status, error) { const err = JSON.parse(xhr.responseText); - $('#liste').append("
  • " + (repo === orgRepo ? repo : orgRepo + " => " + repo) + " - issue failed (" + status + ": " + error + ") " + err + "
  • "); + $('#liste').append("
  • " + (repo === orgRepo ? repo : orgRepo + ' => ' + repo) + ' - issue failed (' + status + ': ' + error + ') ' + err + '
  • '); }, success: function (issue) { adapterList[toSet][repo] = {}; @@ -274,7 +275,7 @@ function createIssue(orgRepo, repo, issueBody, count, issueNr, errorList, warnin adapterList[toSet][repo].createdDate = issue.created_at; adapterList[toSet][repo].help = false; delete adapterList[toGet][orgRepo]; - $('#listeSuccess').append("
  • " + (repo === orgRepo ? repo : orgRepo + " => " + repo) + " (" + count + " errors) - new issue created
  • "); + $('#listeSuccess').append('
  • ' + (repo === orgRepo ? repo : orgRepo + ' => ' + repo) + ' (' + count + ' errors) - new issue created
  • '); }, data: JSON.stringify({ title: issueTitle, @@ -287,19 +288,19 @@ function createIssue(orgRepo, repo, issueBody, count, issueNr, errorList, warnin function closeIssue(orgRepo, repo, issueNr) { if (issueNr) { - const urlComment = "https://api.github.com/repos/" + repo + "/issues/" + issueNr + "/comments"; - const issueBody = "Thanks, that all bugs have been fixed."; + const urlComment = 'https://api.github.com/repos/' + repo + '/issues/' + issueNr + '/comments'; + const issueBody = 'Thanks, that all bugs have been fixed.'; $.ajax({ url: urlComment, - type: "POST", + type: 'POST', beforeSend: function (xhr) { - xhr.setRequestHeader("Authorization", "token " + interactor.token); + xhr.setRequestHeader('Authorization', 'token ' + interactor.token); }, error: function (xhr, status, error) { const err = JSON.parse(xhr.responseText); - $('#liste').append("
  • " + (repo === orgRepo ? repo : orgRepo + " => " + repo) + " - issue failed (" + status + ": " + error + ") " + err + "
  • "); + $('#liste').append("
  • " + (repo === orgRepo ? repo : orgRepo + ' => ' + repo) + ' - issue failed (' + status + ': ' + error + ') ' + err + '
  • '); }, - success: function (issue) { + success: function (/* issue */) { adapterList.checkOk.push(repo); delete adapterList[toGet][orgRepo]; }, @@ -308,15 +309,15 @@ function closeIssue(orgRepo, repo, issueNr) { }) }); - var urlIssue = "https://api.github.com/repos/" + repo + "/issues/" + issueNr; + const urlIssue = 'https://api.github.com/repos/' + repo + '/issues/' + issueNr; $.ajax({ url: urlIssue, - type: "PATCH", + type: 'PATCH', beforeSend: function (xhr) { - xhr.setRequestHeader("Authorization", "token " + interactor.token); + xhr.setRequestHeader('Authorization', 'token ' + interactor.token); }, data: JSON.stringify({ - state: "closed" + state: 'closed' }) }); @@ -329,21 +330,21 @@ function closeIssue(orgRepo, repo, issueNr) { function createHelpComment(orgRepo, repo, issueNr) { if (issueNr && !adapterList[toGet][repo].help) { - var urlComment = "https://api.github.com/repos/" + repo + "/issues/" + issueNr + "/comments"; - const issueBody = "Do you need help fixing the bugs?"; + const urlComment = 'https://api.github.com/repos/' + repo + '/issues/' + issueNr + '/comments'; + const issueBody = 'Do you need help fixing the bugs?'; $.ajax({ url: urlComment, - type: "POST", + type: 'POST', beforeSend: function (xhr) { - xhr.setRequestHeader("Authorization", "token " + interactor.token); + xhr.setRequestHeader('Authorization', 'token ' + interactor.token); }, error: function (xhr, status, error) { const err = JSON.parse(xhr.responseText); - $('#liste').append("
  • " + (repo === orgRepo ? repo : orgRepo + " => " + repo) + " - issue failed (" + status + ": " + error + ") - " + err + "
  • "); + $('#liste').append("
  • " + (repo === orgRepo ? repo : orgRepo + ' => ' + repo) + ' - issue failed (' + status + ': ' + error + ') - ' + err + '
  • '); }, - success: function (issue) { + success: function (/* issue */) { adapterList[toSet][repo] = adapterList[toGet][orgRepo]; - adapterList[toSet][repo].status = "open"; + adapterList[toSet][repo].status = 'open'; adapterList[toSet][repo].createdDate = new Date().toISOString(); adapterList[toSet][repo].help = true; delete adapterList[toGet][orgRepo]; @@ -353,24 +354,24 @@ function createHelpComment(orgRepo, repo, issueNr) { }) }); - const urlIssue = "https://api.github.com/repos/" + repo + "/issues/" + issueNr; + const urlIssue = 'https://api.github.com/repos/' + repo + '/issues/' + issueNr; $.ajax({ url: urlIssue, - type: "PATCH", + type: 'PATCH', beforeSend: function (xhr) { - xhr.setRequestHeader("Authorization", "token " + interactor.token); + xhr.setRequestHeader('Authorization', 'token ' + interactor.token); }, data: JSON.stringify({ - state: "open" + state: 'open' }) }); } } async function getAdapterList() { - const link = "https://raw.githubusercontent.com/ioBrokerChecker/testData/master/data.json"; + const link = 'https://raw.githubusercontent.com/ioBrokerChecker/testData/master/data.json'; try { - return await (await fetch(link, {cache: "no-cache"})).json(); + return await (await fetch(link, { cache: 'no-cache' })).json(); } catch (e) { console.log(e); return null; @@ -391,18 +392,18 @@ async function findAllAdapters(sort) { if (!repoNode.node.hasIssuesEnabled || repoNode.node.isArchived || checkIgnores(full_name)) { return true; } - console.log("Check " + full_name); - let check = await checkIoPackage("https://raw.githubusercontent.com/" + full_name + "/master/io-package.json", full_name); - if(!check){ - check = await checkIoPackage("https://raw.githubusercontent.com/" + full_name + "/main/io-package.json", full_name); + console.log('Check ' + full_name); + let check = await checkIoPackage('https://raw.githubusercontent.com/' + full_name + '/master/io-package.json', full_name); + if (!check) { + check = await checkIoPackage('https://raw.githubusercontent.com/' + full_name + '/main/io-package.json', full_name); } if (check) { - console.log(full_name + " als Adapter erkannt"); + console.log(full_name + ' als Adapter erkannt'); adapterList[toGet][full_name] = {}; adapterList[toGet][full_name].issue = null; - }else{ - console.log(full_name + " ist kein Adapter"); + } else { + console.log(full_name + ' ist kein Adapter'); adapterList.noIoPackage.push(full_name); } }); @@ -418,16 +419,16 @@ async function findAllAdapters(sort) { if (!repoNode.node.hasIssuesEnabled || repoNode.node.isArchived || checkIgnores(full_name)) { return true; } - let check = await checkIoPackage("https://raw.githubusercontent.com/" + full_name + "/master/io-package.json", full_name); - if(!check){ - check = await checkIoPackage("https://raw.githubusercontent.com/" + full_name + "/main/io-package.json", full_name); + let check = await checkIoPackage('https://raw.githubusercontent.com/' + full_name + '/master/io-package.json', full_name); + if (!check) { + check = await checkIoPackage('https://raw.githubusercontent.com/' + full_name + '/main/io-package.json', full_name); } if (check) { - console.log(full_name + " als Adapter erkannt"); + console.log(full_name + ' als Adapter erkannt'); adapterList[toGet][full_name] = {}; adapterList[toGet][full_name].issue = null; - }else{ - console.log(full_name + " ist kein Adapter"); + } else { + console.log(full_name + ' ist kein Adapter'); adapterList.noIoPackage.push(full_name); } }); @@ -435,13 +436,13 @@ async function findAllAdapters(sort) { cursor = repos.data.search.pageInfo.endCursor; } else { hasNext = false; - cursor = ""; + cursor = ''; } } } } -async function checkIoPackage(ioPackageLink, adapter) { +async function checkIoPackage(ioPackageLink/* , adapter */) { try { const ioPackage = await (await fetch(ioPackageLink)).json(); const isAdapter = ioPackage && ioPackage.common; @@ -461,20 +462,20 @@ async function checkVis(ioPackageLink, adapter) { if (!isAdapter) { return false; } - if (ioPackage.common.restartAdapters && ioPackage.common.restartAdapters.includes("vis") && !ioPackage.common.restartAdapters.includes("vis-2")) { + if (ioPackage.common.restartAdapters && ioPackage.common.restartAdapters.includes('vis') && !ioPackage.common.restartAdapters.includes('vis-2')) { adapterList.noRestartVIS2.push(adapter); } - if (ioPackage.common.dependencies && ioPackage.common.dependencies.includes("vis")){ - if(ioPackage.common.onlyWWW){ + if (ioPackage.common.dependencies && ioPackage.common.dependencies.includes('vis')) { + if (ioPackage.common.onlyWWW) { adapterList.dependVISwwwOnly.push(adapter); - }else { + } else { adapterList.dependVIS.push(adapter); } } - if (ioPackage.common.globalDependencies && ioPackage.common.globalDependencies.includes("vis")){ - if(ioPackage.common.onlyWWW){ + if (ioPackage.common.globalDependencies && ioPackage.common.globalDependencies.includes('vis')) { + if (ioPackage.common.onlyWWW) { adapterList.dependVISwwwOnly.push(adapter); - }else { + } else { adapterList.dependVIS.push(adapter); } } @@ -486,7 +487,7 @@ async function checkVis(ioPackageLink, adapter) { async function doTheTest(testLink) { try { - return await (await fetch(adapterTestLink + testLink, {mode: 'cors'})).json(); + return await (await fetch(adapterTestLink + testLink, { mode: 'cors' })).json(); } catch (e) { return {}; } @@ -497,7 +498,7 @@ function testIssueCreation(orgRepo, repo, count, notChanged, warnings) { if (warnings) { countW = warnings.length; } - $('#liste').append("
  • " + (repo === orgRepo?repo: orgRepo + " => " + repo) + " (" + count + " err & " + countW + " war) - issue " + (notChanged ? "is the same" : "has been changed (UPDATE)") + "
  • "); + $('#liste').append("
  • " + (repo === orgRepo ? repo : orgRepo + ' => ' + repo) + ' (' + count + ' err & ' + countW + ' war) - issue ' + (notChanged ? 'is the same' : 'has been changed (UPDATE)') + '
  • '); } async function getDataV4(query) { @@ -507,7 +508,7 @@ async function getDataV4(query) { 'Content-Type': 'application/json', 'Authorization': 'bearer ' + interactor.token }), - body: JSON.stringify({query: query}) + body: JSON.stringify({ query: query }) })).json(); } @@ -515,21 +516,21 @@ function getQueryForRepos(sort, cursor) { let query = getRepoSearchQL; if (cursor) { - query = query.replace("$cursor", ', after: "' + cursor + '"'); + query = query.replace('$cursor', ', after: "' + cursor + '"'); } else { - query = query.replace("$cursor", ""); + query = query.replace('$cursor', ''); } - query = query.replace("$dings", sort); + query = query.replace('$dings', sort); return query; } -async function getFullname(fullname){ +async function getFullname(fullname) { let query = checkRepoNameQL; - const names = fullname.split("/"); - query = query.replace("$name", names[1]).replace("$owner", names[0]); + const names = fullname.split('/'); + query = query.replace('$name', names[1]).replace('$owner', names[0]); const repo = await getDataV4(query); - if(repo && repo["data"] && repo["data"]["repository"]){ - return repo["data"]["repository"]["nameWithOwner"]; + if (repo && repo['data'] && repo['data']['repository']) { + return repo['data']['repository']['nameWithOwner']; } return null;