-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add git service in remixd & use it from the terminal #638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c767721
4ead915
80a9e76
658d4c3
7d02418
80c270c
c44eb3a
d3e59ec
850d85f
baf86d9
dcef83a
23139d4
40484a3
5c49808
6750955
eb64ab6
5c58b48
a789fa7
7d1fe50
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { WebsocketPlugin } from '@remixproject/engine-web' | ||
| import * as packageJson from '../../../../../package.json' | ||
|
|
||
| const profile = { | ||
| name: 'git', | ||
| displayName: 'Git', | ||
| url: 'ws://127.0.0.1:65521', | ||
| methods: ['execute'], | ||
| description: 'Using Remixd daemon, allow to access git API', | ||
| kind: 'other', | ||
| version: packageJson.version | ||
| } | ||
|
|
||
| export class GitHandle extends WebsocketPlugin { | ||
| constructor () { | ||
| super(profile) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ var yo = require('yo-yo') | |
| var EventManager = require('../../lib/events') | ||
| var FileExplorer = require('../files/file-explorer') | ||
| var { RemixdHandle } = require('../files/remixd-handle.js') | ||
| var { GitHandle } = require('../files/git-handle.js') | ||
| var globalRegistry = require('../../global/registry') | ||
| var css = require('./styles/file-panel-styles') | ||
|
|
||
|
|
@@ -60,6 +61,7 @@ module.exports = class Filepanel extends ViewPlugin { | |
| var fileSystemExplorer = createProvider('localhost') | ||
|
|
||
| self.remixdHandle = new RemixdHandle(fileSystemExplorer, self._deps.fileProviders.localhost, appManager) | ||
| self.gitHandle = new GitHandle() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would recommend to put GitHandle at the root of the project and not in the FilePanel property |
||
|
|
||
| const explorers = yo` | ||
| <div> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export { RemixdClient as Sharedfolder } from './services/remixdClient' | ||
| export { GitClient } from './services/gitClient' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import * as WS from 'ws' // eslint-disable-line | ||
| import { PluginClient } from '@remixproject/plugin' | ||
| const { spawn } = require('child_process') | ||
|
|
||
| export class GitClient extends PluginClient { | ||
| methods: ['execute'] | ||
| websocket: WS | ||
| currentSharedFolder: string | ||
| readOnly: boolean | ||
|
|
||
| setWebSocket (websocket: WS): void { | ||
| this.websocket = websocket | ||
| } | ||
|
|
||
| sharedFolder (currentSharedFolder: string, readOnly: boolean): void { | ||
| this.currentSharedFolder = currentSharedFolder | ||
| this.readOnly = readOnly | ||
| } | ||
|
|
||
| execute (cmd: string) { | ||
| assertCommand(cmd) | ||
| const options = { cwd: this.currentSharedFolder, shell: true } | ||
| const child = spawn(cmd, options) | ||
| let result = '' | ||
| let error = '' | ||
| return new Promise((resolve, reject) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would recommend to put the Promise closer to its used : assertCommand(cmd, gitRegex)
const options = { cwd: this.currentSharedFolder, shell: true }
const child = spawn(cmd, options)
let result = ''
let error = ''
return new Promise((resolve, reject) => {
child.stdout.on('data', (data) => result += data.toString())
child.stderr.on('data', (err) => error += data.toString())
child.on('close', (exitCode) => exitCode !== 0 ? reject(error) : resolve(result))
})You don't need to try / catch here everything that throw will be handled by the caller |
||
| child.stdout.on('data', (data) => { | ||
| result += data.toString() | ||
| }) | ||
| child.stderr.on('data', (err) => { | ||
| error += err.toString() | ||
| }) | ||
| child.on('close', () => { | ||
| if (error) reject(error) | ||
| else resolve(result) | ||
| }) | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Validate that command can be run by service | ||
| * @param cmd | ||
| */ | ||
| function assertCommand (cmd) { | ||
| const regex = '^git\\s[^&|;]*$' | ||
| if (!RegExp(regex).test(cmd)) { // git then space and then everything else | ||
| throw new Error('Invalid command for service!') | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,41 +1,41 @@ | ||
| import * as WS from 'ws' | ||
| import * as http from 'http' | ||
| import { WebsocketOpt, SharedFolderClient } from './types' // eslint-disable-line | ||
| import { WebsocketOpt, ServiceClient } from './types' // eslint-disable-line | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any reason why you need to disable line ? I'm not sure you need to do that anymore. |
||
| import { getDomain } from './utils' | ||
| import { createClient } from '@remixproject/plugin-ws' | ||
| export default class WebSocket { | ||
| server: http.Server | ||
| wsServer: WS.Server | ||
|
|
||
| constructor (public port: number, public opt: WebsocketOpt, public sharedFolder: SharedFolderClient) {} //eslint-disable-line | ||
| constructor (public port: number, public opt: WebsocketOpt, public getclient: () => ServiceClient) {} //eslint-disable-line | ||
|
|
||
| start (callback?: (ws: WS) => void): void { | ||
| start (callback?: (ws: WS, client: ServiceClient) => void): void { | ||
| this.server = http.createServer((request, response) => { | ||
| console.log((new Date()) + ' Received request for ' + request.url) | ||
| response.writeHead(404) | ||
| response.end() | ||
| }) | ||
| const loopback = '127.0.0.1' | ||
|
|
||
| this.server.listen(this.port, loopback, function () { | ||
| console.log((new Date()) + ' remixd is listening on ' + loopback + ':65520') | ||
| this.server.listen(this.port, loopback, () => { | ||
| console.log(`${new Date()} remixd is listening on ${loopback}:${this.port}`) | ||
| }) | ||
| this.wsServer = new WS.Server({ | ||
| server: this.server, | ||
| verifyClient: (info, done) => { | ||
| if (!originIsAllowed(info.origin, this)) { | ||
| done(false) | ||
| console.log((new Date()) + ' Connection from origin ' + info.origin + ' rejected.') | ||
| console.log(`${new Date()} connection from origin ${info.origin}`) | ||
| return | ||
| } | ||
| done(true) | ||
| } | ||
| }) | ||
| this.wsServer.on('connection', (ws) => { | ||
| const { sharedFolder } = this | ||
| const client = this.getclient() | ||
|
|
||
| createClient(ws, sharedFolder as any) | ||
| if (callback) callback(ws) | ||
| createClient(ws, client as any) | ||
| if (callback) callback(ws, client) | ||
| }) | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a Plugin I would recommend putting Git at the root of the project and access its methods only through remix-plugin API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will plan this changes later on. This will anyway go in during the react refactoring.