Skip to content
This repository was archived by the owner on Dec 17, 2024. It is now read-only.

Commit 7c1f6f4

Browse files
committed
updates to generalize editor for more languages
1 parent 65c4683 commit 7c1f6f4

File tree

13 files changed

+149
-56
lines changed

13 files changed

+149
-56
lines changed

app/content/css/ui.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ sidecar pre {
835835
/* no margin for action source code */
836836
margin: 0;
837837
}
838-
sidecar:not(.entity-is-actions) .action-content {
838+
sidecar:not(.entity-is-actions):not(.entity-is-apps) .action-content {
839839
display: none;
840840
}
841841
sidecar:not(.entity-is-activations) .activation-content {

app/content/js/command-tree.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ const commandNotFound = (argv, partialMatches) => {
590590
const availablePartials = (partialMatches || []).filter(({options}) => options.usage),
591591
anyPartials = availablePartials.length > 0
592592

593+
console.error(commandNotFoundMessage, argv)
593594
const error = anyPartials ? formatPartialMatches(availablePartials) : new Error(commandNotFoundMessage)
594595
error.code = 404
595596

app/content/js/repl.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,7 @@ self.exec = (commandUntrimmed, execOptions) => {
10611061
return err
10621062
} else if (!nested && !rethrowIt) {
10631063
debug('reporting command execution error to user via repl')
1064+
console.error(err)
10641065
ui.oops(block, nextBlock)(err)
10651066
} else {
10661067
debug('rethrowing command execution error')

app/content/js/ui.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,10 @@ const ui = (function() {
993993
const container = sidecar.querySelector('.custom-content')
994994
removeAllDomChildren(container)
995995
container.appendChild(custom.content)
996+
997+
if (custom && custom.badges) {
998+
custom.badges.forEach(addBadge)
999+
}
9961000
}
9971001

9981002
/**
@@ -1126,6 +1130,8 @@ const ui = (function() {
11261130
*
11271131
*/
11281132
const addBadge = (badgeText, { css, onclick }={}) => {
1133+
debug('addBadge', badgeText)
1134+
11291135
const sidecar = document.querySelector('#sidecar'),
11301136
header = sidecar.querySelector('.sidecar-header'),
11311137
badges = header.querySelector('.badges')
@@ -1269,6 +1275,7 @@ const ui = (function() {
12691275
indexEntryJavascript = zip.getEntry('index.js'),
12701276
indexEntry = indexEntryJavascript
12711277
|| zip.getEntry('index.py')
1278+
|| zip.getEntry('__main__.py')
12721279
|| zip.getEntry('index.php')
12731280
|| zip.getEntry('index.swift')
12741281

app/demos/hello.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#
2+
# Copyright 2018 IBM Corporation
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
# not yet supported:
18+
#def hello(args):
19+
# return {
20+
# "msg": f"hello {args['name']}"
21+
# }
22+
# composer.sequence(hello)
23+
24+
composer.sequence(lambda env, args: { "msg": "hello " + args['name'] })

app/plugins/modules/editor/lib/edit.js

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ const persisters = {
134134
const fs = require('fs'),
135135
tmp = require('tmp')
136136

137-
tmp.file({ prefix: 'shell-', postfix: '.js' }, (err, filepath, fd, cleanup) => {
137+
tmp.file({ prefix: 'shell-', postfix: extension(app.exec.kind) }, (err, filepath, fd, cleanup) => {
138138
if (err) {
139139
reject(err)
140140
} else {
@@ -143,7 +143,7 @@ const persisters = {
143143
reject(err)
144144
} else {
145145
// -r means try to deploy the actions, too
146-
return repl.qexec(`app update "${app.name}" "${filepath}" -r`)
146+
return repl.qexec(`app update "${app.name}" "${filepath}" -r --kind ${app.exec.kind}`)
147147
.then(app => {
148148
cleanup()
149149
resolve(app)
@@ -285,13 +285,29 @@ const tidy = ({wsk, getAction, editor, eventBus}) => ({
285285
*/
286286
const language = kind => {
287287
const base = kind.substring(0, kind.indexOf(':')) || kind
288+
debug('language', kind, base)
288289

289290
return base === 'nodejs'
290291
|| base === 'app'
291292
|| base === 'composition'
292293
|| base === 'sequence' ? 'javascript' : base
293294
}
294295

296+
/**
297+
* What is the filename extension for the given kind?
298+
*
299+
*/
300+
const extension = kind => {
301+
const lang = language(kind)
302+
debug('extension', kind, lang)
303+
304+
switch(lang) {
305+
case 'javascript': return '.js'
306+
case 'python': return '.py'
307+
default: return `.${lang}` // e.g. .swift, .php, .go
308+
}
309+
}
310+
295311
/**
296312
* Update the code in the editor to use the given text
297313
*
@@ -555,6 +571,7 @@ const respondToRepl = (wsk, extraModes=[]) => ({ getAction, editor, content, eve
555571
content,
556572
controlHeaders: ['.header-right-bits'],
557573
displayOptions: [`entity-is-${getAction().type}`, 'edit-mode'],
574+
badges: [ language(getAction().exec.kind) ],
558575
modes: extraModes
559576
.map(_ => _({wsk, getAction, editor, eventBus}))
560577
.concat([ save({wsk, getAction, editor, eventBus}),
@@ -610,10 +627,6 @@ const edit = (wsk, prequire) => (_0, _1, fullArgv, { ui, errors }, _2, _3, args,
610627
name = args[args.indexOf('edit') + 1]
611628
|| (sidecar.entity && `/${sidecar.entity.namespace}/${sidecar.entity.name}`)
612629

613-
if (!name || options.help) {
614-
throw new errors.usage(usage.edit)
615-
}
616-
617630
//
618631
// fetch the action and open the editor in parallel
619632
// then update the editor to show the action
@@ -644,19 +657,19 @@ const addVariantSuffix = kind => {
644657
* Command handler to create a new action or app
645658
*
646659
*/
647-
const newAction = ({wsk, prequire, op='new', type='actions', _kind=defaults.kind, placeholder, persister=persisters.actions}) => (_0, _1, fullArgv, { ui, errors }, _2, _3, args, options) => {
648-
debug('newAction', op)
649-
660+
const newAction = ({wsk, prequire, op='new', type='actions', _kind=defaults.kind, placeholder, placeholderFn, persister=persisters.actions}) => (_0, _1, fullArgv, { ui, errors }, _2, _3, args, options) => {
650661
const name = args[args.indexOf(op) + 1],
651-
kind = addVariantSuffix(options.kind || _kind)
662+
prettyKind = addVariantSuffix(options.kind || _kind),
663+
kind = addVariantSuffix(options.kind || defaults.kind)
652664

653-
if (options.help || !name) {
654-
throw new errors.usage(usage[op])
655-
}
665+
debug('newAction', op, name, kind, prettyKind)
666+
667+
// create the initial, placeholder, source code to place in the editor
668+
const makePlaceholderCode = placeholderFn || (() => placeholder || placeholders[language(kind)])
656669

657670
// our placeholder action
658671
const action = { name, type,
659-
exec: { kind, code: placeholder || placeholders[language(kind)] },
672+
exec: { kind, prettyKind, code: makePlaceholderCode({kind}) },
660673
isNew: true,
661674
persister
662675
}
@@ -741,7 +754,7 @@ const addWskflow = prequire => opts => {
741754
const compositionOptions = baseOptions => {
742755
return Object.assign({type: 'apps',
743756
_kind: 'app',
744-
placeholder: placeholders.composition, // the placeholder impl
757+
placeholderFn: ({kind='nodejs:default'}) => placeholders.composition[language(kind)], // the placeholder impl
745758
persister: persisters.apps, // the persister impl
746759
}, baseOptions)
747760
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2018 IBM Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
const { provider } = require('./composer-javascript')
18+
19+
module.exports = {
20+
language: 'python',
21+
provider
22+
}

app/plugins/modules/editor/lib/placeholders.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,10 @@ function main(array $args) : array
3434
return ["greeting" => $greeting];
3535
}`
3636

37-
exports.composition = `// try typing "composer." to begin your composition
37+
exports.composition = {
38+
javascript: `// try typing "composer." to begin your composition
39+
`,
40+
41+
python: `# try typing "composer." to begin your composition
3842
`
43+
}

app/plugins/modules/editor/usage.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818
const all = ['compose', 'new', 'edit']
1919
const allExcept = cmd => all.filter(_ => _ !== cmd)
2020

21+
/** optional arguments for new and compose commands */
22+
const optional = allowed => [
23+
{ name: '--kind', alias: '-k', docs: 'The OpenWhisk kind of the new action',
24+
allowed,
25+
allowedIsPrefixMatch: true,
26+
defaultValue: 'nodejs'
27+
}
28+
]
29+
2130
/**
2231
* Usage model for the editor plugin
2332
*
@@ -52,6 +61,7 @@ module.exports = {
5261
header: 'For quick prototyping of compositions, this command opens an editor in the sidecar.',
5362
example: 'compose <appName>',
5463
required: [{ name: '<appName>', docs: 'The name of your new composition' }],
64+
optional: optional(['nodejs', 'python']),
5565
parents: [{command: 'editor'}],
5666
related: allExcept('compose')
5767
},
@@ -63,11 +73,7 @@ module.exports = {
6373
header: 'For quick prototyping of actions, this command opens an editor in the sidecar.',
6474
example: 'new <actionName>',
6575
required: [{ name: '<actionName>', docs: 'The name of your new action' }],
66-
optional: [{ name: '--kind', alias: '-k', docs: 'The OpenWhisk kind of the new action',
67-
allowed: ['nodejs', 'python', 'php', 'swift'],
68-
allowedIsPrefixMatch: true,
69-
defaultValue: 'nodejs'
70-
}],
76+
optional: optional(['nodejs', 'python', 'php', 'swift']),
7177
parents: [{command: 'editor'}],
7278
related: allExcept('new')
7379
}

app/plugins/openwhisk-extensions/actions/invoke.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
*
2727
*/
2828

29+
const debug = require('debug')('openwhisk invoke extension')
30+
2931
const path = require('path'),
3032
{ actions } = require(path.join(__dirname, '../../ui/commands/openwhisk-usage'))
3133

@@ -61,6 +63,8 @@ const fetchFromError = error => {
6163
*
6264
*/
6365
const respond = options => response => {
66+
debug('responding to caller', response)
67+
6468
if (options.quiet) {
6569
return true
6670
} else {

0 commit comments

Comments
 (0)