Skip to content

Commit

Permalink
mega-linter-runner --codetotal (#2877)
Browse files Browse the repository at this point in the history
* runner v0

* Allow to run CodeTotal with a single command npx mega-linter-runner@beta --codetotal

* Manage browser open

* Add codetotal-url option

* Add colors in messages

* changelog

* changelog

* cspell !

* [MegaLinter] Apply linters fixes

---------

Co-authored-by: nvuillam <nicolas.vuillamy@ox.security>
Co-authored-by: nvuillam <nvuillam@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 9, 2023
1 parent 8d5dd3e commit 832236e
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 10 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@
"codebases",
"codeclimate",
"codecov",
"codetotal",
"codenarcargs",
"codeql",
"codestyle",
Expand Down
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ Note: Can be used with `oxsecurity/megalinter@beta` in your GitHub Action mega-l
- Features
- Allow to define linter_key**_COMMAND_REMOVE_ARGUMENTS** to remove a command line argument internally added by MegaLinter

- Redis reporter
- Return URL of linter icons when available, in property `iconPngUrl`

- Fixes
- Replace `https://megalinter.io/config-file` by `https://megalinter.io/latest/config-file` to avoid lychee 404 detection
- Improve docs for posting comments to PRs in GitHub Enterprise

- CodeTotal
- Redis reporter: Return URL of linter icons when available, in property `iconPngUrl`
- Allow to run CodeTotal with a single command `npx mega-linter-runner@beta --codetotal` , that opens CodeTotal in Web Browser once started

- Linter versions upgrades
- [cfn-lint](https://github.com/aws-cloudformation/cfn-lint) from 0.79.2 to **0.79.3** on 2023-07-26
- [bicep_linter](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/linter) from 0.19.5 to **0.20.4** on 2023-08-03
Expand Down
12 changes: 6 additions & 6 deletions docs/reporters/GitHubCommentReporter.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ Click on hyperlinks to access detailed logs

## Configuration

| Variable | Description | Default value | Notes |
|-------------------------|-------------------------------------------------------------------------------------------|--------------------------|----------|
| GITHUB_COMMENT_REPORTER | Activates/deactivates reporter | true | |
| Variable | Description | Default value | Notes |
|-------------------------|-------------------------------------------------------------------------------------------|--------------------------|----------------------------------------------|
| GITHUB_COMMENT_REPORTER | Activates/deactivates reporter | true | |
| GITHUB_API_URL | URL where the github API can be reached<br/>Must be overridden if using GitHub Enterprise | `https://api.github.com` | For GHE, use `https://my.company.com/api/v3` |
| GITHUB_SERVER_URL | URL of the GitHub instance<br/>Must be overridden if using GitHub Enterprise | `https://github.com` | |
| CI_ACTION_RUN_URL | URL of the CI job visualization page url (if using Github but not GitHub Actions) | <!-- --> | |
| REPORTERS_MARKDOWN_TYPE | Set to `simple` to avoid external images in generated markdown | `advanced` | |
| GITHUB_SERVER_URL | URL of the GitHub instance<br/>Must be overridden if using GitHub Enterprise | `https://github.com` | |
| CI_ACTION_RUN_URL | URL of the CI job visualization page url (if using Github but not GitHub Actions) | <!-- --> | |
| REPORTERS_MARKDOWN_TYPE | Set to `simple` to avoid external images in generated markdown | `advanced` | |
29 changes: 28 additions & 1 deletion mega-linter-runner/lib/ascii.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,31 @@ function asciiArt() {
`;
}

module.exports = { asciiArt };
function asciiArtCodeTotal() {
return `
.:oool' ,looo;
.xNXNXl .dXNNXo.
lXXXX0c. 'oKXXN0;
.oKNXNX0kxdddddddoc,. .;lodddddddxk0XXXX0c
.:kKXXXXXXXXXXXXNXX0dllx0XXXXXXXXXXXXXXXKd,
.,cdkOOOOOOOO0KXXXXXXXXXXK0OOOOOOOkxo:'
'ckKXNNNXkc'
':::::;. .c0XX0l. .;::::;.
'xXXXXXx' :kx: ;OXXXXKd.
.dKNNXXO; .. :0XXXXKl.
.lKXXXX0: .lKXXXX0:
:0XXXXKl. .dXXXXXk,
;kXXXXKd:cxXXXXXx'
'xXNXXXXXXXXXKo.
.oKXXXXNXXX0l.
.lKNNXNNXO:
,looool'
==========================================================
============= CodeTotal, by OX Security ==============
============= https://codetotal.io ===============
==========================================================
`;
}

module.exports = { asciiArt, asciiArtCodeTotal };
114 changes: 114 additions & 0 deletions mega-linter-runner/lib/codetotal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#! /usr/bin/env node
"use strict";
const { spawnSync, spawn } = require("child_process");
const c = require("chalk");
const fs = require("fs-extra");
const https = require('https');
const open = require("open");
const path = require("path");
const which = require("which");
const { asciiArtCodeTotal } = require("./ascii");

class CodeTotalRunner {
constructor(options = {}) {
this.options = options;
}

async run() {
console.log(asciiArtCodeTotal());

// Retrieve docker-compose
if (!fs.existsSync(path.join(process.cwd(), 'docker-compose.yml'))) {
const dockerComposeUrl = "https://raw.githubusercontent.com/oxsecurity/codetotal/main/docker-compose.yml";
console.info(c.cyan(`Downloading latest docker-compose.yml from ${c.bold(dockerComposeUrl)} ...`));
https.get(dockerComposeUrl, resp => resp.pipe(fs.createWriteStream(path.join(process.cwd(), 'docker-compose.yml'))));
await new Promise(r => setTimeout(r, 2000));
}

// Check for docker installation
const whichPromise = which("docker");
whichPromise.catch(() => {
console.error(c.red(`
ERROR: Docker engine has not been found on your system.
- to run CodeTotal locally, please install docker desktop: https://www.docker.com/products/docker-desktop`));
});

// Get platform to use with docker pull & run
const imagesPlatform = this.options.platform || "linux/amd64";
const platformVars = {
"DOCKER_DEFAULT_PLATFORM": imagesPlatform
};

// Pull docker image
if (this.options.nodockerpull !== true) {
console.info(c.cyan(`Pulling docker-compose.yml images...`));
console.info(c.grey(
"INFO: this operation can be long during the first use of CodeTotal"
));
console.info(c.grey(
"The next runs, it will be immediate (thanks to docker cache !)"
));
console.log("Running command: " + c.whiteBright(c.bgGray("docker-compose " + ["-f", "docker-compose.yml", "pull"].join(" "))));
const spawnResPull = spawnSync(
"docker-compose",
["-f", "docker-compose.yml", "pull"],
{
detached: false,
stdio: "inherit",
windowsHide: true,
windowsVerbatimArguments: true,
env: { ...process.env, ...platformVars }
}
);
// Manage case when unable to pull docker image
if (spawnResPull.status !== 0) {
return {
status: 2,
errorMsg: `Unable to pull docker images: \n${JSON.stringify(
spawnResPull,
null,
2
)}`,
};
}
} else {
console.log(`Skipped pull of docker images (--nodockerpull used)`);
}

// Prepare docker-compose command
const commandArgs = ["-f", "docker-compose.yml", "up"];

// Prepare interval to check localhost is open
let isOpen = false;
const uiUrl = this.options["codetotal-url"] || "http://localhost:8081/";
let interval = setInterval(async () => {
let response;
try {
response = await fetch(uiUrl);
} catch (e) {
// URL not available yet
return;
}
const statusCode = response.status;
if (statusCode >= 200 && statusCode <= 400 && isOpen === false) {
clearInterval(interval);
isOpen = true;
console.log(c.green("CodeTotal is started: opening " + uiUrl + " ..."));
open(uiUrl);
console.log(c.yellow("Hit CTRL+C to terminate"));
}
}, 2000);

// Call docker run
console.log("Running command: " + c.whiteBright(c.bgGray("docker-compose " + commandArgs.join(" "))));
const spawnOptions = {
stdio: "inherit",
windowsHide: true,
env: { ...process.env, ...platformVars }
};
const spawnRes = spawn("docker-compose", commandArgs, spawnOptions);
return spawnRes;
}
}

module.exports = { CodeTotalRunner };
11 changes: 11 additions & 0 deletions mega-linter-runner/lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ module.exports = optionator({
type: "Boolean",
description: "Remove MegaLinter Docker container when done",
},
{
option: "codetotal",
type: "Boolean",
description: "Run CodeTotal locally",
},
{
option: "codetotal-url",
type: "String",
default: "http://localhost:8081/",
description: "URL Hosting CodeTotal once launched",
},
],
mutuallyExclusive: [
["help", "version", "install"],
Expand Down
7 changes: 7 additions & 0 deletions mega-linter-runner/lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const path = require("path");
const which = require("which");
const fs = require("fs-extra");
const { MegaLinterUpgrader } = require("./upgrade");
const { CodeTotalRunner} = require("./codetotal");
const { DEFAULT_RELEASE } = require("./config");

class MegaLinterRunner {
Expand Down Expand Up @@ -59,6 +60,12 @@ class MegaLinterRunner {
return { status: 0 };
}

if (options.codetotal) {
const codeTotalRunner = new CodeTotalRunner(options);
await codeTotalRunner.run();
return {status: 0 }
}

// Build MegaLinter docker image name with flavor and release version
const release = options.release in ["stable"] ? DEFAULT_RELEASE : options.release;
const dockerImageName =
Expand Down

0 comments on commit 832236e

Please sign in to comment.