diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac5ebf8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,118 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# Sigbench +*.vsix +task.ts + +# End of https://www.toptal.com/developers/gitignore/api/node diff --git a/.taskkey b/.taskkey new file mode 100644 index 0000000..359b14f --- /dev/null +++ b/.taskkey @@ -0,0 +1 @@ +809ef638-f710-4688-9124-506475b245b4 \ No newline at end of file diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md diff --git a/README.md b/README.md index 7819bdd..73929e4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,14 @@ -# sigbench -Azure DevOps Extension to signature bench your files. +# Signature Benchmark (short: Sigbench) +![Sigbench logo](https://raw.githubusercontent.com/cpz/sigbench/master/images/extension-logo.jpg) + +Sigbench is extension for Azure Pipelines. + +## Test your binary files against signature scans. +It will give you percent of difference and intersection. Difference percent higher is better meanwhile intersection otherwise. +It will also give you the signatures that matched both binaries. (Enable it in Signature Benchmark Advanced - Print Matched). + +## Contributing +Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. + +## License +[MIT](https://choosealicense.com/licenses/mit/) \ No newline at end of file diff --git a/images/extension-logo.jpg b/images/extension-logo.jpg new file mode 100644 index 0000000..e4686eb Binary files /dev/null and b/images/extension-logo.jpg differ diff --git a/sb-task/package-lock.json b/sb-task/package-lock.json new file mode 100644 index 0000000..cc940f1 --- /dev/null +++ b/sb-task/package-lock.json @@ -0,0 +1,220 @@ +{ + "name": "sigbench", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/node": { + "version": "14.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz", + "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==", + "dev": true + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "azure-pipelines-task-lib": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.9.6.tgz", + "integrity": "sha512-KTJuFdMl/r1Y8Snh5lHyV2YOyTu9bKzltMlRlnod8YKLc9GfENDkxwm+z9cHH6NlDln+2YI3G82Ri9XcbhyuZg==", + "requires": { + "minimatch": "3.0.4", + "mockery": "^1.7.0", + "q": "^1.1.2", + "semver": "^5.1.0", + "shelljs": "^0.3.0", + "sync-request": "3.0.1", + "uuid": "^3.0.1" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "http-basic": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-2.5.1.tgz", + "integrity": "sha1-jORHvbW2xXf4pj4/p4BW7Eu02/s=", + "requires": { + "caseless": "~0.11.0", + "concat-stream": "^1.4.6", + "http-response-object": "^1.0.0" + } + }, + "http-response-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-1.1.0.tgz", + "integrity": "sha1-p8TnWq6C87tJBOT0P2FWc7TVGMM=" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mockery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", + "integrity": "sha1-9O3g2HUMHJcnwnLqLGBiniyaHE8=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "sync-request": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-3.0.1.tgz", + "integrity": "sha1-yqEjWq+Im6UBB2oYNMQ2gwqC+3M=", + "requires": { + "concat-stream": "^1.4.7", + "http-response-object": "^1.0.1", + "then-request": "^2.0.1" + } + }, + "then-request": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-2.2.0.tgz", + "integrity": "sha1-ZnizL6DKIY/laZgbvYhxtZQGDYE=", + "requires": { + "caseless": "~0.11.0", + "concat-stream": "^1.4.7", + "http-basic": "^2.5.1", + "http-response-object": "^1.1.0", + "promise": "^7.1.1", + "qs": "^6.1.0" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } + } +} diff --git a/sb-task/package.json b/sb-task/package.json new file mode 100644 index 0000000..5d22922 --- /dev/null +++ b/sb-task/package.json @@ -0,0 +1,31 @@ +{ + "name": "sigbench", + "version": "1.0.0", + "description": "Azure DevOps Extension to signature benchmark your files.", + "main": "task.ts", + "repository": { + "type": "git", + "url": "git+https://github.com/cpz/sigbench.git" + }, + "keywords": [ + "VSTS", + "release", + "build", + "signature", + "benchmark", + "variable" + ], + "author": "Konstantin 'cpz' L.", + "license": "MIT", + "bugs": { + "url": "https://github.com/cpz/sigbench/issues" + }, + "homepage": "https://github.com/cpz/sigbench#readme", + "dependencies": { + "azure-pipelines-task-lib": "^2.9.6" + }, + "devDependencies": { + "@types/node": "^14.0.23", + "@types/q": "^1.5.4" + } +} diff --git a/sb-task/task.js b/sb-task/task.js new file mode 100644 index 0000000..dd2fe2f --- /dev/null +++ b/sb-task/task.js @@ -0,0 +1,200 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fs = __importStar(require("fs")); +var tl = __importStar(require("azure-pipelines-task-lib/task")); +var sigSize = tl.getInput('sigSize', true); // size of signatures +var percentPrecise = tl.getInput('percentPrecise', true); // percent precise +var file1 = tl.getPathInput('file1', true); // file 1 to compare +var file2 = tl.getPathInput('file2', true); // file 2 to compare +var print_matched = tl.getBoolInput('printMatched', true); // prints in console Signatures which similiar +var custom_Var = tl.getBoolInput('customVar', true); // creates variable $(Sigbench.Percent) +var f1 = []; +var f2 = []; +function GetSigFiles(inputFile, SigArray) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + console.log("##[debug]GetSigFiles()::" + inputFile); + return [2 /*return*/, new Promise(function (resolve, reject) { + var fetchData = []; + fs.createReadStream(inputFile, { highWaterMark: sigSize }) + .on('data', function (chunk) { + SigArray.push(chunk); + }) + .on('end', function () { + resolve(fetchData); + }) + .on('error', reject); + })]; + }); + }); +} +function difference(a1, a2) { + var a = [], diff = []; + for (var i = 0; i < a1.length; i++) + a[a1[i]] = a1[i]; + for (var i = 0; i < a2.length; i++) + if (a[a2[i]]) + delete a[a2[i]]; + else + a[a2[i]] = a2[i]; + for (var k in a) + diff.push(a[k]); + return diff; +} +function intersect(a, b) { + var ai = 0, bi = 0; + var result = []; + while (ai < a.length && bi < b.length) { + if (a[ai] < b[bi]) { + ai++; + } + else if (a[ai] > b[bi]) { + bi++; + } + else /* they're equal */ { + result.push(a[ai]); + ai++; + bi++; + } + } + return result; +} +// https://stackoverflow.com/a/18650828 +function formatBytes(bytes, decimals) { + if (decimals === void 0) { decimals = 2; } + if (bytes === 0) + return '0 Bytes'; + var k = 1024; + var dm = decimals < 0 ? 0 : decimals; + var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + var i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} +function precise(x, precision) { + if (precision === void 0) { precision = 4; } + return Number.parseFloat(x).toPrecision(precision); +} +// Start function +function run() { + return __awaiter(this, void 0, void 0, function () { + var f1_size, f2_size, inter, inter_arr_debug, inter_arr_command, inter_length, diff, diff_arr_debug, diff_length, DifferencePercent, IntersectionPercent, err_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 3, , 4]); + return [4 /*yield*/, GetSigFiles(file1, f1)]; + case 1: + _a.sent(); + return [4 /*yield*/, GetSigFiles(file2, f2)]; + case 2: + _a.sent(); + f1_size = f1.length * sigSize; + f2_size = f2.length * sigSize; + console.log('##[group]Information about files. (debug only)'); + console.log('##[debug]Signature Size (block size): ', sigSize); + console.log('##[debug]File 1 Signatures (total blocks in file 1): ', f1.length); + console.log('##[debug]File 2 Size: ', formatBytes(f1_size)); + console.log('##[debug]File 2 Signatures (total blocks in file 2): ', f2.length); + console.log('##[debug]File 2 Size: ', formatBytes(f2_size)); + console.log('##[debug]Total Signatures (blocks): ', f1.length + f2.length); + console.log('##[debug]Total Size: ', formatBytes(f1_size + f2_size)); + console.log('##[endgroup]'); + inter = intersect(f1, f2); + inter_arr_debug = inter.map(function (i) { return '##[debug]' + i; }); + console.log('##[group]Found Signtures (inter). (debug only)'); + console.log(inter_arr_debug); + console.log('##[endgroup]'); + if (print_matched) { + console.log('##[command]Signature Benchmark | Matched signatures: '); + inter_arr_command = inter.map(function (i) { return '##[command]' + i; }); + console.log(inter_arr_command); + } + else { + console.log('##[debug]Print Intersection set to false'); + } + inter_length = inter.length; + console.log('##[debug]Found Signtures Num (inter length): ', inter_length); + diff = difference(f1, f2); + diff_arr_debug = diff.map(function (i) { return '##[debug]' + i; }); + console.log('##[group]Found Signtures (diff). (debug only)'); + console.log(diff_arr_debug); + console.log('##[endgroup]'); + diff_length = diff.length; + console.log('##[debug]Found Signtures Num (diff length): ', diff_length); + DifferencePercent = 100 - diff_length / f2.length; + console.log('##[command]Difference Percent: ', DifferencePercent + '%'); + IntersectionPercent = inter_length / (f2.length + f1.length - inter_length); + console.log('##[command]Intersection Percent: ', IntersectionPercent + '%'); + if (custom_Var) { + tl.setVariable('Sigbench.DiffPercent', precise(DifferencePercent, percentPrecise)); + tl.setVariable('Sigbench.InterPercent', precise(IntersectionPercent, percentPrecise)); + } + else { + console.log('##[debug]Create Variables set to false'); + } + return [3 /*break*/, 4]; + case 3: + err_1 = _a.sent(); + tl.setResult(tl.TaskResult.Failed, err_1.message); + return [3 /*break*/, 4]; + case 4: return [2 /*return*/]; + } + }); + }); +} +run(); diff --git a/sb-task/task.json b/sb-task/task.json new file mode 100644 index 0000000..a9dd601 --- /dev/null +++ b/sb-task/task.json @@ -0,0 +1,93 @@ +{ + "id": "2eadfaf9-a99a-4a51-9815-6935b5aa39fe", + "name": "sigbench", + "friendlyName": "Signature Benchmark", + "description": "Azure DevOps Extension to signature benchmark your files.", + "author": "Konstantin 'cpz' L.", + "helpMarkDown": "https://github.com/cpz/sigbench", + "category": "Utility", + "visibility": [ + "Build", + "Release" + ], + "demands": [], + "version": { + "Major": "1", + "Minor": "0", + "Patch": "52" + }, + "minimumAgentVersion": "1.95.0", + "instanceNameFormat": "Signature Benchmark", + "groups": [{ + "name": "SigbenchConfig", + "displayName": "Signature Benchmark Configuration", + "isExpanded": true + }, + { + "name": "SigbenchData", + "displayName": "Signature Benchmark Advanced", + "isExpanded": false + } + ], + "inputs": [{ + "name": "sigSize", + "type": "string", + "label": "Signature Sizes", + "defaultValue": "32", + "required": true, + "groupName": "SigbenchConfig", + "helpMarkDown": "Signature Sizes (default: 32 or 34, because this length used by Battleye)" + }, + { + "name": "file1", + "type": "filePath", + "label": "File 1 to Compare", + "defaultValue": "**/*.dll", + "required": true, + "groupName": "SigbenchConfig", + "helpMarkDown": "Type path to file 1 to compare" + }, + { + "name": "file2", + "type": "filePath", + "label": "File 2 to Compare", + "defaultValue": "**/*.dll", + "required": true, + "groupName": "SigbenchConfig", + "helpMarkDown": "Type path to file 2 to compare" + }, + { + "name": "customVar", + "type": "boolean", + "label": "Create Variables", + "defaultValue": "false", + "required": false, + "groupName": "SigbenchData", + "helpMarkDown": "Creates variable $(Sigbench.DiffPercent) and $(Sigbench.InterPercent) which provides information about difference and intersection percentage. Example: 99.68362902369064 (difference) or 0.21652039927647887 (intersection)." + }, + { + "name": "printMatched", + "type": "boolean", + "label": "Print Matched Signatures", + "defaultValue": "false", + "required": false, + "groupName": "SigbenchData", + "helpMarkDown": "Prints signatures that matched both binaries." + }, + { + "name": "percentPrecise", + "type": "string", + "label": "Percent Precise", + "defaultValue": "4", + "required": false, + "groupName": "SigbenchData", + "helpMarkDown": "Changes Percent Precise (default: 4). Example: 99.68" + } + ], + "execution": { + "Node": { + "target": "task.js", + "argumentFormat": "" + } + } +} \ No newline at end of file diff --git a/sb-task/tsconfig.json b/sb-task/tsconfig.json new file mode 100644 index 0000000..c9f603c --- /dev/null +++ b/sb-task/tsconfig.json @@ -0,0 +1,69 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "skipLibCheck": true, /* Skip type checking of declaration files. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} diff --git a/vss-extension.json b/vss-extension.json new file mode 100644 index 0000000..85a859b --- /dev/null +++ b/vss-extension.json @@ -0,0 +1,45 @@ +{ + "manifestVersion": 1, + "id": "sigbench", + "publisher": "cpz", + "version": "1.0.52", + "name": "Sigbench", + "description": "Azure DevOps Extension to signature benchmark your files.", + "public": false, + "demands": ["api-version/3.0"], + "categories": ["Azure Pipelines"], + "targets": [ + { + "id": "Microsoft.VisualStudio.Services" + } + ], + "icons": { + "default": "images/extension-logo.jpg" + }, + "content": { + "details": { + "path": "README.md" + }, + "license": { + "path": "LICENSE.md" + } + }, + "contributions": [ + { + "id": "sigbench-task", + "type": "ms.vss-distributed-task.task", + "targets": [ + "ms.vss-distributed-task.task" + ], + "properties": { + "name": "sb-task" + } + } + ], + "files": [ + { + "path": "sb-task", + "addressable": true + } + ] +}