rdesktop
filip mertens 1 year ago
parent 429e845785
commit 5728f3c7db
  1. 2
      apps/1test/src/electron/fsPlugin.ts
  2. 135
      apps/1test/src/index.ts
  3. 2
      apps/1test/src/remix/fsPlugin.ts
  4. 2
      apps/1test/src/remix/gitPlugin.ts
  5. 5
      apps/remix-ide/src/app.js
  6. 275
      apps/remix-ide/src/app/files/dgitProvider.js
  7. 4
      apps/remix-ide/src/app/files/fileManager.ts
  8. 31
      apps/remix-ide/src/app/plugins/fsPlugin.ts
  9. 19
      apps/remix-ide/src/app/plugins/isoGitPlugin.ts
  10. 35
      apps/remix-ide/src/app/tabs/theme-module.js
  11. 10
      apps/remixdesktop/src/engine.ts
  12. 62
      apps/remixdesktop/src/plugins/fsPlugin.ts
  13. 15
      apps/remixdesktop/src/plugins/gitPlugin.ts
  14. 241
      apps/remixdesktop/src/plugins/isoGitPlugin.ts
  15. 0
      apps/remixdesktop/src/plugins/xtermPlugin.ts
  16. 2
      apps/remixdesktop/src/preload.ts
  17. 1
      libs/remix-ui/workspace/src/lib/actions/index.ts

@ -35,7 +35,7 @@ const clientProfile: Profile = {
class FSPluginClient extends ElectronBasePluginClient { class FSPluginClient extends ElectronBasePluginClient {
watcher: chokidar.FSWatcher watcher: chokidar.FSWatcher
workingDir: string = '/Volumes/bunsen/code/rmproject2/remix-project/apps/remix-ide/contracts/' workingDir: string = '/Volumes/bunsen/code/empty/'
constructor(webContentsId: number, profile: Profile) { constructor(webContentsId: number, profile: Profile) {
super(webContentsId, profile) super(webContentsId, profile)

@ -94,7 +94,7 @@ const menu = [shellMenu(commandKeys, execCommand)]
Menu.setApplicationMenu(Menu.buildFromTemplate(menu)) Menu.setApplicationMenu(Menu.buildFromTemplate(menu))
import fs from 'fs/promises' import fs from 'fs/promises'
import { readlink } from 'fs'; import { readlink, stat } from 'fs';
//const menu = Menu.buildFromTemplate(shellMenu([], undefined)) //const menu = Menu.buildFromTemplate(shellMenu([], undefined))
//Menu.setApplicationMenu(menu) //Menu.setApplicationMenu(menu)
@ -110,11 +110,11 @@ const myFS = {
return file return file
}, },
readFile: async (path: string, options: any): Promise<string>=> { readFile: async (path: string, options: any): Promise<string> => {
//console.log('myFS.readFile', path, options) //console.log('myFS.readFile', path, options)
const file = await (fs as any).readFile(path, options) const file = await (fs as any).readFile(path, options)
//console.log('myFS.readFile', file) //console.log('myFS.readFile', file)
return file return file
}, },
@ -164,14 +164,18 @@ const myFS = {
} }
console.log('myFS', myFS) console.log('myFS', myFS)
import git, { CommitObject, ReadCommitResult } from 'isomorphic-git'
async function checkGit() { async function checkGit() {
const git = require('isomorphic-git');
const files = await git.statusMatrix({ fs: myFS, dir: '/Volumes/bunsen/code/rmproject2/remix-project' });
const files = await git.statusMatrix({ fs: myFS, dir: '/Volumes/bunsen/code/rmproject2/remix-project', filepaths: ['apps/1test/src/index.ts'] });
console.log('GIT', files) console.log('GIT', files)
} }
//checkGit()
/*
setInterval(() => { setInterval(() => {
const startTime = Date.now() const startTime = Date.now()
@ -181,3 +185,118 @@ checkGit()
}) })
}, 3000) }, 3000)
*/
/*
git.add({ fs: myFS, dir: '/Volumes/bunsen/code/rmproject2/remix-project', filepath: 'test.txt' }).then(() => {
console.log('git add')
}).catch((e: any) => {
console.log('git add error', e)
})
git.log({ fs: myFS, dir: '/Volumes/bunsen/code/rmproject2/remix-project', depth:10 }).then((log: any) => {
console.log('git log', log)
})
*/
// run a shell command
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
const statusTransFormMatrix = (status: string) => {
switch (status) {
case '??':
return [0, 2, 0]
case 'A ':
return [0, 2, 2]
case 'M ':
return [1, 2, 2]
case 'MM':
return [1, 2, 3]
case ' M':
return [1, 0, 1]
case ' D':
return [0, 2, 0]
case 'D ':
return [1, 0, 0]
case 'AM':
return [0, 2, 3]
default:
return [-1, -1, -1]
}
}
execAsync('git status --porcelain -uall', { cwd: '/Volumes/bunsen/code/rmproject2/remix-project' }).then(async (result: any) => {
//console.log('git status --porcelain -uall', result.stdout)
// parse the result.stdout
const lines = result.stdout.split('\n')
const files: any = []
const fileNames: any = []
//console.log('lines', lines)
lines.forEach((line: string) => {
// get the first two characters of the line
const status = line.slice(0, 2)
const file = line.split(' ').pop()
//console.log('line', line)
if (status && file) {
fileNames.push(file)
files.push([
file,
...statusTransFormMatrix(status)
])
}
}
)
// sort files by first column
files.sort((a: any, b: any) => {
if (a[0] < b[0]) {
return -1
}
if (a[0] > b[0]) {
return 1
}
return 0
})
//console.log('files', files, files.length)
const iso = await git.statusMatrix({ fs: myFS, dir: '/Volumes/bunsen/code/rmproject2/remix-project', filepaths: fileNames });
//console.log('GIT', iso, iso.length)
})
git.log({ fs: myFS, dir: '/Volumes/bunsen/code/rmproject2/remix-project', depth:3 }).then((log: ReadCommitResult[]) => {
log.forEach((commit: ReadCommitResult) => {
console.log('commit', commit.commit.parent)
})
})
// exec git log --pretty=format:"%h - %an, %ar : %s" -n 10
execAsync(`git log --pretty=format:'{ "oid":"%H", "message":"%s", "author":"%an", "email": "%ae", "timestamp":"%at", "tree": "%T", "committer": "%cn", "committer-email": "%ce", "committer-timestamp": "%ct", "parent": "%P" }' -n 3`, { cwd: '/Volumes/bunsen/code/rmproject2/remix-project' }).then(async (result: any) =>{
//console.log('git log', result.stdout)
const lines = result.stdout.split('\n')
const commits: ReadCommitResult[] = []
lines.forEach((line: string) => {
console.log('line', line)
const data = JSON.parse(line)
let commit:ReadCommitResult = {} as ReadCommitResult
commit.oid = data.oid
commit.commit = {} as CommitObject
commit.commit.message = data.message
commit.commit.tree = data.tree
commit.commit.committer = {} as any
commit.commit.committer.name = data.committer
commit.commit.committer.email = data['committer-email']
commit.commit.committer.timestamp = data['committer-timestamp']
commit.commit.author = {} as any
commit.commit.author.name = data.author
commit.commit.author.email = data.email
commit.commit.author.timestamp = data.timestamp
commit.commit.parent = [data.parent]
console.log('commit', commit)
commits.push(commit)
})
})

@ -1,6 +1,6 @@
import { ElectronPlugin } from './lib/electronPlugin'; import { ElectronPlugin } from './lib/electronPlugin';
let workingDir = '/Volumes/bunsen/code/rmproject2/remix-project/apps/remix-ide/contracts/' let workingDir = '/Volumes/bunsen/code/empty/'
const fixPath = (path: string) => { const fixPath = (path: string) => {
/* /*

@ -9,4 +9,6 @@ export class gitPlugin extends ElectronPlugin {
}) })
this.methods = ['log', 'status', 'add', 'commit', 'push', 'pull', 'clone', 'checkout', 'branch', 'merge', 'reset', 'revert', 'diff', 'stash', 'apply', 'cherryPick', 'rebase', 'tag', 'fetch', 'remote', 'config', 'show', 'init', 'help', 'version'] this.methods = ['log', 'status', 'add', 'commit', 'push', 'pull', 'clone', 'checkout', 'branch', 'merge', 'reset', 'revert', 'diff', 'stash', 'apply', 'cherryPick', 'rebase', 'tag', 'fetch', 'remote', 'config', 'show', 'init', 'help', 'version']
} }
} }

@ -46,6 +46,7 @@ import { CodeFormat } from './app/plugins/code-format'
import { SolidityUmlGen } from './app/plugins/solidity-umlgen' import { SolidityUmlGen } from './app/plugins/solidity-umlgen'
import { ContractFlattener } from './app/plugins/contractFlattener' import { ContractFlattener } from './app/plugins/contractFlattener'
import { fsPlugin } from './app/plugins/fsPlugin' import { fsPlugin } from './app/plugins/fsPlugin'
import { isoGitPlugin } from './app/plugins/isoGitPlugin'
const isElectron = require('is-electron') const isElectron = require('is-electron')
@ -318,6 +319,8 @@ class AppComponent {
if (isElectron()) { if (isElectron()) {
const FSPlugin = new fsPlugin() const FSPlugin = new fsPlugin()
this.engine.register([FSPlugin]) this.engine.register([FSPlugin])
const isoGit = new isoGitPlugin()
this.engine.register([isoGit])
} }
// LAYOUT & SYSTEM VIEWS // LAYOUT & SYSTEM VIEWS
@ -436,7 +439,7 @@ class AppComponent {
await this.appManager.activatePlugin(['solidity-script']) await this.appManager.activatePlugin(['solidity-script'])
if(isElectron()){ if(isElectron()){
await this.appManager.activatePlugin(['fs']) await this.appManager.activatePlugin(['fs', 'isogit'])
} }
this.appManager.on( this.appManager.on(

@ -25,7 +25,7 @@ const profile = {
kind: 'file-system' kind: 'file-system'
} }
class DGitProvider extends Plugin { class DGitProvider extends Plugin {
constructor () { constructor() {
super(profile) super(profile)
this.ipfsconfig = { this.ipfsconfig = {
host: 'jqgt.remixproject.org', host: 'jqgt.remixproject.org',
@ -48,13 +48,12 @@ class DGitProvider extends Plugin {
this.ipfsSources = [this.remixIPFS, this.globalIPFSConfig, this.ipfsconfig] this.ipfsSources = [this.remixIPFS, this.globalIPFSConfig, this.ipfsconfig]
} }
async onActivation () { async onActivation() {
} }
async getGitConfig () { async getGitConfig() {
if(isElectron()){ if (isElectron()) {
return { return {
fs: window.remixFileSystem, fs: window.remixFileSystem,
dir: '/' dir: '/'
@ -70,7 +69,7 @@ class DGitProvider extends Plugin {
} }
} }
async parseInput (input) { async parseInput(input) {
return { return {
corsProxy: 'https://corsproxy.remixproject.org/', corsProxy: 'https://corsproxy.remixproject.org/',
http, http,
@ -85,7 +84,15 @@ class DGitProvider extends Plugin {
} }
} }
async init (input) { async init(input) {
if(isElectron()) {
await this.call('isogit', 'init', {
defaultBranch: (input && input.branch) || 'main'
})
this.emit('init')
return
}
await git.init({ await git.init({
...await this.getGitConfig(), ...await this.getGitConfig(),
defaultBranch: (input && input.branch) || 'main' defaultBranch: (input && input.branch) || 'main'
@ -93,7 +100,14 @@ class DGitProvider extends Plugin {
this.emit('init') this.emit('init')
} }
async status (cmd) { async status(cmd) {
if (isElectron()) {
const status = await this.call('isogit', 'status', cmd)
console.log('STATUS', status)
return status
}
console.log('status') console.log('status')
const status = await git.statusMatrix({ const status = await git.statusMatrix({
...await this.getGitConfig(), ...await this.getGitConfig(),
@ -103,43 +117,76 @@ class DGitProvider extends Plugin {
return status return status
} }
async add (cmd) { async add(cmd) {
await git.add({
...await this.getGitConfig(), if (isElectron()) {
...cmd await this.call('isogit', 'add', cmd)
}) } else {
await git.add({
...await this.getGitConfig(),
...cmd
})
}
this.emit('add') this.emit('add')
} }
async rm (cmd) { async rm(cmd) {
await git.remove({
...await this.getGitConfig(), if (isElectron()) {
...cmd await this.call('isogit', 'rm', cmd)
}) } else {
await git.remove({
...await this.getGitConfig(),
...cmd
})
this.emit('rm')
}
} }
async checkout(cmd, refresh = true) {
async checkout (cmd, refresh = true) { if (isElectron()) {
await git.checkout({ await this.call('isogit', 'checkout', cmd)
...await this.getGitConfig(), } else {
...cmd await git.checkout({
}) ...await this.getGitConfig(),
...cmd
})
}
if (refresh) { if (refresh) {
setTimeout(async () => { setTimeout(async () => {
await this.call('fileManager', 'refresh') await this.call('fileManager', 'refresh')
}, 1000) }, 1000)
} }
this.emit('checkout') this.emit('checkout')
} }
async log (cmd) { async log(cmd) {
if (isElectron()) {
const status = await this.call('isogit', 'log', {
...cmd,
depth: 10
})
console.log('STATUS', status)
return status
}
const status = await git.log({ const status = await git.log({
...await this.getGitConfig(), ...await this.getGitConfig(),
...cmd ...cmd,
depth: 10
}) })
return status return status
} }
async remotes (config) { async remotes(config) {
if (isElectron()) {
return await this.call('isogit', 'remotes', config)
}
let remotes = [] let remotes = []
try { try {
remotes = await git.listRemotes({ ...config ? config : await this.getGitConfig() }) remotes = await git.listRemotes({ ...config ? config : await this.getGitConfig() })
@ -149,13 +196,19 @@ class DGitProvider extends Plugin {
return remotes return remotes
} }
async branch (cmd, refresh = true) { async branch(cmd, refresh = true) {
const status = await git.branch({
...await this.getGitConfig(), let status
...cmd if (isElectron()) {
}) status = await this.call('isogit', 'branch', cmd)
} else {
status = await git.branch({
...await this.getGitConfig(),
...cmd
})
}
if (refresh) { if (refresh) {
setTimeout(async () => { setTimeout(async () => {
await this.call('fileManager', 'refresh') await this.call('fileManager', 'refresh')
}, 1000) }, 1000)
} }
@ -163,20 +216,34 @@ class DGitProvider extends Plugin {
return status return status
} }
async currentbranch (config) { async currentbranch(config) {
try{
console.log('currentbranch')
if (isElectron()) {
console.log('currentbranch electron')
return await this.call('isogit', 'currentbranch')
}
try {
const defaultConfig = await this.getGitConfig() const defaultConfig = await this.getGitConfig()
const cmd = config ? defaultConfig ? { ...defaultConfig, ...config } : config : defaultConfig const cmd = config ? defaultConfig ? { ...defaultConfig, ...config } : config : defaultConfig
const name = await git.currentBranch(cmd) const name = await git.currentBranch(cmd)
return name return name
}catch(e){ } catch (e) {
return '' return ''
} }
} }
async branches (config) { async branches(config) {
try{
if (isElectron()) {
return await this.call('isogit', 'branches', config)
}
try {
const defaultConfig = await this.getGitConfig() const defaultConfig = await this.getGitConfig()
const cmd = config ? defaultConfig ? { ...defaultConfig, ...config } : config : defaultConfig const cmd = config ? defaultConfig ? { ...defaultConfig, ...config } : config : defaultConfig
const remotes = await this.remotes(config) const remotes = await this.remotes(config)
@ -188,26 +255,44 @@ class DGitProvider extends Plugin {
branches = [...branches, ...remotebranches] branches = [...branches, ...remotebranches]
} }
return branches return branches
}catch(e){ } catch (e) {
return [] return []
} }
} }
async commit (cmd) { async commit(cmd) {
await this.init()
try { if (isElectron()) {
const sha = await git.commit({ try {
...await this.getGitConfig(), await this.call('isogit', 'init')
...cmd const sha = await this.call('isogit', 'commit', cmd)
}) this.emit('commit')
this.emit('commit') return sha
return sha } catch (e) {
} catch (e) { throw new Error(e)
throw new Error(e) }
} else {
await this.init()
try {
const sha = await git.commit({
...await this.getGitConfig(),
...cmd
})
this.emit('commit')
return sha
} catch (e) {
throw new Error(e)
}
} }
} }
async lsfiles (cmd) { async lsfiles(cmd) {
if (isElectron()) {
return await this.call('isogit', 'lsfiles', cmd)
}
const filesInStaging = await git.listFiles({ const filesInStaging = await git.listFiles({
...await this.getGitConfig(), ...await this.getGitConfig(),
...cmd ...cmd
@ -215,7 +300,12 @@ class DGitProvider extends Plugin {
return filesInStaging return filesInStaging
} }
async resolveref (cmd) { async resolveref(cmd) {
if (isElectron()) {
return await this.call('isogit', 'resolveref', cmd)
}
const oid = await git.resolveRef({ const oid = await git.resolveRef({
...await this.getGitConfig(), ...await this.getGitConfig(),
...cmd ...cmd
@ -223,7 +313,7 @@ class DGitProvider extends Plugin {
return oid return oid
} }
async readblob (cmd) { async readblob(cmd) {
const readBlobResult = await git.readBlob({ const readBlobResult = await git.readBlob({
...await this.getGitConfig(), ...await this.getGitConfig(),
...cmd ...cmd
@ -231,14 +321,14 @@ class DGitProvider extends Plugin {
return readBlobResult return readBlobResult
} }
async setIpfsConfig (config) { async setIpfsConfig(config) {
this.ipfsconfig = config this.ipfsconfig = config
return new Promise((resolve) => { return new Promise((resolve) => {
resolve(this.checkIpfsConfig()) resolve(this.checkIpfsConfig())
}) })
} }
async checkIpfsConfig (config) { async checkIpfsConfig(config) {
this.ipfs = IpfsHttpClient(config || this.ipfsconfig) this.ipfs = IpfsHttpClient(config || this.ipfsconfig)
try { try {
await this.ipfs.config.getAll() await this.ipfs.config.getAll()
@ -248,19 +338,19 @@ class DGitProvider extends Plugin {
} }
} }
async addremote (input) { async addremote(input) {
await git.addRemote({ ...await this.getGitConfig(), url: input.url, remote: input.remote }) await git.addRemote({ ...await this.getGitConfig(), url: input.url, remote: input.remote })
} }
async delremote (input) { async delremote(input) {
await git.deleteRemote({ ...await this.getGitConfig(), remote: input.remote }) await git.deleteRemote({ ...await this.getGitConfig(), remote: input.remote })
} }
async localStorageUsed () { async localStorageUsed() {
return this.calculateLocalStorage() return this.calculateLocalStorage()
} }
async clone (input, workspaceName, workspaceExists = false) { async clone(input, workspaceName, workspaceExists = false) {
const permission = await this.askUserPermission('clone', 'Import multiple files into your workspaces.') const permission = await this.askUserPermission('clone', 'Import multiple files into your workspaces.')
if (!permission) return false if (!permission) return false
if (this.calculateLocalStorage() > 10000) throw new Error('The local storage of the browser is full.') if (this.calculateLocalStorage() > 10000) throw new Error('The local storage of the browser is full.')
@ -284,7 +374,7 @@ class DGitProvider extends Plugin {
return result return result
} }
async push (input) { async push(input) {
const cmd = { const cmd = {
force: input.force, force: input.force,
ref: input.ref, ref: input.ref,
@ -295,12 +385,19 @@ class DGitProvider extends Plugin {
email: input.email email: input.email
}, },
...await this.parseInput(input), ...await this.parseInput(input),
...await this.getGitConfig()
} }
return await git.push(cmd) if (isElectron()) {
return await this.call('isogit', 'push', cmd)
}
return await git.push({
...await this.getGitConfig(),
...cmd
})
} }
async pull (input) { async pull(input) {
const cmd = { const cmd = {
ref: input.ref, ref: input.ref,
remoteRef: input.remoteRef, remoteRef: input.remoteRef,
@ -310,16 +407,25 @@ class DGitProvider extends Plugin {
}, },
remote: input.remote, remote: input.remote,
...await this.parseInput(input), ...await this.parseInput(input),
...await this.getGitConfig()
}
let result
if (isElectron()) {
result = await this.call('isogit', 'pull', cmd)
}
else {
result = await git.pull({
...await this.getGitConfig(),
...cmd
})
} }
const result = await git.pull(cmd)
setTimeout(async () => { setTimeout(async () => {
await this.call('fileManager', 'refresh') await this.call('fileManager', 'refresh')
}, 1000) }, 1000)
return result return result
} }
async fetch (input) { async fetch(input) {
const cmd = { const cmd = {
ref: input.ref, ref: input.ref,
remoteRef: input.remoteRef, remoteRef: input.remoteRef,
@ -329,16 +435,23 @@ class DGitProvider extends Plugin {
}, },
remote: input.remote, remote: input.remote,
...await this.parseInput(input), ...await this.parseInput(input),
...await this.getGitConfig()
} }
const result = await git.fetch(cmd) let result
if (isElectron()) {
result = await this.call('isogit', 'fetch', cmd)
} else {
result = await git.fetch({
...await this.getGitConfig(),
...cmd
})
}
setTimeout(async () => { setTimeout(async () => {
await this.call('fileManager', 'refresh') await this.call('fileManager', 'refresh')
}, 1000) }, 1000)
return result return result
} }
async export (config) { async export(config) {
if (!this.checkIpfsConfig(config)) return false if (!this.checkIpfsConfig(config)) return false
const workspace = await this.call('filePanel', 'getCurrentWorkspace') const workspace = await this.call('filePanel', 'getCurrentWorkspace')
const files = await this.getDirectory('/') const files = await this.getDirectory('/')
@ -358,7 +471,7 @@ class DGitProvider extends Plugin {
return r.cid.string return r.cid.string
} }
async pin (pinataApiKey, pinataSecretApiKey) { async pin(pinataApiKey, pinataSecretApiKey) {
const workspace = await this.call('filePanel', 'getCurrentWorkspace') const workspace = await this.call('filePanel', 'getCurrentWorkspace')
const files = await this.getDirectory('/') const files = await this.getDirectory('/')
this.filesToSend = [] this.filesToSend = []
@ -425,7 +538,7 @@ class DGitProvider extends Plugin {
} }
} }
async pinList (pinataApiKey, pinataSecretApiKey) { async pinList(pinataApiKey, pinataSecretApiKey) {
const url = 'https://api.pinata.cloud/data/pinList?status=pinned' const url = 'https://api.pinata.cloud/data/pinList?status=pinned'
try { try {
const result = await axios const result = await axios
@ -444,7 +557,7 @@ class DGitProvider extends Plugin {
} }
} }
async unPin (pinataApiKey, pinataSecretApiKey, hashToUnpin) { async unPin(pinataApiKey, pinataSecretApiKey, hashToUnpin) {
const url = `https://api.pinata.cloud/pinning/unpin/${hashToUnpin}` const url = `https://api.pinata.cloud/pinning/unpin/${hashToUnpin}`
try { try {
await axios await axios
@ -460,7 +573,7 @@ class DGitProvider extends Plugin {
} }
} }
async importIPFSFiles (config, cid, workspace) { async importIPFSFiles(config, cid, workspace) {
const ipfs = IpfsHttpClient(config) const ipfs = IpfsHttpClient(config)
let result = false let result = false
try { try {
@ -489,7 +602,7 @@ class DGitProvider extends Plugin {
return result return result
} }
calculateLocalStorage () { calculateLocalStorage() {
var _lsTotal = 0 var _lsTotal = 0
var _xLen; var _x var _xLen; var _x
for (_x in localStorage) { for (_x in localStorage) {
@ -503,7 +616,7 @@ class DGitProvider extends Plugin {
return (_lsTotal / 1024).toFixed(2) return (_lsTotal / 1024).toFixed(2)
} }
async import (cmd) { async import(cmd) {
const permission = await this.askUserPermission('import', 'Import multiple files into your workspaces.') const permission = await this.askUserPermission('import', 'Import multiple files into your workspaces.')
if (!permission) return false if (!permission) return false
if (this.calculateLocalStorage() > 10000) throw new Error('The local storage of the browser is full.') if (this.calculateLocalStorage() > 10000) throw new Error('The local storage of the browser is full.')
@ -522,13 +635,13 @@ class DGitProvider extends Plugin {
if (!result) throw new Error(`Cannot pull files from IPFS at ${cid}`) if (!result) throw new Error(`Cannot pull files from IPFS at ${cid}`)
} }
async getItem (name) { async getItem(name) {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
return window.localStorage.getItem(name) return window.localStorage.getItem(name)
} }
} }
async setItem (name, content) { async setItem(name, content) {
try { try {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
window.localStorage.setItem(name, content) window.localStorage.setItem(name, content)
@ -540,7 +653,7 @@ class DGitProvider extends Plugin {
return true return true
} }
async zip () { async zip() {
const zip = new JSZip() const zip = new JSZip()
const workspace = await this.call('filePanel', 'getCurrentWorkspace') const workspace = await this.call('filePanel', 'getCurrentWorkspace')
const files = await this.getDirectory('/') const files = await this.getDirectory('/')
@ -557,7 +670,7 @@ class DGitProvider extends Plugin {
}) })
} }
async createDirectories (strdirectories) { async createDirectories(strdirectories) {
const ignore = ['.', '/.', ''] const ignore = ['.', '/.', '']
if (ignore.indexOf(strdirectories) > -1) return false if (ignore.indexOf(strdirectories) > -1) return false
const directories = strdirectories.split('/') const directories = strdirectories.split('/')
@ -575,7 +688,7 @@ class DGitProvider extends Plugin {
} }
} }
async getDirectory (dir) { async getDirectory(dir) {
let result = [] let result = []
const files = await this.call('fileManager', 'readdir', dir) const files = await this.call('fileManager', 'readdir', dir)
const fileArray = normalize(files) const fileArray = normalize(files)
@ -599,7 +712,7 @@ class DGitProvider extends Plugin {
} }
const addSlash = (file) => { const addSlash = (file) => {
if (!file.startsWith('/'))file = '/' + file if (!file.startsWith('/')) file = '/' + file
return file return file
} }

@ -195,8 +195,8 @@ class FileManager extends Plugin {
path = this.normalize(path) path = this.normalize(path)
path = this.limitPluginScope(path) path = this.limitPluginScope(path)
path = this.getPathFromUrl(path).file path = this.getPathFromUrl(path).file
await this._handleExists(path, `Cannot open file ${path}`) //await this._handleExists(path, `Cannot open file ${path}`)
await this._handleIsFile(path, `Cannot open file ${path}`) //await this._handleIsFile(path, `Cannot open file ${path}`)
await this.openFile(path) await this.openFile(path)
} }

@ -1,6 +1,4 @@
import { ElectronPlugin } from '@remixproject/engine-electron'; import { ElectronPlugin } from '@remixproject/engine-electron';
import once from 'just-once';
let workingDir = null let workingDir = null
@ -8,15 +6,6 @@ const fixPath = (path: string) => {
return path return path
} }
function wrapCallback(opts, cb) {
if (typeof opts === "function") {
cb = opts;
}
cb = once(cb);
const resolve = (...args) => cb(null, ...args)
return [resolve, cb];
}
export class fsPlugin extends ElectronPlugin { export class fsPlugin extends ElectronPlugin {
public fs: any public fs: any
public fsSync: any public fsSync: any
@ -58,9 +47,9 @@ export class fsPlugin extends ElectronPlugin {
}, },
readdir: async (path: string) => { readdir: async (path: string) => {
path = fixPath(path) path = fixPath(path)
console.log('readdir', path) //console.log('readdir', path)
const files = await this.call('fs', 'readdir', path) const files = await this.call('fs', 'readdir', path)
console.log('readdir', path, files) //console.log('readdir', path, files)
return files return files
}, },
unlink: async (path: string) => { unlink: async (path: string) => {
@ -73,13 +62,13 @@ export class fsPlugin extends ElectronPlugin {
}, },
readFile: async (path: string, options) => { readFile: async (path: string, options) => {
try { try {
console.log('readFile', path, options) //console.log('readFile', path, options)
path = fixPath(path) path = fixPath(path)
const file = await this.call('fs', 'readFile', path, options) const file = await this.call('fs', 'readFile', path, options)
console.log('readFile', path, file) //console.log('readFile', path, file)
return file return file
} catch (e) { } catch (e) {
console.log('readFile error', e) //console.log('readFile error', e)
return undefined return undefined
} }
} }
@ -99,10 +88,10 @@ export class fsPlugin extends ElectronPlugin {
if(!stat) return undefined if(!stat) return undefined
stat.isDirectory = () => stat.isDirectoryValue stat.isDirectory = () => stat.isDirectoryValue
stat.isFile = () => !stat.isDirectoryValue stat.isFile = () => !stat.isDirectoryValue
//console.log('stat', path, stat) ////console.log('stat', path, stat)
return stat return stat
} catch (e) { } catch (e) {
console.log('stat error', e) //console.log('stat error', e)
return undefined return undefined
} }
}, },
@ -115,7 +104,7 @@ export class fsPlugin extends ElectronPlugin {
stat.isFile = () => !stat.isDirectoryValue stat.isFile = () => !stat.isDirectoryValue
return stat return stat
} catch (e) { } catch (e) {
console.log('lstat error', e) //console.log('lstat error', e)
return undefined return undefined
} }
}, },
@ -145,12 +134,12 @@ export class fsPlugin extends ElectronPlugin {
async onActivation() { async onActivation() {
console.log('fsPluginClient onload', this.fs); //console.log('fsPluginClient onload', this.fs);
(window as any).remixFileSystem = this.fs; (window as any).remixFileSystem = this.fs;
this.on('fs', 'workingDirChanged', async (path: string) => { this.on('fs', 'workingDirChanged', async (path: string) => {
console.log('change working dir', path) //console.log('change working dir', path)
workingDir = path workingDir = path
await this.call('fileManager', 'refresh') await this.call('fileManager', 'refresh')
}) })

@ -0,0 +1,19 @@
import { ElectronPlugin } from '@remixproject/engine-electron';
export class isoGitPlugin extends ElectronPlugin {
constructor() {
super({
displayName: 'isogit',
name: 'isogit',
description: 'isogit',
})
this.methods = []
}
onActivation(): void {
}
}

@ -30,7 +30,7 @@ const profile = {
} }
export class ThemeModule extends Plugin { export class ThemeModule extends Plugin {
constructor () { constructor() {
super(profile) super(profile)
this.events = new EventEmitter() this.events = new EventEmitter()
this._deps = { this._deps = {
@ -39,8 +39,8 @@ export class ThemeModule extends Plugin {
this.themes = {} this.themes = {}
themes.map((theme) => { themes.map((theme) => {
this.themes[theme.name.toLocaleLowerCase()] = { this.themes[theme.name.toLocaleLowerCase()] = {
...theme, ...theme,
url: isElectron()? theme.url: window.location.origin + ( window.location.pathname.startsWith('/address/') || window.location.pathname.endsWith('.sol') ? '/' : window.location.pathname ) + theme.url url: isElectron() ? theme.url : window.location.origin + (window.location.pathname.startsWith('/address/') || window.location.pathname.endsWith('.sol') ? '/' : window.location.pathname) + theme.url
} }
}) })
this._paq = _paq this._paq = _paq
@ -58,22 +58,26 @@ export class ThemeModule extends Plugin {
/** Return the active theme /** Return the active theme
* @return {{ name: string, quality: string, url: string }} - The active theme * @return {{ name: string, quality: string, url: string }} - The active theme
*/ */
currentTheme () { currentTheme() {
if (isElectron()) {
const theme = 'https://remix.ethereum.org/' + this.themes[this.active].url.replace(/\\/g, '/').replace(/\/\//g, '/').replace(/\/$/g, '')
return { ...this.themes[this.active], url: theme }
}
return this.themes[this.active] return this.themes[this.active]
} }
/** Returns all themes as an array */ /** Returns all themes as an array */
getThemes () { getThemes() {
return Object.keys(this.themes).map(key => this.themes[key]) return Object.keys(this.themes).map(key => this.themes[key])
} }
/** /**
* Init the theme * Init the theme
*/ */
initTheme (callback) { // callback is setTimeOut in app.js which is always passed initTheme(callback) { // callback is setTimeOut in app.js which is always passed
if (callback) this.initCallback = callback if (callback) this.initCallback = callback
if (this.active) { if (this.active) {
document.getElementById('theme-link') ? document.getElementById('theme-link').remove():null document.getElementById('theme-link') ? document.getElementById('theme-link').remove() : null
const nextTheme = this.themes[this.active] // Theme const nextTheme = this.themes[this.active] // Theme
document.documentElement.style.setProperty('--theme', nextTheme.quality) document.documentElement.style.setProperty('--theme', nextTheme.quality)
@ -93,7 +97,7 @@ export class ThemeModule extends Plugin {
* Change the current theme * Change the current theme
* @param {string} [themeName] - The name of the theme * @param {string} [themeName] - The name of the theme
*/ */
switchTheme (themeName) { switchTheme(themeName) {
themeName = themeName && themeName.toLocaleLowerCase() themeName = themeName && themeName.toLocaleLowerCase()
if (themeName && !Object.keys(this.themes).includes(themeName)) { if (themeName && !Object.keys(this.themes).includes(themeName)) {
throw new Error(`Theme ${themeName} doesn't exist`) throw new Error(`Theme ${themeName} doesn't exist`)
@ -103,7 +107,7 @@ export class ThemeModule extends Plugin {
_paq.push(['trackEvent', 'themeModule', 'switchTo', next]) _paq.push(['trackEvent', 'themeModule', 'switchTo', next])
const nextTheme = this.themes[next] // Theme const nextTheme = this.themes[next] // Theme
if (!this.forced) this._deps.config.set('settings/theme', next) if (!this.forced) this._deps.config.set('settings/theme', next)
document.getElementById('theme-link') ? document.getElementById('theme-link').remove():null document.getElementById('theme-link') ? document.getElementById('theme-link').remove() : null
const theme = document.createElement('link') const theme = document.createElement('link')
theme.setAttribute('rel', 'stylesheet') theme.setAttribute('rel', 'stylesheet')
@ -118,18 +122,21 @@ export class ThemeModule extends Plugin {
if (themeName) this.active = themeName if (themeName) this.active = themeName
// TODO: Only keep `this.emit` (issue#2210) // TODO: Only keep `this.emit` (issue#2210)
console.log('themeChanged', nextTheme) console.log('themeChanged', nextTheme)
if(isElectron()) { if (isElectron()) {
nextTheme.url = nextTheme.url = 'https://remix.ethereum.org/' + nextTheme.url.replace(/\\/g, '/').replace(/\/\//g, '/').replace(/\/$/g, '') const theme = 'https://remix.ethereum.org/' + nextTheme.url.replace(/\\/g, '/').replace(/\/\//g, '/').replace(/\/$/g, '')
this.emit('themeChanged', { ...nextTheme, url: theme })
this.events.emit('themeChanged', { ...nextTheme, url: theme })
} else {
this.emit('themeChanged', nextTheme)
this.events.emit('themeChanged', nextTheme)
} }
this.emit('themeChanged', nextTheme)
this.events.emit('themeChanged', nextTheme)
} }
/** /**
* fixes the invertion for images since this should be adjusted when we switch between dark/light qualified themes * fixes the invertion for images since this should be adjusted when we switch between dark/light qualified themes
* @param {element} [image] - the dom element which invert should be fixed to increase visibility * @param {element} [image] - the dom element which invert should be fixed to increase visibility
*/ */
fixInvert (image) { fixInvert(image) {
const invert = this.currentTheme().quality === 'dark' ? 1 : 0 const invert = this.currentTheme().quality === 'dark' ? 1 : 0
if (image) { if (image) {
image.style.filter = `invert(${invert})` image.style.filter = `invert(${invert})`

@ -1,19 +1,23 @@
import { Engine, PluginManager } from '@remixproject/engine'; import { Engine, PluginManager } from '@remixproject/engine';
import { ipcMain } from 'electron'; import { ipcMain } from 'electron';
import { FSPlugin } from './fsPlugin'; import { FSPlugin } from './plugins/fsPlugin';
import { GitPlugin } from './gitPlugin'; import { GitPlugin } from './plugins/gitPlugin';
import { app } from 'electron'; import { app } from 'electron';
import { XtermPlugin } from './xtermPlugin'; import { XtermPlugin } from './plugins/xtermPlugin';
import git from 'isomorphic-git'
import { IsoGitPlugin } from './plugins/isoGitPlugin';
const engine = new Engine() const engine = new Engine()
const appManager = new PluginManager() const appManager = new PluginManager()
const fsPlugin = new FSPlugin() const fsPlugin = new FSPlugin()
const gitPlugin = new GitPlugin() const gitPlugin = new GitPlugin()
const xtermPlugin = new XtermPlugin() const xtermPlugin = new XtermPlugin()
const isoGitPlugin = new IsoGitPlugin()
engine.register(appManager) engine.register(appManager)
engine.register(fsPlugin) engine.register(fsPlugin)
engine.register(gitPlugin) engine.register(gitPlugin)
engine.register(xtermPlugin) engine.register(xtermPlugin)
engine.register(isoGitPlugin)
appManager.activatePlugin('fs') appManager.activatePlugin('fs')

@ -41,38 +41,38 @@ const clientProfile: Profile = {
class FSPluginClient extends ElectronBasePluginClient { class FSPluginClient extends ElectronBasePluginClient {
watcher: chokidar.FSWatcher watcher: chokidar.FSWatcher
workingDir: string = '/Volumes/bunsen/code/rmproject2/remix-project/apps/remix-ide/contracts/' workingDir: string = '/Volumes/bunsen/code/empty/'
constructor(webContentsId: number, profile: Profile) { constructor(webContentsId: number, profile: Profile) {
super(webContentsId, profile) super(webContentsId, profile)
this.onload(() => { this.onload(() => {
console.log('fsPluginClient onload') //console.log('fsPluginClient onload')
}) })
} }
async readdir(path: string): Promise<string[]> { async readdir(path: string): Promise<string[]> {
// call node fs.readdir // call node fs.readdir
console.log('readdir', path) //console.log('readdir', path)
if (!path) return [] if (!path) return []
const files = fs.readdir(this.fixPath(path)) const files = fs.readdir(this.fixPath(path))
return files return files
} }
async readFile(path: string, options: any): Promise<string | undefined> { async readFile(path: string, options: any): Promise<string | undefined> {
console.log('readFile', path, options) //console.log('readFile', path, options)
// hacky fix for TS error // hacky fix for TS error
if (!path) return undefined if (!path) return undefined
try { try {
return (fs as any).readFile(this.fixPath(path), options) return (fs as any).readFile(this.fixPath(path), options)
} catch (e) { } catch (e) {
console.log('readFile error', e) //console.log('readFile error', e)
return undefined return undefined
} }
} }
async writeFile(path: string, content: string, options: any): Promise<void> { async writeFile(path: string, content: string, options: any): Promise<void> {
console.log('writeFile', path, content, options) //console.log('writeFile', path, content, options)
return (fs as any).writeFile(this.fixPath(path), content, options) return (fs as any).writeFile(this.fixPath(path), content, options)
} }
@ -95,14 +95,14 @@ class FSPluginClient extends ElectronBasePluginClient {
async stat(path: string): Promise<any> { async stat(path: string): Promise<any> {
try { try {
const stat = await fs.stat(this.fixPath(path)) const stat = await fs.stat(this.fixPath(path))
//console.log('stat', path, stat) ////console.log('stat', path, stat)
const isDirectory = stat.isDirectory() const isDirectory = stat.isDirectory()
return { return {
...stat, ...stat,
isDirectoryValue: isDirectory isDirectoryValue: isDirectory
} }
} catch (e) { } catch (e) {
console.log('stat error', e) //console.log('stat error', e)
return undefined return undefined
} }
} }
@ -116,40 +116,40 @@ class FSPluginClient extends ElectronBasePluginClient {
isDirectoryValue: isDirectory isDirectoryValue: isDirectory
} }
} catch (e) { } catch (e) {
console.log('lstat error', e) //console.log('lstat error', e)
return undefined return undefined
} }
} }
async exists(path: string): Promise < boolean > { async exists(path: string): Promise<boolean> {
return fs.access(this.fixPath(path)).then(() => true).catch(() => false) return fs.access(this.fixPath(path)).then(() => true).catch(() => false)
} }
async currentPath(): Promise < string > { async currentPath(): Promise<string> {
return process.cwd() return process.cwd()
} }
async watch(path: string): Promise < void> { async watch(path: string): Promise<void> {
if(this.watcher) this.watcher.close() if (this.watcher) this.watcher.close()
this.watcher = this.watcher =
chokidar.watch(this.fixPath(path)).on('change', (path, stats) => { chokidar.watch(this.fixPath(path)).on('change', (path, stats) => {
console.log('change', path, stats) //console.log('change', path, stats)
this.emit('change', path, stats) this.emit('change', path, stats)
}) })
} }
async closeWatch(): Promise < void> { async closeWatch(): Promise<void> {
console.log('closing Watcher', this.webContentsId) //console.log('closing Watcher', this.webContentsId)
if(this.watcher) this.watcher.close() if (this.watcher) this.watcher.close()
} }
async setWorkingDir(): Promise < void> { async setWorkingDir(): Promise<void> {
const dirs = dialog.showOpenDialogSync(this.window, { const dirs = dialog.showOpenDialogSync(this.window, {
properties: ['openDirectory'] properties: ['openDirectory']
}) })
if(dirs && dirs.length > 0) { if (dirs && dirs.length > 0) {
this.workingDir = dirs[0] this.workingDir = dirs[0]
this.emit('workingDirChanged', dirs[0]) this.emit('workingDirChanged', dirs[0])
} }

@ -1,6 +1,5 @@
import { PluginClient } from "@remixproject/plugin"; import { PluginClient } from "@remixproject/plugin";
import { Profile } from "@remixproject/plugin-utils"; import { Profile } from "@remixproject/plugin-utils";
import { spawn } from "child_process";
import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron" import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron"
const profile: Profile = { const profile: Profile = {
@ -33,20 +32,8 @@ class GitPluginClient extends ElectronBasePluginClient {
}) })
} }
async log(path: string): Promise<string> { async log(cmd: any): Promise<any> {
const log = spawn('git', ['log'], {
cwd: path,
env: {
NODE_ENV: 'production',
PATH: process.env.PATH,
},
})
return new Promise((resolve, reject) => {
log.stdout.on('data', (data) => {
resolve(data.toString())
})
})
} }

@ -0,0 +1,241 @@
import { PluginClient } from "@remixproject/plugin";
import { Profile } from "@remixproject/plugin-utils";
import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron"
import fs from 'fs/promises'
import git from 'isomorphic-git'
const profile: Profile = {
name: 'isogit',
displayName: 'isogit',
description: 'isogit plugin',
}
export class IsoGitPlugin extends ElectronBasePlugin {
client: PluginClient
constructor() {
super(profile, clientProfile, IsoGitPluginClient)
}
}
const clientProfile: Profile = {
name: 'isogit',
displayName: 'isogit',
description: 'isogit plugin',
methods: ['init', 'localStorageUsed', 'addremote', 'delremote', 'remotes', 'fetch', 'clone', 'export', 'import', 'status', 'log', 'commit', 'add', 'remove', 'rm', 'lsfiles', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pin', 'pull', 'pinList', 'unPin', 'setIpfsConfig', 'zip', 'setItem', 'getItem']
}
class IsoGitPluginClient extends ElectronBasePluginClient {
workingDir: string = '/Volumes/bunsen/code/empty/'
constructor(webContentsId: number, profile: Profile) {
super(webContentsId, profile)
this.onload(() => {
console.log('IsoGit client onload')
this.on('fs' as any, 'workingDirChanged', async (path: string) => {
console.log('workingDirChanged', path)
this.workingDir = path
await this.status({
})
})
})
}
async getGitConfig () {
return {
fs,
dir: this.workingDir,
}
}
async status (cmd: any) {
console.log('status')
const status = await git.statusMatrix({
...await this.getGitConfig(),
...cmd
})
console.log('STATUS', status, await this.getGitConfig())
return status
}
async log (cmd: any) {
console.log('log')
const log = await git.log({
...await this.getGitConfig(),
...cmd
})
console.log('LOG', log)
return log
}
async add (cmd: any) {
console.log('add')
const add = await git.add({
...await this.getGitConfig(),
...cmd
})
console.log('ADD', add)
return add
}
async rm(cmd: any) {
console.log('rm')
const rm = await git.remove({
...await this.getGitConfig(),
...cmd
})
console.log('RM', rm)
return rm
}
async commit (cmd: any) {
console.log('commit')
const commit = await git.commit({
...await this.getGitConfig(),
...cmd
})
console.log('COMMIT', commit)
return commit
}
async init (input: any) {
await git.init({
...await this.getGitConfig(),
defaultBranch: (input && input.branch) || 'main'
})
}
async branch (cmd: any) {
console.log('branch')
const branch = await git.branch({
...await this.getGitConfig(),
...cmd
})
console.log('BRANCH', branch)
return branch
}
async lsfiles (cmd: any) {
console.log('lsfiles')
const lsfiles = await git.listFiles({
...await this.getGitConfig(),
...cmd
})
console.log('LSFILES', lsfiles)
return lsfiles
}
async resolveref (cmd: any) {
console.log('resolveref')
const resolveref = await git.resolveRef({
...await this.getGitConfig(),
...cmd
})
console.log('RESOLVEREF', resolveref)
return resolveref
}
async readblob (cmd: any) {
console.log('readblob')
const readblob = await git.readBlob({
...await this.getGitConfig(),
...cmd
})
console.log('READBLOB', readblob)
return readblob
}
async checkout (cmd: any) {
console.log('checkout')
const checkout = await git.checkout({
...await this.getGitConfig(),
...cmd
})
console.log('CHECKOUT', checkout)
return checkout
}
async push (cmd: any) {
console.log('push')
const push = await git.push({
...await this.getGitConfig(),
...cmd
})
console.log('PUSH', push)
return push
}
async pull (cmd: any) {
console.log('pull')
const pull = await git.pull({
...await this.getGitConfig(),
...cmd
})
console.log('PULL', pull)
return pull
}
async fetch(cmd: any) {
console.log('fetch')
const fetch = await git.fetch({
...await this.getGitConfig(),
...cmd
})
console.log('FETCH', fetch)
return fetch
}
remotes = async () => {
let remotes = []
remotes = await git.listRemotes({...await this.getGitConfig() })
console.log('remotes', remotes)
return remotes
}
async currentbranch() {
try {
const defaultConfig = await this.getGitConfig()
const name = await git.currentBranch(defaultConfig)
console.log('currentbranch', name)
return name
} catch (e) {
return ''
}
}
async branches() {
try {
let cmd: any = {...await this.getGitConfig()}
const remotes = await this.remotes()
let branches = []
branches = (await git.listBranches(cmd)).map((branch) => { return { remote: undefined, name: branch } })
for (const remote of remotes) {
cmd = {
...cmd,
remote: remote.remote
}
const remotebranches = (await git.listBranches(cmd)).map((branch) => { return { remote: remote.remote, name: branch } })
branches = [...branches, ...remotebranches]
}
console.log('branches', branches)
return branches
} catch (e) {
return []
}
}
}

@ -6,7 +6,7 @@ console.log('preload.ts')
/* preload script needs statically defined API for each plugin */ /* preload script needs statically defined API for each plugin */
const exposedPLugins = ['fs', 'git', 'xterm'] const exposedPLugins = ['fs', 'git', 'xterm', 'isogit']
console.log('preload.ts', process) console.log('preload.ts', process)
let webContentsId: number | undefined let webContentsId: number | undefined

@ -125,6 +125,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
dispatch(setCurrentWorkspace({ name: 'electron', isGitRepo: false })) dispatch(setCurrentWorkspace({ name: 'electron', isGitRepo: false }))
listenOnProviderEvents(electrOnProvider)(dispatch) listenOnProviderEvents(electrOnProvider)(dispatch)
listenOnPluginEvents(plugin)
dispatch(setMode('browser')) dispatch(setMode('browser'))
dispatch(fsInitializationCompleted()) dispatch(fsInitializationCompleted())
plugin.emit('workspaceInitializationCompleted') plugin.emit('workspaceInitializationCompleted')

Loading…
Cancel
Save