pull/4991/head
Your Name 5 months ago
parent 8e249dc88d
commit 0ac2809d54
  1. 397
      apps/remix-ide/src/app/files/dgitProvider.ts
  2. 68
      apps/remixdesktop/src/plugins/isoGitPlugin.ts
  3. 23
      libs/remix-api/src/lib/types/git.ts
  4. 418
      libs/remix-git/src/isogit.ts
  5. 4
      libs/remix-ui/git/src/lib/gitactions.ts
  6. 4
      libs/remix-ui/git/src/state/actions.ts
  7. 4
      libs/remix-ui/git/src/state/gitpayload.ts
  8. 4
      libs/remix-ui/git/src/types/index.ts

@ -4,26 +4,14 @@ import {
Plugin
} from '@remixproject/engine'
import git, { ReadBlobResult, ReadCommitResult, StatusRow } from 'isomorphic-git'
import IpfsHttpClient from 'ipfs-http-client'
import {
saveAs
} from 'file-saver'
import http from 'isomorphic-git/http/web'
import JSZip from 'jszip'
import path from 'path'
import FormData from 'form-data'
import axios from 'axios'
import { Registry } from '@remix-project/remix-lib'
import { Octokit, App } from "octokit"
import { OctokitResponse } from '@octokit/types'
import { Endpoints } from "@octokit/types"
import { Octokit } from "octokit"
import { IndexedDBStorage } from './filesystems/indexedDB'
import { GitHubUser, branch, commitChange, remote, userEmails } from '@remix-ui/git'
import { checkoutInputType, statusInput, logInputType, author, pagedCommits, remoteCommitsInputType, cloneInputType, fetchInputType, pullInputType, pushInputType, currentBranchInput, branchInputType, addInputType, rmInputType, resolveRefInput, readBlobInput, repositoriesInput, commitInputType, branchDifference, compareBranchesInput, initInputType, isoGitConfig} from '@remix-api'
import { LibraryProfile, StatusEvents } from '@remixproject/plugin-utils'
import { ITerminal } from '@remixproject/plugin-api/src/lib/terminal'
import { partial } from 'lodash'
import { branch, commitChange, remote } from '@remix-ui/git'
import { checkoutInputType, statusInput, logInputType, author, pagedCommits, remoteCommitsInputType, cloneInputType, fetchInputType, pullInputType, pushInputType, currentBranchInput, branchInputType, addInputType, rmInputType, resolveRefInput, readBlobInput, repositoriesInput, commitInputType, branchDifference, compareBranchesInput, initInputType, isoGitFSConfig, GitHubUser, userEmails } from '@remix-api'
import { LibraryProfile } from '@remixproject/plugin-utils'
import { CustomRemixApi } from '@remix-api'
import { isoGit } from "libs/remix-git/src/isogit"
@ -37,49 +25,17 @@ const profile: LibraryProfile = {
description: 'Decentralized git provider',
icon: 'assets/img/fileManager.webp',
version: '0.0.1',
methods: ['init', 'localStorageUsed', 'addremote', 'delremote', 'remotes', 'fetch', 'clone', 'export', 'import', 'status', 'log', 'commit', 'add', 'remove', 'rm', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pull', 'setIpfsConfig', 'zip', 'setItem', 'getItem', 'version', 'updateSubmodules'
methods: ['init', 'addremote', 'delremote', 'remotes', 'fetch', 'clone', 'status', 'log', 'commit', 'add', 'remove', 'rm', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pull', 'version', 'updateSubmodules'
, 'getGitHubUser', 'remotebranches', 'remotecommits', 'repositories', 'getCommitChanges', 'compareBranches'],
kind: 'file-system'
}
class DGitProvider extends Plugin<any, CustomRemixApi> {
ipfsconfig: { host: string; port: number; protocol: string; ipfsurl: string }
globalIPFSConfig: { host: string; port: number; protocol: string; ipfsurl: string }
remixIPFS: { host: string; port: number; protocol: string; ipfsurl: string }
ipfsSources: any[]
ipfs: any
filesToSend: any[]
constructor() {
super(profile)
this.ipfsconfig = {
host: 'jqgt.remixproject.org',
port: 443,
protocol: 'https',
ipfsurl: 'https://jqgt.remixproject.org/ipfs/'
}
this.globalIPFSConfig = {
host: 'ipfs.io',
port: 443,
protocol: 'https',
ipfsurl: 'https://ipfs.io/ipfs/'
}
this.remixIPFS = {
host: 'jqgt.remixproject.org',
port: 443,
protocol: 'https',
ipfsurl: 'https://jqgt.remixproject.org/ipfs/'
}
this.ipfsSources = [this.remixIPFS, this.globalIPFSConfig, this.ipfsconfig]
}
async addIsomorphicGitConfigFS(dir = '') {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return {
fs: window.remixFileSystem,
dir: '/'
}
}
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
if (!workspace) return
@ -89,61 +45,12 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
}
}
async addIsomorphicGitConfig(input) {
const token = await this.call('config' as any, 'getAppParameter', 'settings/gist-access-token')
let config = {
corsProxy: 'https://corsproxy.remixproject.org/',
http,
onAuth: url => {
url
const auth = {
username: input.token || token,
password: ''
}
return auth
}
}
if (input.url) {
const url = new URL(input.url)
if (url.hostname.includes('localhost')) {
config = {
...config,
corsProxy: null
}
}
}
if ((input.remote && input.remote.url)) {
const url = new URL(input.remote.url)
if (url.hostname.includes('localhost')) {
config = {
...config,
corsProxy: null,
}
}
}
if (input.provider && input.provider === 'github') {
config = {
...config,
corsProxy: 'https://corsproxy.remixproject.org/',
}
}
if (input.provider && input.provider === 'localhost') {
config = {
...config,
corsProxy: null
}
}
return config
async getToken() {
return await this.call('config' as any, 'getAppParameter', 'settings/gist-access-token')
}
async getCommandUser(input) {
async getAuthor(input) {
const author: author = {
name: '',
email: ''
@ -306,10 +213,10 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
async getCommitChanges(commitHash1: string, commitHash2: string): Promise<commitChange[]> {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
const result = this.call('isogit', 'getCommitChanges', commitHash1, commitHash2 )
const result = this.call('isogit', 'getCommitChanges', commitHash1, commitHash2)
return result
}
return await isoGit.getCommitChanges(commitHash1, commitHash2, await this.addIsomorphicGitConfigFS())
}
@ -351,7 +258,7 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
return await isoGit.currentbranch(input, defaultConfig)
}
async branches(config: isoGitConfig): Promise<branch[]> {
async branches(config: isoGitFSConfig): Promise<branch[]> {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
const branches = await this.call('isogit', 'branches')
@ -416,22 +323,6 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
return readBlobResult
}
async setIpfsConfig(config) {
this.ipfsconfig = config
return new Promise((resolve) => {
resolve(this.checkIpfsConfig())
})
}
async checkIpfsConfig(config?) {
this.ipfs = IpfsHttpClient(config || this.ipfsconfig)
try {
await this.ipfs.config.getAll()
return true
} catch (e) {
return false
}
}
async addremote(input: remote): Promise<void> {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
@ -449,10 +340,6 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
await git.deleteRemote({ ...await this.addIsomorphicGitConfigFS(), remote: input.name })
}
async localStorageUsed() {
return this.calculateLocalStorage()
}
async clone(input: cloneInputType) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
@ -481,14 +368,13 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
} else {
const permission = await this.askUserPermission('clone', 'Import multiple files into your workspaces.')
if (!permission) return false
if (parseFloat(this.calculateLocalStorage()) > 10000) throw new Error('The local storage of the browser is full.')
if (!input.workspaceExists) await this.call('filePanel', 'createWorkspace', input.workspaceName || `workspace_${Date.now()}`, true)
const cmd = {
url: input.url,
singleBranch: input.singleBranch,
ref: input.branch,
depth: input.depth || 10,
...await this.addIsomorphicGitConfig(input),
...await isoGit.addIsomorphicGitProxyConfig(input, this),
...await this.addIsomorphicGitConfigFS()
}
this.call('terminal', 'logHtml', `Cloning ${input.url}... please wait...`)
@ -575,10 +461,10 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
url: module.url,
singleBranch: true,
depth: 1,
...await this.addIsomorphicGitConfig({
...await isoGit.addIsomorphicGitProxyConfig({
...input,
provider: 'github'
}),
provider: 'github',
}, this),
...await this.addIsomorphicGitConfigFS(dir)
}
this.call('terminal', 'logHtml', `Cloning submodule ${dir}...`)
@ -602,10 +488,10 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
if (result && result.length) {
this.call('terminal', 'logHtml', `Checking out submodule ${dir} to ${result[0]} in directory ${dir}`)
await git.fetch({
...await this.addIsomorphicGitConfig({
...await isoGit.addIsomorphicGitProxyConfig({
...input,
provider: 'github'
}),
provider: 'github',
}, this),
...await this.addIsomorphicGitConfigFS(dir),
singleBranch: true,
ref: result[0]
@ -652,61 +538,23 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
async push(input: pushInputType) {
const cmd = {
force: input.force,
ref: input.ref.name,
remoteRef: input.remoteRef && input.remoteRef.name,
remote: input.remote.name,
author: await this.getCommandUser(input),
input,
}
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return await this.call('isogit', 'push', {
...input,
author: await this.getCommandUser(input),
})
return await this.call('isogit', 'push', input)
} else {
const cmd2 = {
...cmd,
...await this.addIsomorphicGitConfig(input),
}
const result = await git.push({
...await this.addIsomorphicGitConfigFS(),
...cmd2
})
const result = await isoGit.push(input, await this.addIsomorphicGitConfigFS(), this)
return result
}
}
async pull(input: pullInputType) {
const cmd = {
ref: input.ref.name,
remoteRef: input.remoteRef && input.remoteRef.name,
author: await this.getCommandUser(input),
remote: input.remote.name,
input,
}
let result
if ((Registry.getInstance().get('platform').api.isDesktop())) {
result = await this.call('isogit', 'pull', {
...input,
author: await this.getCommandUser(input),
})
result = await this.call('isogit', 'pull', input)
}
else {
const cmd2 = {
...cmd,
...await this.addIsomorphicGitConfig(input),
}
result = await git.pull({
...await this.addIsomorphicGitConfigFS(),
...cmd2
})
result = await isoGit.pull(input, await this.addIsomorphicGitConfigFS(), this)
}
setTimeout(async () => {
await this.call('fileManager', 'refresh')
@ -715,33 +563,15 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
}
async fetch(input: fetchInputType) {
const cmd = {
ref: input.ref && input.ref.name,
remoteRef: input.remoteRef && input.remoteRef.name,
author: await this.getCommandUser(input),
remote: input.remote && input.remote.name,
depth: input.depth || 5,
singleBranch: input.singleBranch,
relative: input.relative,
input
}
let result
if ((Registry.getInstance().get('platform').api.isDesktop())) {
result = await this.call('isogit', 'fetch', {
...input,
author: await this.getCommandUser(input),
})
} else {
const cmd2 = {
...cmd,
...await this.addIsomorphicGitConfig(input),
}
result = await git.fetch({
...await this.addIsomorphicGitConfigFS(),
...cmd2
})
result = await isoGit.fetch(input, await this.addIsomorphicGitConfigFS(), this)
}
setTimeout(async () => {
@ -750,162 +580,6 @@ class DGitProvider extends Plugin<any, CustomRemixApi> {
return result
}
async export(config) {
if (!this.checkIpfsConfig(config)) return false
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
const files = await this.getDirectory('/')
this.filesToSend = []
for (const file of files) {
const c = await window.remixFileSystem.readFile(`${workspace.absolutePath}/${file}`, null)
const ob = {
path: file,
content: c
}
this.filesToSend.push(ob)
}
const addOptions = {
wrapWithDirectory: true
}
const r = await this.ipfs.add(this.filesToSend, addOptions)
return r.cid.string
}
async importIPFSFiles(config, cid, workspace) {
const ipfs = IpfsHttpClient(config)
let result = false
try {
const data = ipfs.get(cid, { timeout: 60000 })
for await (const file of data) {
if (file.path) result = true
file.path = file.path.replace(cid, '')
if (!file.content) {
continue
}
const content = []
for await (const chunk of file.content) {
content.push(chunk)
}
const dir = path.dirname(file.path)
try {
await this.createDirectories(`${workspace.absolutePath}/${dir}`)
} catch (e) { throw new Error(e) }
try {
await window.remixFileSystem.writeFile(`${workspace.absolutePath}/${file.path}`, Buffer.concat(content) || new Uint8Array(), null)
} catch (e) { throw new Error(e) }
}
} catch (e) {
throw new Error(e)
}
return result
}
calculateLocalStorage() {
let _lsTotal = 0
let _xLen; let _x
for (_x in localStorage) {
// eslint-disable-next-line no-prototype-builtins
if (!localStorage.hasOwnProperty(_x)) {
continue
}
_xLen = ((localStorage[_x].length + _x.length) * 2)
_lsTotal += _xLen
}
return (_lsTotal / 1024).toFixed(2)
}
async import(cmd) {
const permission = await this.askUserPermission('import', 'Import multiple files into your workspaces.')
if (!permission) return false
if (parseFloat(this.calculateLocalStorage()) > 10000) throw new Error('The local storage of the browser is full.')
const cid = cmd.cid
await this.call('filePanel', 'createWorkspace', `workspace_${Date.now()}`, true)
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
let result
if (cmd.local) {
result = await this.importIPFSFiles(this.ipfsconfig, cid, workspace)
} else {
result = await this.importIPFSFiles(this.remixIPFS, cid, workspace) || await this.importIPFSFiles(this.ipfsconfig, cid, workspace) || await this.importIPFSFiles(this.globalIPFSConfig, cid, workspace)
}
setTimeout(async () => {
await this.call('fileManager', 'refresh')
}, 1000)
if (!result) throw new Error(`Cannot pull files from IPFS at ${cid}`)
}
async getItem(name) {
if (typeof window !== 'undefined') {
return window.localStorage.getItem(name)
}
}
async setItem(name, content) {
try {
if (typeof window !== 'undefined') {
window.localStorage.setItem(name, content)
}
} catch (e) {
console.log(e)
return false
}
return true
}
async zip() {
const zip = new JSZip()
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
const files = await this.getDirectory('/')
this.filesToSend = []
for (const file of files) {
const c = await window.remixFileSystem.readFile(`${workspace.absolutePath}/${file}`, null)
zip.file(file, c)
}
await zip.generateAsync({
type: 'blob'
})
.then(function (content) {
saveAs(content, `${workspace.name}.zip`)
})
}
async createDirectories(strdirectories) {
const ignore = ['.', '/.', '']
if (ignore.indexOf(strdirectories) > -1) return false
const directories = strdirectories.split('/')
for (let i = 0; i < directories.length; i++) {
let previouspath = ''
if (i > 0) previouspath = '/' + directories.slice(0, i).join('/')
const finalPath = previouspath + '/' + directories[i]
try {
if (!await window.remixFileSystem.exists(finalPath)) {
await window.remixFileSystem.mkdir(finalPath)
}
} catch (e) {
console.log(e)
}
}
}
async getDirectory(dir) {
let result = []
const files = await this.call('fileManager', 'readdir', dir)
const fileArray = normalize(files)
for (const fi of fileArray) {
if (fi) {
const type = fi.data.isDirectory
if (type === true) {
result = [
...result,
...(await this.getDirectory(
`${fi.filename}`
))
]
} else {
result = [...result, fi.filename]
}
}
}
return result
}
// OCTOKIT FEATURES
@ -1042,23 +716,4 @@ const addSlash = (file) => {
return file
}
const normalize = (filesList) => {
const folders = []
const files = []
Object.keys(filesList || {}).forEach(key => {
if (filesList[key].isDirectory) {
folders.push({
filename: key,
data: filesList[key]
})
} else {
files.push({
filename: key,
data: filesList[key]
})
}
})
return [...folders, ...files]
}
module.exports = DGitProvider

@ -5,7 +5,7 @@ import git from 'isomorphic-git'
import http from 'isomorphic-git/http/web'
import { gitProxy } from "../tools/git";
import { isoGit } from "@remix-git"
import { branch, branchDifference, branchInputType, cloneInputType, commitChange, commitInputType, compareBranchesInput, currentBranchInput, fetchInputType, initInputType, logInputType, pullInputType, pushInputType, remote, resolveRefInput, statusInput } from "@remix-api";
import { branchDifference, branchInputType, cloneInputType, commitChange, commitInputType, compareBranchesInput, currentBranchInput, fetchInputType, initInputType, logInputType, pullInputType, pushInputType, remote, resolveRefInput, statusInput } from "@remix-api";
const profile: Profile = {
name: 'isogit',
@ -28,20 +28,6 @@ export class IsoGitPlugin extends ElectronBasePlugin {
}
}
const parseInput = (input: any) => {
return {
corsProxy: 'https://corsproxy.remixproject.org/',
http,
onAuth: (url: any) => {
url
const auth = {
username: input.token,
password: ''
}
return auth
}
}
}
const clientProfile: Profile = {
name: 'isogit',
@ -58,10 +44,10 @@ class IsoGitPluginClient extends ElectronBasePluginClient {
this.onload(async () => {
this.on('fs' as any, 'workingDirChanged', async (path: string) => {
this.workingDir = path
this.gitIsInstalled = await gitProxy.version() ? true : false
this.gitIsInstalled = await gitProxy.version() ? true : false
})
this.workingDir = await this.call('fs' as any, 'getWorkingDir')
this.gitIsInstalled = await gitProxy.version() && !useIsoGit ? true : false
this.gitIsInstalled = await gitProxy.version() && !useIsoGit ? true : false
})
}
@ -102,6 +88,8 @@ class IsoGitPluginClient extends ElectronBasePluginClient {
async log(cmd: logInputType) {
console.log('LOG', cmd)
const token = await this.call('config' as any, 'getAppParameter', 'settings/gist-access-token')
console.log('LOG', token)
/* we will use isomorphic git for now
if(this.gitIsInstalled){
const log = await gitProxy.log(this.workingDir, cmd.ref)
@ -237,66 +225,46 @@ class IsoGitPluginClient extends ElectronBasePluginClient {
return checkout
}
async push(cmd: pushInputType) {
async push(input: pushInputType) {
console.log('PUSH', input, this.gitIsInstalled)
if (!this.workingDir || this.workingDir === '') {
throw new Error('No working directory')
}
if (this.gitIsInstalled) {
await gitProxy.push(this.workingDir, cmd)
return await gitProxy.push(this.workingDir, input)
} else {
/*
const push = await git.push({
...await this.getGitConfig(),
...cmd,
...parseInput(cmd.input)
})
return push*/
const push = await isoGit.push(input, await this.getGitConfig(), this)
return push
}
}
async pull(cmd: pullInputType) {
async pull(input: pullInputType) {
console.log('PULL', input)
if (!this.workingDir || this.workingDir === '') {
throw new Error('No working directory')
}
if (this.gitIsInstalled) {
await gitProxy.pull(this.workingDir, cmd)
return await gitProxy.pull(this.workingDir, input)
} else {
/*
const pull = await git.pull({
...await this.getGitConfig(),
...cmd,
...parseInput(cmd.input)
})
const pull = await isoGit.pull(input, await this.getGitConfig(), this)
return pull
*/
}
}
async fetch(cmd: fetchInputType) {
console.log('FETCH', cmd)
async fetch(input: fetchInputType) {
console.log('FETCH', input)
if (!this.workingDir || this.workingDir === '') {
throw new Error('No working directory')
}
if (this.gitIsInstalled) {
await gitProxy.fetch(this.workingDir, cmd)
await gitProxy.fetch(this.workingDir, input)
} else {
/*
const fetch = await git.fetch({
...await this.getGitConfig(),
...cmd,
...parseInput(cmd.input)
})
*/
const fetch = await isoGit.fetch(input, await this.getGitConfig(), this)
return fetch
}
}

@ -1,4 +1,5 @@
import { ReadCommitResult } from "isomorphic-git"
import { Endpoints } from "@octokit/types"
import { AuthCallback, HttpClient, ReadCommitResult } from "isomorphic-git"
export type branchDifference = {
uniqueHeadCommits: ReadCommitResult[],
@ -71,7 +72,7 @@ export type initInputType = {
export type author = {
name: string,
email: string
email: string,
}
export type updateSubmodulesInput = {
@ -96,6 +97,7 @@ export type fetchInputType = {
relative?: boolean,
quiet?: boolean
author?: author
token?: string
}
export type logInputType = {
@ -108,6 +110,7 @@ export type pullInputType = {
ref: branch,
remoteRef?: branch
author?: author
token?: string
}
export type pushInputType = {
@ -115,7 +118,8 @@ export type pushInputType = {
ref: branch,
remoteRef?: branch,
force?: boolean,
author?: author
author?: author,
token?: string
}
export type branchInputType = {
@ -183,7 +187,16 @@ export interface repositoriesInput { token: string, page?: number, per_page?: nu
export interface statusInput { ref: string, filepaths?: string[] }
export type isoGitConfig = {
export type isoGitFSConfig = {
fs: any,
dir: string,
}
}
export type isoGitProxyConfig = {
corsProxy: string
http: HttpClient
onAuth: AuthCallback
}
export type GitHubUser = Partial<Endpoints["GET /user"]["response"]['data']>
export type userEmails = Endpoints["GET /user/emails"]["response"]["data"]

@ -1,159 +1,329 @@
import { branch, commitChange, compareBranchesInput, currentBranchInput, isoGitConfig, remote } from "@remix-api"
import { GitHubUser, author, branch, commitChange, compareBranchesInput, currentBranchInput, fetchInputType, isoGitFSConfig, isoGitProxyConfig, pullInputType, pushInputType, remote, userEmails } from "@remix-api"
import git from 'isomorphic-git'
import {
Plugin
} from '@remixproject/engine'
import http from 'isomorphic-git/http/web'
const currentbranch = async (input: currentBranchInput, defaultConfig: isoGitConfig ) => {
console.log('CURRENT BRANCH', input)
import { Octokit } from "octokit"
import { ElectronBasePluginClient } from "@remixproject/plugin-electron"
const currentbranch = async (input: currentBranchInput, fsConfig: isoGitFSConfig) => {
console.log('CURRENT BRANCH', input)
try {
const cmd = input ? fsConfig ? { ...fsConfig, ...input } : input : fsConfig
const name = await git.currentBranch(cmd)
let remote: remote = undefined
try {
const cmd = input ? defaultConfig ? { ...defaultConfig, ...input } : input : defaultConfig
const name = await git.currentBranch(cmd)
let remote: remote = undefined
try {
const remoteName = await git.getConfig({
...defaultConfig,
path: `branch.${name}.remote`
const remoteName = await git.getConfig({
...fsConfig,
path: `branch.${name}.remote`
})
if (remoteName) {
const remoteUrl = await git.getConfig({
...fsConfig,
path: `remote.${remoteName}.url`
})
if (remoteName) {
const remoteUrl = await git.getConfig({
...defaultConfig,
path: `remote.${remoteName}.url`
})
remote = { name: remoteName, url: remoteUrl }
}
remote = { name: remoteName, url: remoteUrl }
}
} catch (e) {
// do nothing
} catch (e) {
// do nothing
}
console.log('NAME', name)
console.log('REMOTE', remote)
return {
remote: remote,
name: name || ''
}
} catch (e) {
return undefined
}
}
const branches = async (fsConfig: isoGitFSConfig) => {
try {
const remotes = await isoGit.remotes(fsConfig)
let branches: branch[] = []
branches = (await git.listBranches(fsConfig)).map((branch) => { return { remote: undefined, name: branch } })
for (const remote of remotes) {
const cmd = {
...fsConfig,
remote: remote.name
}
console.log('NAME', name)
console.log('REMOTE', remote)
return {
remote: remote,
name: name || ''
const remotebranches = (await git.listBranches(cmd)).map((branch) => { return { remote: remote, name: branch } })
branches = [...branches, ...remotebranches]
}
return branches
} catch (e) {
console.log(e)
return []
}
}
const remotes = async (fsConfig: isoGitFSConfig) => {
let remotes: remote[] = []
try {
remotes = (await git.listRemotes({ ...fsConfig })).map((remote) => { return { name: remote.remote, url: remote.url } }
)
} catch (e) {
// do nothing
}
return remotes
}
const push = async (input: pushInputType, fsConfig: isoGitFSConfig, plugin: Plugin | ElectronBasePluginClient) => {
const cmd = {
force: input.force,
ref: input.ref.name,
remoteRef: input.remoteRef && input.remoteRef.name,
remote: input.remote.name,
author: await getAuthor(input, plugin),
input,
}
const proxy = await isoGit.addIsomorphicGitProxyConfig(input, plugin)
console.log({ ...fsConfig, ...cmd, ...proxy })
return await git.push({ ...fsConfig, ...cmd, ...proxy })
}
const pull = async (input: pullInputType, fsConfig: isoGitFSConfig, plugin: Plugin | ElectronBasePluginClient) => {
const cmd = {
ref: input.ref.name,
remoteRef: input.remoteRef && input.remoteRef.name,
author: await getAuthor(input, plugin),
remote: input.remote.name,
input,
}
const proxy = await isoGit.addIsomorphicGitProxyConfig(input, plugin)
console.log({ ...fsConfig, ...cmd, ...proxy })
return await git.pull({ ...fsConfig, ...cmd, ...proxy })
}
const fetch = async (input: fetchInputType, fsConfig: isoGitFSConfig, plugin: Plugin | ElectronBasePluginClient) => {
const cmd = {
ref: input.ref && input.ref.name,
remoteRef: input.remoteRef && input.remoteRef.name,
author: await getAuthor(input, plugin),
remote: input.remote && input.remote.name,
depth: input.depth || 5,
singleBranch: input.singleBranch,
relative: input.relative,
input
}
const proxy = await isoGit.addIsomorphicGitProxyConfig(input, plugin)
console.log({ ...fsConfig, ...cmd, ...proxy })
return await git.fetch({ ...fsConfig, ...cmd, ...proxy })
}
const getAuthor = async (input, plugin: any) => {
const author: author = {
name: '',
email: ''
}
if (input && input.name && input.email) {
author.name = input.name
author.email = input.email
} else {
const username = await plugin.call('config' as any, 'getAppParameter', 'settings/github-user-name')
const email = await plugin.call('config' as any, 'getAppParameter', 'settings/github-email')
const token = await plugin.call('config' as any, 'getAppParameter', 'settings/gist-access-token')
if (username && email) {
author.name = username
author.email = email
} else if (token) {
const gitHubUser = await isoGit.getGitHubUser({ token })
if (gitHubUser) {
author.name = gitHubUser.user.login
}
} catch (e) {
return undefined
}
}
return author
}
const branches = async (defaultConfig: isoGitConfig ) => {
try {
const remotes = await isoGit.remotes(defaultConfig)
let branches: branch[] = []
branches = (await git.listBranches(defaultConfig)).map((branch) => { return { remote: undefined, name: branch } })
for (const remote of remotes) {
const cmd = {
...defaultConfig,
remote: remote.name
}
const remotebranches = (await git.listBranches(cmd)).map((branch) => { return { remote: remote, name: branch } })
branches = [...branches, ...remotebranches]
const getGitHubUser = async (input: { token: string }): Promise<{
user: GitHubUser,
emails: userEmails,
scopes: string[]
}> => {
try {
const octokit = new Octokit({
auth: input.token
})
const user = await octokit.request('GET /user')
const emails = await octokit.request('GET /user/emails')
const scopes = user.headers['x-oauth-scopes'] || ''
console.log('USER', user.data)
return {
user: user.data,
emails: emails.data,
scopes: scopes && scopes.split(',')
}
} catch (e) {
return null
}
}
const addIsomorphicGitProxyConfig = async (input: {
url?: string,
remote?: remote,
provider?: 'github' | 'localhost',
token?: string,
}, plugin: any) => {
const token = await plugin.call('config' as any, 'getAppParameter', 'settings/gist-access-token')
console.log('TOKEN', token)
let config: isoGitProxyConfig = {
corsProxy: 'https://corsproxy.remixproject.org/',
http,
onAuth: url => {
url
const auth = {
username: input.token || token,
password: ''
}
return branches
} catch (e) {
console.log(e)
return []
return auth
}
}
if (input.url) {
const remotes = async(defaultConfig: isoGitConfig) => {
const url = new URL(input.url)
if (url.hostname.includes('localhost')) {
config = {
...config,
corsProxy: null
}
}
}
if ((input.remote && input.remote.url)) {
let remotes: remote[] = []
try {
remotes = (await git.listRemotes({ ...defaultConfig })).map((remote) => { return { name: remote.remote, url: remote.url } }
)
} catch (e) {
// do nothing
const url = new URL(input.remote.url)
if (url.hostname.includes('localhost')) {
config = {
...config,
corsProxy: null,
}
}
}
if (input.provider && input.provider === 'github') {
config = {
...config,
corsProxy: 'https://corsproxy.remixproject.org/',
}
return remotes
}
const getCommitChanges = async (commitHash1: string, commitHash2: string, defaultConfig: isoGitConfig) => {
const result: commitChange[] = await git.walk({
...defaultConfig,
trees: [git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })],
map: async function (filepath, [A, B]) {
if (input.provider && input.provider === 'localhost') {
config = {
...config,
corsProxy: null
}
}
return config
}
const getCommitChanges = async (commitHash1: string, commitHash2: string, fsConfig: isoGitFSConfig) => {
const result: commitChange[] = await git.walk({
...fsConfig,
trees: [git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })],
map: async function (filepath, [A, B]) {
if (filepath === '.') {
if (filepath === '.') {
return
}
try {
if ((A && await A.type()) === 'tree' || B && (await B.type()) === 'tree') {
return
}
try {
if ((A && await A.type()) === 'tree' || B && (await B.type()) === 'tree') {
return
}
} catch (e) {
// ignore
}
} catch (e) {
// ignore
}
// generate ids
const Aoid = A && await A.oid() || undefined
const Boid = B && await B.oid() || undefined
// generate ids
const Aoid = A && await A.oid() || undefined
const Boid = B && await B.oid() || undefined
const commitChange: Partial<commitChange> = {
hashModified: commitHash1,
hashOriginal: commitHash2,
path: filepath,
}
const commitChange: Partial<commitChange> = {
hashModified: commitHash1,
hashOriginal: commitHash2,
path: filepath,
}
// determine modification type
if (Aoid !== Boid) {
commitChange.type = "modified"
}
if (Aoid === undefined) {
commitChange.type = "deleted"
}
if (Boid === undefined || !commitHash2) {
commitChange.type = "added"
}
if (Aoid === undefined && Boid === undefined) {
commitChange.type = "unknown"
}
if (commitChange.type)
return commitChange
else
return undefined
},
})
// determine modification type
if (Aoid !== Boid) {
commitChange.type = "modified"
}
if (Aoid === undefined) {
commitChange.type = "deleted"
}
if (Boid === undefined || !commitHash2) {
commitChange.type = "added"
}
if (Aoid === undefined && Boid === undefined) {
commitChange.type = "unknown"
}
if (commitChange.type)
return commitChange
else
return undefined
},
})
return result
}
return result
}
const compareBranches = async ({ branch, remote }: compareBranchesInput, defaultConfig: isoGitConfig) => {
const compareBranches = async ({ branch, remote }: compareBranchesInput, fsConfig: isoGitFSConfig) => {
// Get current branch commits
const headCommits = await git.log({
...defaultConfig,
ref: branch.name,
});
// Get current branch commits
const headCommits = await git.log({
...fsConfig,
ref: branch.name,
});
// Get remote branch commits
const remoteCommits = await git.log({
...defaultConfig,
ref: `${remote.name}/${branch.name}`,
});
// Get remote branch commits
const remoteCommits = await git.log({
...fsConfig,
ref: `${remote.name}/${branch.name}`,
});
// Convert arrays of commit objects to sets of commit SHAs
const headCommitSHAs = new Set(headCommits.map(commit => commit.oid));
const remoteCommitSHAs = new Set(remoteCommits.map(commit => commit.oid));
// Convert arrays of commit objects to sets of commit SHAs
const headCommitSHAs = new Set(headCommits.map(commit => commit.oid));
const remoteCommitSHAs = new Set(remoteCommits.map(commit => commit.oid));
// Filter out commits that are only in the remote branch
const uniqueRemoteCommits = remoteCommits.filter(commit => !headCommitSHAs.has(commit.oid));
// Filter out commits that are only in the remote branch
const uniqueRemoteCommits = remoteCommits.filter(commit => !headCommitSHAs.has(commit.oid));
// filter out commits that are only in the local branch
const uniqueHeadCommits = headCommits.filter(commit => !remoteCommitSHAs.has(commit.oid));
// filter out commits that are only in the local branch
const uniqueHeadCommits = headCommits.filter(commit => !remoteCommitSHAs.has(commit.oid));
return {
uniqueHeadCommits,
uniqueRemoteCommits,
};
}
return {
uniqueHeadCommits,
uniqueRemoteCommits,
};
}
export const isoGit = {
currentbranch,
remotes,
branches,
getCommitChanges,
compareBranches
}
export const isoGit = {
currentbranch,
remotes,
branches,
getCommitChanges,
compareBranches,
addIsomorphicGitProxyConfig,
push,
pull,
fetch,
getGitHubUser
}

@ -1,13 +1,13 @@
import { ReadBlobResult, ReadCommitResult } from "isomorphic-git";
import React from "react";
import { fileStatus, fileStatusMerge, setRemoteBranchCommits, resetRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog, setUserEmails, setCurrenHead } from "../state/gitpayload";
import { GitHubUser, gitActionDispatch, statusMatrixType, gitState, gitLog, fileStatusResult, userEmails } from '../types';
import { gitActionDispatch, statusMatrixType, gitState, gitLog, fileStatusResult } from '../types';
import { removeSlash } from "../utils";
import { disableCallBacks, enableCallBacks } from "./listeners";
import { ModalTypes } from "@remix-ui/app";
import { setFileDecorators } from "./pluginActions";
import { Plugin } from "@remixproject/engine";
import { addInputType, branch, branchDifference, checkoutInputType, cloneInputType, commitChange, CustomRemixApi, fetchInputType, pullInputType, pushInputType, remote, rmInputType } from "@remix-api";
import { addInputType, branch, branchDifference, checkoutInputType, cloneInputType, commitChange, CustomRemixApi, fetchInputType, GitHubUser, pullInputType, pushInputType, remote, rmInputType, userEmails } from "@remix-api";
import { file } from "jszip";
export const fileStatuses = [

@ -1,6 +1,6 @@
import { ReadCommitResult } from "isomorphic-git"
import { fileStatusResult, GitHubUser, gitLog, userEmails } from "../types"
import { branch, branchDifference, commitChange, pagedCommits, remote, remoteBranch, repository } from '@remix-api'
import { fileStatusResult, gitLog } from "../types"
import { GitHubUser, branch, branchDifference, commitChange, pagedCommits, remote, remoteBranch, repository, userEmails } from '@remix-api'
export interface ActionPayloadTypes {
FILE_STATUS: fileStatusResult[],
FILE_STATUS_MERGE: fileStatusResult[]

@ -1,6 +1,6 @@
import { ReadCommitResult } from "isomorphic-git"
import { GitHubUser, fileStatusResult, gitLog, userEmails } from "../types"
import { repository, pagedCommits, branch, remote, commitChange, branchDifference } from "@remix-api"
import { fileStatusResult, gitLog } from "../types"
import { repository, pagedCommits, branch, remote, commitChange, branchDifference, GitHubUser, userEmails } from "@remix-api"
export const fileStatus = (files: fileStatusResult[]) => {
return {

@ -1,8 +1,6 @@
import { Endpoints } from "@octokit/types"
import { branch, branchDifference, commitChange, pagedCommits, remote, remoteBranch, repository, syncStatus } from "@remix-api"
import { GitHubUser, branch, branchDifference, commitChange, pagedCommits, remote, remoteBranch, repository, syncStatus, userEmails } from "@remix-api"
import { ReadCommitResult } from "isomorphic-git"
export type GitHubUser = Partial<Endpoints["GET /user"]["response"]['data']>
export type userEmails = Endpoints["GET /user/emails"]["response"]["data"]
export type gitState = {
currentBranch: branch

Loading…
Cancel
Save