Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into condition-parser
Browse files Browse the repository at this point in the history
  • Loading branch information
DinoChiesa committed Dec 5, 2023
2 parents 522324c + 0bf2c26 commit 332272d
Show file tree
Hide file tree
Showing 34 changed files with 978 additions and 99 deletions.
42 changes: 37 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,8 @@ is written there.
If you do not also specify `--quiet` the report will go to both stdout and to
the specified filesystem destination.



#### Listing plugins

List plugins and formatters, with or without --externalPluginsDirectory.
```sh
apigeelint --list
Expand All @@ -132,11 +131,42 @@ apigeelint --list -x ./externalPlugins

apigeelint --list --externalPluginsDirectory ./externalPlugins

```
```

#### Selecting a profile

Apigee X/hybrid is very similar to Apigee Edge, but there are differences in the
supported policy types, and some of the supported configuration options. For
example, policies like GraphQL, the AssertCondition, or the Integration policy
step types are available only in X/hybrid.

As a result of these differences, a proxy that is valid in Apigee Edge might not
work in Apigee X, and vice versa. Apigeelint uses the `--profile` option to
allow the user to configure which target environment is intended: Edge
(`--profile apigee`) or X/hybrid (`--profile apigeex`). The default is `apigee`.

```sh
# lint a proxy that will be used in Apigee X/hybrid
apigeelint -f table.js --profile apigeex -s path/to/your/apiproxy

# lint a proxy that will be used in Apigee Edge
apigeelint -f table.js --profile apigee -s path/to/your/apiproxy
```

As an example, if you lint a proxy that uses the GraphQL policy type, and you
specify the `apigee` profile, the PO028 plugin will issue an error, telling you
that the GraphQL policy is not available in the apigee profile. If you lint the
same proxy with the `apigeex` profile, apigeelint will not generate an error.

The selection of a profile affects other checks, too. For example, [the Google
Authentication feature](https://cloud.google.com/apigee/docs/api-platform/security/google-auth/overview)
is available only in X/hybrid.


## Does this tool just lint or does it also check style?

This tool does both traditional linting (looking for problematic patterns) and style checking (enforcement of conventions). You can use it for both.
This tool does both traditional linting (looking for problematic patterns) and
style checking (enforcement of conventions). You can use it for both.

## Tests

Expand All @@ -145,7 +175,7 @@ The `test` directory includes scripts to exercise a subset of rules. Overall lin
```
apigeelint -s ./test/fixtures/resources/sampleProxy/24Solver/apiproxy/
```
This sample exhibits many bad practices and as such generates some noisy output.
This sample exhibits many bad practices and as such generates numerous errors and warnings in output.

In a development installation, the equivalent to the command above is:
```
Expand Down Expand Up @@ -260,6 +290,8 @@ This is the current list:
| Endpoints |   |   |   |   |
|   |:white_check_mark:| EP001 | CORS Policy attachment | Check for multiple CORS policies, or attachment to Target Endpoint. |
|   |:white_check_mark:| EP002 | Misplaced Elements | Check for commonly misplaced configuration elements in Proxy and Target Endpoints. |
| Features |   |   |   |   |
|   |:white_check_mark:| FE001 | Use of Authentication element | Check for the Authentication element in policies or in Target Endpoints. |
| Deprecation |   |   |   |   |
|   |:white_check_mark:| DC001 | ConcurrentRateLimit Policy Deprecation | Check usage of deprecated policy ConcurrentRateLimit. |
|   |:white_check_mark:| DC002 | OAuth V1 Policies Deprecation | Check usage of deprecated OAuth V1 policies. |
Expand Down
32 changes: 17 additions & 15 deletions lib/package/Condition.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019 Google LLC
Copyright 2019, 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -14,14 +14,14 @@
limitations under the License.
*/

var TruthTable = require("./TruthTable.js");
const TruthTable = require("./TruthTable.js");

function Condition(element, parent) {
this.parent = parent;
this.element = element;
}

Condition.prototype.getExpression = function() {
Condition.prototype.getExpression = function () {
return (
(this.element.childNodes &&
this.element.childNodes[0] &&
Expand All @@ -30,51 +30,53 @@ Condition.prototype.getExpression = function() {
);
};

Condition.prototype.getMessages = function() {
Condition.prototype.getMessages = function () {
return this.parent.getMessages();
};

Condition.prototype.getElement = function() {
Condition.prototype.getElement = function () {
return this.element;
};

Condition.prototype.getParent = function() {
Condition.prototype.getParent = function () {
return this.parent;
};

Condition.prototype.getLines = function(start, stop) {
Condition.prototype.getLines = function (start, stop) {
return this.parent.getLines(start, stop);
};

Condition.prototype.getSource = function() {
Condition.prototype.getSource = function () {
if (!this.source) {
var start = this.element.lineNumber - 1,
const start = this.element.lineNumber - 1,
stop = this.element.nextSibling.lineNumber - 1;
this.source = this.getLines(start, stop);
}
return this.source;
};

Condition.prototype.getTruthTable = function() {
Condition.prototype.getTruthTable = function () {
if (!this.truthTable) {
this.truthTable = new TruthTable(this.getExpression());
this.truthTable = new TruthTable(
this.getExpression().replace(/(\n| +)/g, " ")
);
}
return this.truthTable;
};

Condition.prototype.addMessage = function(msg) {
Condition.prototype.addMessage = function (msg) {
if (!msg.hasOwnProperty("entity")) {
msg.entity = this;
}
this.parent.addMessage(msg);
};

Condition.prototype.onConditions = function(pluginFunction, cb) {
Condition.prototype.onConditions = function (pluginFunction, cb) {
pluginFunction(this, cb);
};

Condition.prototype.summarize = function() {
var summary = {};
Condition.prototype.summarize = function () {
const summary = {};
summary.type = "Condition";
summary.condition = this.getExpression();
try {
Expand Down
39 changes: 22 additions & 17 deletions lib/package/plugins/CC001-checkConditionForLiterals.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2020 Google LLC
Copyright 2019-2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -14,27 +14,32 @@
limitations under the License.
*/

const ruleId = require("../myUtil.js").getRuleId(),
debug = require("debug")("apigeelint:" + ruleId);

const plugin = {
ruleId : require("../myUtil.js").getRuleId(),
name: "Literals in Conditionals",
message:
"Single term literals statically evaluate to True or False and needlessly complicate a conditional at best, at worst they create dead code or are misleading in implying condtional execution.",
fatal: false,
severity: 1, //warning
nodeType: "Condition",
enabled: true
};
ruleId,
name: "Literals in Conditionals",
message:
"Single term literals statically evaluate to True or False and needlessly complicate a conditional at best, at worst they create dead code or are misleading in implying condtional execution.",
fatal: false,
severity: 1, //warning
nodeType: "Condition",
enabled: true
};

const onCondition = function(condition, cb) {
condition.getTruthTable().getAST(function(ast) {
let hasLiteral = false,
nodes = [ast],
actions = [{ action: "root", parent: undefined }];
const onCondition = function (condition, cb) {
debug(`onCondition (${condition.getExpression()})`);
condition.getTruthTable().getAST(function (ast) {
let hasLiteral = false;
const nodes = [ast],
actions = [{ action: "root", parent: undefined }];

while (nodes[0] && !hasLiteral) {
let node = nodes.pop(),
const node = nodes.pop(),
parentAction = actions.pop();

debug(`node (${JSON.stringify(node)})`);
if (
node.type === "constant" &&
(!parentAction.parent ||
Expand All @@ -55,7 +60,7 @@ const onCondition = function(condition, cb) {
});
} else if (node.args) {
//lets also capture the prior action
let act = { action: node.action, parent: undefined };
const act = { action: node.action, parent: undefined };
if (parentAction && parentAction.action) {
act.parent = parentAction.action;
}
Expand Down
Loading

0 comments on commit 332272d

Please sign in to comment.