Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
84809ba
V5 build support
Apr 2, 2019
8d6bb57
Update README.md
Apr 2, 2019
c28118a
Update README.md
Apr 2, 2019
683e19a
clean up debug logging
Apr 3, 2019
48bdfa0
clear auth state when icp4d url is changed
Apr 3, 2019
b18a515
action/epic/reducer cleanup
Apr 4, 2019
901926b
toolkit cache refresh fix
Apr 8, 2019
8efd063
improve error handling if unable to reach icp4d master node
Apr 8, 2019
6f6545c
Update dependencies, clean up util imports
Apr 8, 2019
d950ede
fix util index
Apr 8, 2019
a6bcbec
Improved error handling if toolkit path setting is not valid
Apr 8, 2019
90345c8
spl compile error message handling fixes
Apr 9, 2019
4c1e952
add List Toolkits command to see build service toolkits and local too…
Apr 9, 2019
a04889d
filter toolkits that get included in source archive
Apr 9, 2019
658400e
update dependencies
Apr 9, 2019
64ac93d
fix lint handling in case of building app against v4 and v5
Apr 10, 2019
2ecdc81
re-order config settings
Apr 10, 2019
0ccef5f
fix toolkit return property
Apr 10, 2019
8d92df7
fix if there are no toolkits to include in source archive
Apr 10, 2019
3ab800c
migration for streaming analytics credentials setting
Apr 10, 2019
c2fb76b
keep job submission notification up until success or failure
Apr 26, 2019
ee3592a
safe type handling for url endpoints
Apr 26, 2019
70068c4
support configurable request timeouts
Apr 26, 2019
441d94d
Merge pull request #41 from IBMStreams/v5Support
Apr 26, 2019
55e6e3f
default to use streaming analytics
Apr 26, 2019
350de9b
Merge pull request #42 from IBMStreams/v5Support
Apr 26, 2019
5b9b970
updated version
petenicholls Apr 26, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"presets": ["flow", "env", "stage-2"],
"plugins": [
["babel-plugin-dynamic-import-node"],
["dynamic-import-node"]
],
"sourceMap": "inline"
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"dynamic-import-node"
]
}
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ root = true

[*]
charset = utf-8
indent_style = tab
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
Expand Down
56 changes: 56 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"parser": "babel-eslint",
"extends": "airbnb",
"env": {
"es6": true,
"browser": true,
"node": true,
"jquery": true
},
"rules": {
"array-callback-return": ["off"],
"arrow-body-style": ["off"],
"arrow-parens": ["off"],
"class-methods-use-this": 0,
"compat/compat": 2,
"consistent-return": "off",
"comma-dangle": "off",
"generator-star-spacing": "off",
"import/no-unresolved": ["error", { "ignore": ["electron", "atom"] }],
"import/no-extraneous-dependencies": "off",
"jsx-a11y/no-static-element-interactions": 0,
"jsx-a11y/label-has-associated-control": [ 2, {
"controlComponents": [ "Field" ]
}],
"jsx-a11y/label-has-for": 0,
"max-len": ["off"],
"no-cond-assign": ["error", "except-parens"],
"no-console": 1,
"no-param-reassign": ["error", { "props": false }],
"no-return-assign": ["off"],
"no-use-before-define": "off",
"no-underscore-dangle": "off",
"no-unused-vars": ["error", { "args": "none" }],
"prefer-destructuring": ["error", {"array": false}],
"promise/param-names": 2,
"promise/always-return": 0,
"promise/catch-or-return": 0,
"promise/no-native": 0,
"react/jsx-no-bind": "off",
"react/jsx-filename-extension": ["error", { "extensions": [".js", ".jsx"] }],
"react/no-find-dom-node": 0,
"react/no-string-refs": 0,
"react/prefer-stateless-function": "off",
"react/sort-comp": "off"
},
"plugins": [
"import",
"promise",
"compat",
"react"
],
"globals": {
"atom": "readable",
"electron": "readable"
}
}
43 changes: 0 additions & 43 deletions .eslintrc.js

This file was deleted.

21 changes: 0 additions & 21 deletions .flowconfig

This file was deleted.

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
npm-debug.log
node_modules
.vscode
package-lock.json
yarn.lock
toolkitsCache
3 changes: 3 additions & 0 deletions .jscsrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"requireTrailingComma": false
}
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,28 @@ This is the initial public release. For best results you should also install th
* ide-ibmstreams

### Setup Instructions
#### Build - Streaming Analytics Credentials
The <b>build-ibmstreams</b> package requires a running IBM Streaming Analytics service. SPL applications will be built and deployed on this service. If you need to create one, start <a href="https://cloud.ibm.com/catalog/services/streaming-analytics" rel="noopener" target="_blank">here</a> and follow the instructions to create an account.

### Build

You may either build and run your Streams applications on an [IBM Cloud Streaming Analytics service](https://cloud.ibm.com/docs/services/StreamingAnalytics/index.html#gettingstarted) (V4.3) or an [IBM Cloud Private for Data (ICP4D) Streams add-on instance](https://www.ibm.com/support/knowledgecenter/SSQNUZ_current/com.ibm.icpdata.doc/streams/intro.html) (V5).

#### IBM Cloud: Streaming Analytics service
A running IBM Streaming Analytics service is required. You must provide your service credentials (in JSON format) in order for this extension to connect to your service. SPL applications will be built and deployed on this service. If you need to create one, start [here](https://cloud.ibm.com/catalog/services/streaming-analytics) and follow the instructions to create an account.

<b>Note:</b>The service needs to support V2 of the rest api.

Once you have an account go to your <a href="https://cloud.ibm.com/resources?groups=resource-instance" rel="noopener" target="_blank">dashboard</a> and select the Streaming Analytics service you want to use. You need to make sure it is running and then copy your credentials to the clipboard. To get your credentials select <b>Service Credentials</b> from the actions on the left. From the credentials page, press <b>View credentials</b> for the one you want to use and press the copy button in the upper right side of the credentials to copy them to the clipboard.
Once you have an account go to your [Dashboard](https://cloud.ibm.com/resources?groups=resource-instance) and select the Streaming Analytics service you want to use. Ensure that it is running and then create a new set of credentials. Select the __Service credentials__ tab on the left and select your existing credentials or click on the __New credential__ button. On the credentials page, click on the __View credentials__ action and click on the __Copy__ button in the top-right corner of the credentials snippet to copy them to the clipboard.

In Atom there is a setting in the <b>build-ibmstreams</b> package for the credentials. Go to <b>Atom->Preferences->Packages</b> and press the <b>Settings</b> button on the <b>build-ibmstreams</b> package and paste your credentials into the setting.
In Atom, to open __build-ibmstreams__ package settings go to Atom->Preferences->Packages and press the Settings button on the build-ibmstreams package. Select __IBM Cloud Streaming Analytics service__ in the __Build and submit__ dropdown and then paste your credentials in the __Streaming Analytics Credentials__ field.
![](./images/atomcredssetting.png)

#### IBM Cloud Private for Data: Streams add-on instance

A provisioned IBM Streams add-on is required. You must provide your IBM Cloud Private for Data URL in order for this extension to connect to your add-on instance. Enter your url in the __build-ibmstreams__ package settings and select __IBM Cloud Private for Data Streams addon__ in the __Build and submit__ dropdown.

If you need to provision an add-on, start [here](https://www.ibm.com/support/knowledgecenter/SSQNUZ_current/com.ibm.icpdata.doc/streams/intro.html) and follow the instructions.



### SPL Application build
![](./images/build.gif)
157 changes: 90 additions & 67 deletions lib/LintHandler.js
Original file line number Diff line number Diff line change
@@ -1,78 +1,101 @@
// @flow
"use strict";
"use babel";
'use babel';
'use strict';

export class LintHandler {
import { StreamsUtils } from './util';

linter = null;
msgRegex = null;
appRoot = null;
const CONF_API_VERSION_V4 = 'v4';
const CONF_API_VERSION_V5 = 'v5';

constructor(linter, msgRegex, appRoot) {
this.linter = linter;
this.msgRegex = msgRegex;
this.appRoot = appRoot;
}
export default class LintHandler {
linter = null;

msgRegex = null;

lint(input) {
if (!this.linter || !input) {
return;
}
appRoot = null;

if (input.output && Array.isArray(input.output)) {
let convertedMessages = input.output.map(
(message) => message.message_text
).filter(
// filter only messages that match expected format
(msg) => msg.match(this.msgRegex)
).map(
(msg) => {
// return objects for each message
let parts = msg.match(this.msgRegex);
let severityCode = parts[4].trim().substr(parts[4].trim().length - 1);
let severity = "info";
if (severityCode) {
switch (severityCode) {
case "I":
severity = "info";
break;
case "W":
severity = "warning";
break;
case "E":
severity = "error";
break;
default:
break;
}
}
let absolutePath = parts[1];
if (this.appRoot && typeof(this.appRoot) === "string") {
absolutePath = `${this.appRoot}/${parts[1]}`;
}
apiVersion = null;

return {
severity: severity,
location: {
constructor(linter, appRoot, apiVersion) {
this.linter = linter;
this.appRoot = appRoot;
this.apiVersion = apiVersion;
this.msgRegex = apiVersion === CONF_API_VERSION_V4 ? StreamsUtils.SPL_MSG_REGEX : StreamsUtils.SPL_MSG_REGEX_V5;
}

file: absolutePath,
position: [
[parseInt(parts[2])-1 ,parseInt(parts[3])-1],
[parseInt(parts[2])-1,parseInt(parts[3])]
], // 0-indexed
},
excerpt: parts[4],
description: parts[5],
};
}
);
setV5() {
this.apiVersion = CONF_API_VERSION_V5;
this.msgRegex = StreamsUtils.SPL_MSG_REGEX_V5;
}

this.linter.setAllMessages(convertedMessages);
setV4() {
this.apiVersion = CONF_API_VERSION_V4;
this.msgRegex = StreamsUtils.SPL_MSG_REGEX;
}

if (Array.isArray(convertedMessages) && convertedMessages.length > 0) {
atom.workspace.open("atom://nuclide/diagnostics");
}
}
}
lint(input) {
if (!this.linter || !input) {
return;
}
let messages = [];
if (input.output) {
this.setV4();
messages = input.output.map(message => message.message_text);
} else if (Array.isArray(input)) {
this.setV5();
messages = input;
}

if (Array.isArray(messages)) {
const convertedMessages = messages.filter(
// filter only messages that match expected format
(msg) => msg.match(this.msgRegex)
).map(
(msg) => {
// return objects for each message
const parts = msg.match(this.msgRegex);
if (parts && parts.length > 4) {
const severityCode = parts[4].trim().substr(parts[4].trim().length - 1);
let severity = 'info';
if (severityCode) {
switch (severityCode) {
case 'I':
severity = 'info';
break;
case 'W':
severity = 'warning';
break;
case 'E':
severity = 'error';
break;
default:
break;
}
}
let absolutePath = parts[1];
if (this.appRoot && typeof (this.appRoot) === 'string') {
absolutePath = `${this.appRoot}/${parts[1]}`;
}
return {
severity,
location: {
file: absolutePath,
position: [
[parseInt(parts[2], 10) - 1, parseInt(parts[3], 10) - 1],
[parseInt(parts[2], 10) - 1, parseInt(parts[3], 10)]
], // 0-indexed
},
excerpt: parts[4],
description: parts[5],
};
}
}
);

this.linter.setAllMessages(convertedMessages);

if (Array.isArray(convertedMessages) && convertedMessages.length > 0) {
atom.workspace.open('atom://nuclide/diagnostics');
}
}
}
}
Loading