Skip to content

Commit

Permalink
DX-3316: Update to Use JS Ruleset and tmp Files (#15)
Browse files Browse the repository at this point in the history
* Update to use JS ruleset and tmp file storage.

* Remove unused dependency.

* Update src/static/.local.ruleset.js

Co-authored-by: Cameron Koegel <[email protected]>

* Update download ruleset function structure.

* Update local ruleset file.

* Updatee local ruleset.

---------

Co-authored-by: Cameron Koegel <[email protected]>
  • Loading branch information
matthewkmartin and ckoegel authored Feb 16, 2023
1 parent d15cbef commit 8591208
Show file tree
Hide file tree
Showing 6 changed files with 409 additions and 270 deletions.
22 changes: 12 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@stoplight/spectral-runtime": "^1.1.2",
"axios": "^0.27.2",
"chalk": "^4.1.2",
"yaml": "^2.1.1",
"tmp": "^0.2.1",
"yargs": "^17.5.1"
}
}
85 changes: 33 additions & 52 deletions src/commands/lint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import axios from "axios";
import type { Arguments } from "yargs";

const fs = require("fs");
const tmp = require("tmp");
const homeDir = require("os").homedir();
const path = require("path");
const util = require("util");
const chalk = require("chalk");
const YAML = require("yaml");
const Parsers = require("@stoplight/spectral-parsers");
const { fetch } = require("@stoplight/spectral-runtime");
const { Spectral, Document } = require("@stoplight/spectral-core");
Expand All @@ -34,37 +34,30 @@ interface Result {
};
}

const rulesetUrl = "https://bw-linter-ruleset.s3.amazonaws.com/ruleset.yml";
var rulesetFilename = ".remote.spectral.yaml";
var rulesetFilepath = path.join(__dirname, rulesetFilename);
const tmpRulesetFile = tmp.fileSync({ postfix: ".js" });
const RULESET_URL = "https://bw-linter-ruleset.s3.amazonaws.com/ruleset.js";

async function downloadRuleset(
fileUrl: string,
outputLocationPath: string
): Promise<any> {
const writer = fs.createWriteStream(outputLocationPath);

return axios({
const downloadRemoteRuleset = async () => {
const response = await axios({
method: "get",
url: fileUrl,
responseType: "stream",
}).then((response) => {
return new Promise((resolve, reject) => {
response.data.pipe(writer);
let error: any = null;
writer.on("error", (err: any) => {
error = err;
writer.close();
reject(err);
});
writer.on("close", () => {
if (!error) {
resolve(true);
}
});
});
url: RULESET_URL,
});
}

// Check for failure response
if (response.status != 200) {
console.error(`Failed to retrieve ruleset from AWS.`);
return false;
}

try {
fs.writeFileSync(tmpRulesetFile.name, response.data);
return true;
} catch (err) {
// If there is an issue writing, default to local
console.error(`Failed to write ruleset to file, error: ${err}`);
return false;
}
};

function saveResult(resultFilename: string, homeDir: string, result: Object) {
try {
Expand All @@ -77,14 +70,6 @@ function saveResult(resultFilename: string, homeDir: string, result: Object) {
}
}

function deleteRemoteRuleset() {
try {
fs.unlinkSync(path.join(__dirname, rulesetFilename));
} catch (err) {
console.error(err);
}
}

exports.command = "lint <specPath>";
exports.aliases = ["l"];
exports.describe = "Lint an OpenAPI Specification";
Expand All @@ -110,29 +95,29 @@ exports.handler = async (argv: Arguments<Options>): Promise<void> => {
// Open the provided API Spec
const { specPath, save, json, ruleset } = argv;
const specFile = fs.readFileSync(specPath, "utf8");
const spec = YAML.parse(specFile);
var specName = path.basename(specPath, path.extname(specPath));
let specName = path.basename(specPath, path.extname(specPath));
let rulesetFilepath;

// attempt to download the ruleset if no local file was provided
var downloadSuccess;
// Attempt to download the ruleset if no local file was provided
if (!ruleset) {
downloadSuccess = true;
try {
await downloadRuleset(rulesetUrl, rulesetFilepath);
} catch (error) {
const downloadSuccess = await downloadRemoteRuleset();
if (downloadSuccess) {
// Use the downloaded ruleset
rulesetFilepath = tmpRulesetFile.name;
} else {
// Error downloading the remote ruleset - use the bundled local copy
console.warn(
chalk.yellow.bold(
"Failed to download remote ruleset. Using Local Copy."
)
);
console.log("Note that lint results may vary from production ruleset.");
rulesetFilename = "./static/.local.spectral.yaml";
const rulesetFilename = "./static/.local.ruleset.js";
rulesetFilepath = path.join(__dirname, "..", rulesetFilename);
console.log(rulesetFilepath);
downloadSuccess = false;
}
} else {
// Use the provided ruleset
rulesetFilepath = ruleset;
}

Expand All @@ -141,6 +126,7 @@ exports.handler = async (argv: Arguments<Options>): Promise<void> => {
spectral.setRuleset(
await bundleAndLoadRuleset(rulesetFilepath, { fs, fetch })
);
spectral.set;

// Run the linter
await spectral
Expand All @@ -163,9 +149,4 @@ exports.handler = async (argv: Arguments<Options>): Promise<void> => {
saveResult(specName + "_lint_result.json", homeDir, result);
}
});

// If ruleset was downloaded successfully - delete it
if (downloadSuccess) {
deleteRemoteRuleset();
}
};
Loading

0 comments on commit 8591208

Please sign in to comment.