This repository has been archived by the owner on Apr 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 111
WIP Make Che use multi root workspaces by default #408
Closed
JPinkney
wants to merge
8
commits into
eclipse-che:master
from
JPinkney:workspace_roots_che_on_master
Closed
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
17aab3a
Add workspaces module
tsmaeder d182e37
fix version
78f8d2c
Register update workspace command
tsmaeder df83e2f
Add to workspace on clone
tsmaeder 8bba0e8
Make add folder command handle multiple uris
tsmaeder ce91740
Use single command to update workspace
tsmaeder 2eb142d
Ensure open file is visible
tsmaeder f537906
Start theia using projects.theia-workspace
JPinkney File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"folders": [], | ||
"settings": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
conf | ||
lib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "@eclipse-che/theia-workspace", | ||
"keywords": [ | ||
"theia-extension", | ||
"workspace" | ||
], | ||
"version": "0.0.1", | ||
"description": "Eclipse Che - Workspace Menu", | ||
"dependencies": { | ||
"@theia/core": "^0.8.0", | ||
"@theia/workspace": "^0.8.0" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"theiaExtensions": [ | ||
{ | ||
"frontend": "lib/browser/workspace-frontend-module" | ||
} | ||
], | ||
"license": "EPL-2.0", | ||
"files": [ | ||
"lib", | ||
"src", | ||
"scripts", | ||
"conf" | ||
], | ||
"scripts": { | ||
"prepare": "yarn run clean && yarn run build", | ||
"clean": "rimraf lib", | ||
"format": "tsfmt -r --useTsfmt ../../configs/tsfmt.json", | ||
"lint": "tslint -c ../../configs/tslint.json --project tsconfig.json", | ||
"compile": "tsc", | ||
"build": "concurrently -n \"format,lint,compile\" -c \"red,green,blue\" \"yarn format\" \"yarn lint\" \"yarn compile\"", | ||
"watch": "tsc -w", | ||
"publish:next": "yarn publish --registry=https://registry.npmjs.org/ --no-git-tag-version --new-version 0.0.1-\"$(date +%s)\"" | ||
}, | ||
"devDependencies": {} | ||
} |
97 changes: 97 additions & 0 deletions
97
extensions/eclipse-che-theia-workspace/src/browser/workspace-frontend-contribution.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2017 TypeFox and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
import { injectable, inject } from 'inversify'; | ||
import { CommandContribution, CommandRegistry, MenuContribution, MenuModelRegistry } from '@theia/core/lib/common'; | ||
import { | ||
CommonMenus, LabelProvider, KeybindingRegistry, KeybindingContribution | ||
} from '@theia/core/lib/browser'; | ||
import { WorkspaceCommands, WorkspaceService } from '@theia/workspace/lib/browser'; | ||
import { ContextKeyService } from '@theia/core/lib/browser/context-key-service'; | ||
import URI from '@theia/core/lib/common/uri'; | ||
|
||
@injectable() | ||
export class WorkspaceFrontendContribution implements CommandContribution, KeybindingContribution, MenuContribution { | ||
|
||
@inject(LabelProvider) protected readonly labelProvider: LabelProvider; | ||
@inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry; | ||
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; | ||
|
||
@inject(ContextKeyService) | ||
protected readonly contextKeyService: ContextKeyService; | ||
|
||
registerCommands(commands: CommandRegistry): void { | ||
// Not visible/enabled on Windows/Linux in electron. | ||
commands.unregisterCommand(WorkspaceCommands.OPEN); | ||
// Visible/enabled only on Windows/Linux in electron. | ||
commands.unregisterCommand(WorkspaceCommands.OPEN_FOLDER); | ||
commands.unregisterCommand(WorkspaceCommands.OPEN_RECENT_WORKSPACE); | ||
commands.unregisterCommand(WorkspaceCommands.CLOSE); | ||
commands.unregisterCommand(WorkspaceCommands.OPEN_RECENT_WORKSPACE); | ||
commands.unregisterCommand(WorkspaceCommands.SAVE_WORKSPACE_AS); | ||
|
||
commands.registerCommand({ | ||
id: 'che.workspace.addFolder' | ||
}, { | ||
execute: async (uris: URI[]) => await this.workspaceService.spliceRoots(0, 0, ...uris) | ||
}); | ||
} | ||
|
||
registerMenus(menus: MenuModelRegistry): void { | ||
menus.unregisterMenuAction({ | ||
commandId: WorkspaceCommands.OPEN.id, | ||
}, CommonMenus.FILE_OPEN); | ||
menus.unregisterMenuAction({ | ||
commandId: WorkspaceCommands.OPEN_FOLDER.id | ||
}); | ||
menus.unregisterMenuAction({ | ||
commandId: WorkspaceCommands.OPEN_WORKSPACE.id | ||
}); | ||
menus.unregisterMenuAction({ | ||
commandId: WorkspaceCommands.OPEN_RECENT_WORKSPACE.id | ||
}); | ||
menus.unregisterMenuAction({ | ||
commandId: WorkspaceCommands.SAVE_WORKSPACE_AS.id | ||
}); | ||
menus.unregisterMenuAction({ | ||
commandId: WorkspaceCommands.CLOSE.id | ||
}); | ||
menus.registerMenuAction(CommonMenus.FILE_OPEN, { | ||
commandId: WorkspaceCommands.OPEN_FILE.id, | ||
label: `${WorkspaceCommands.OPEN_FILE.dialogLabel}...`, | ||
order: 'a01' | ||
}); | ||
} | ||
|
||
registerKeybindings(keybindings: KeybindingRegistry): void { | ||
keybindings.unregisterKeybinding({ | ||
command: WorkspaceCommands.OPEN.id, | ||
keybinding: 'ctrlcmd+alt+o', | ||
}); | ||
keybindings.unregisterKeybinding({ | ||
command: WorkspaceCommands.OPEN_FOLDER.id, | ||
keybinding: 'ctrl+k ctrl+o', | ||
}); | ||
keybindings.unregisterKeybinding({ | ||
command: WorkspaceCommands.OPEN_WORKSPACE.id, | ||
keybinding: 'ctrlcmd+alt+w', | ||
}); | ||
keybindings.unregisterKeybinding({ | ||
command: WorkspaceCommands.OPEN_RECENT_WORKSPACE.id, | ||
keybinding: 'ctrlcmd+alt+r', | ||
}); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
extensions/eclipse-che-theia-workspace/src/browser/workspace-frontend-module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2019 Red Hat, Inc. | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
**********************************************************************/ | ||
|
||
import { ContainerModule } from 'inversify'; | ||
import { WorkspaceFrontendContribution } from './workspace-frontend-contribution'; | ||
import { CommandContribution } from '@theia/core/lib/common/command'; | ||
import { KeybindingContribution } from '@theia/core/lib/browser/keybinding'; | ||
import { MenuContribution } from '@theia/core/lib/common/menu'; | ||
|
||
export default new ContainerModule((bind, unbind, isBound, rebind) => { | ||
|
||
bind(WorkspaceFrontendContribution).toSelf().inSingletonScope(); | ||
for (const identifier of [CommandContribution, KeybindingContribution, MenuContribution]) { | ||
bind(identifier).toService(WorkspaceFrontendContribution); | ||
} | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"extends": "../../configs/base.tsconfig.json", | ||
"compilerOptions": { | ||
"lib": [ | ||
"es6", | ||
"dom" | ||
], | ||
"rootDir": "src", | ||
"outDir": "lib" | ||
}, | ||
"include": [ | ||
"src" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ import * as theia from '@theia/plugin'; | |
import { che as cheApi } from '@eclipse-che/api'; | ||
import * as fileuri from './file-uri'; | ||
import * as git from './git'; | ||
import * as fs from 'fs'; | ||
|
||
const CHE_TASK_TYPE = 'che'; | ||
|
||
|
@@ -31,7 +32,7 @@ function isDevfileProjectConfig(project: cheApi.workspace.ProjectConfig | cheApi | |
export class TheiaCloneCommand { | ||
|
||
private locationURI: string | undefined; | ||
private folder: string; | ||
private _folder: string; | ||
private checkoutBranch?: string | undefined; | ||
private checkoutTag?: string | undefined; | ||
private checkoutStartPoint?: string | undefined; | ||
|
@@ -46,7 +47,7 @@ export class TheiaCloneCommand { | |
} | ||
|
||
this.locationURI = source.location; | ||
this.folder = project.clonePath ? path.join(projectsRoot, project.clonePath) : path.join(projectsRoot, project.name); | ||
this._folder = project.clonePath ? path.join(projectsRoot, project.clonePath) : path.join(projectsRoot, project.name); | ||
this.checkoutBranch = source.branch; | ||
this.checkoutStartPoint = source.startPoint; | ||
this.checkoutTag = source.tag; | ||
|
@@ -59,7 +60,7 @@ export class TheiaCloneCommand { | |
const parameters = project.source.parameters; | ||
|
||
this.locationURI = project.source.location; | ||
this.folder = projectsRoot + project.path; | ||
this._folder = projectsRoot + project.path; | ||
this.checkoutBranch = parameters['branch']; | ||
this.checkoutStartPoint = parameters['startPoint']; | ||
this.checkoutTag = project.source.parameters['tag']; | ||
|
@@ -68,13 +69,13 @@ export class TheiaCloneCommand { | |
this.projectsRoot = projectsRoot; | ||
} | ||
|
||
execute(): PromiseLike<void> { | ||
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 don't see any good reasons to rename |
||
clone(): PromiseLike<void> { | ||
if (!this.locationURI) { | ||
return new Promise(() => { }); | ||
} | ||
|
||
const clone = async (progress: theia.Progress<{ message?: string; increment?: number }>, token: theia.CancellationToken): Promise<void> => { | ||
const args: string[] = ['clone', this.locationURI, this.folder]; | ||
const args: string[] = ['clone', this.locationURI, this._folder]; | ||
if (this.checkoutBranch) { | ||
args.push('--branch'); | ||
args.push(this.checkoutBranch); | ||
|
@@ -90,15 +91,15 @@ export class TheiaCloneCommand { | |
: (this.checkoutTag ? this.checkoutTag : this.checkoutCommitId); | ||
|
||
const branch = this.checkoutBranch ? this.checkoutBranch : 'default branch'; | ||
const messageStart = `Project ${this.locationURI} cloned to ${this.folder} and checked out ${branch}`; | ||
const messageStart = `Project ${this.locationURI} cloned to ${this._folder} and checked out ${branch}`; | ||
|
||
if (treeish) { | ||
git.execGit(this.folder, 'reset', '--hard', treeish) | ||
git.execGit(this._folder, 'reset', '--hard', treeish) | ||
.then(_ => { | ||
theia.window.showInformationMessage(`${messageStart} which has been reset to ${treeish}.`); | ||
}, e => { | ||
theia.window.showErrorMessage(`${messageStart} but resetting to ${treeish} failed with ${e.message}.`); | ||
console.log(`Couldn't reset to ${treeish} of ${this.folder} cloned from ${this.locationURI} and checked out to ${branch}.`, e); | ||
console.log(`Couldn't reset to ${treeish} of ${this._folder} cloned from ${this.locationURI} and checked out to ${branch}.`, e); | ||
}); | ||
} else { | ||
theia.window.showInformationMessage(`${messageStart}.`); | ||
|
@@ -109,12 +110,29 @@ export class TheiaCloneCommand { | |
} | ||
}; | ||
|
||
return theia.window.withProgress({ | ||
location: theia.ProgressLocation.Notification, | ||
title: `Cloning ${this.locationURI} ...` | ||
}, (progress, token) => clone(progress, token)); | ||
if (!fs.existsSync(this._folder)) { | ||
return theia.window.withProgress({ | ||
location: theia.ProgressLocation.Notification, | ||
title: `Cloning ${this.locationURI} ...` | ||
}, (progress, token) => clone(progress, token)); | ||
} | ||
return Promise.resolve(); | ||
} | ||
|
||
isInTheiaWorkspace(): boolean { | ||
for (let i = 0; i < theia.workspace.workspaceFolders.length; i++) { | ||
const wsFolder = theia.workspace.workspaceFolders[i]; | ||
|
||
if (wsFolder && fs.realpathSync(wsFolder.uri.fsPath) === fs.realpathSync(this._folder)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
get folder(): string { | ||
return this._folder; | ||
} | ||
} | ||
|
||
export class TheiaCommand { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,8 +8,6 @@ | |
* SPDX-License-Identifier: EPL-2.0 | ||
**********************************************************************/ | ||
|
||
import * as path from 'path'; | ||
import * as fs from 'fs'; | ||
import { TheiaCloneCommand } from './theia-commands'; | ||
import * as git from './git'; | ||
import * as projectsHelper from './projects'; | ||
|
@@ -41,11 +39,6 @@ abstract class WorkspaceProjectsManager { | |
abstract deleteProject(workspace: cheApi.workspace.Workspace, projectFolderURI: string): void; | ||
|
||
async run(workspace?: cheApi.workspace.Workspace) { | ||
if (!theia.workspace.name) { | ||
// no workspace opened, so nothing to clone / watch | ||
return; | ||
} | ||
|
||
if (!workspace) { | ||
workspace = await che.workspace.getCurrentWorkspace(); | ||
} | ||
|
@@ -61,9 +54,16 @@ abstract class WorkspaceProjectsManager { | |
} | ||
|
||
theia.window.showInformationMessage('Che Workspace: Starting cloning projects.'); | ||
const workspaceFolders: theia.Uri[] = []; | ||
await Promise.all( | ||
cloneCommandList.map(cloneCommand => cloneCommand.execute()) | ||
cloneCommandList.map(cloneCommand => { | ||
if (!cloneCommand.isInTheiaWorkspace()) { | ||
workspaceFolders.push(theia.Uri.file(cloneCommand.folder)); | ||
} | ||
return cloneCommand.clone(); | ||
}) | ||
); | ||
await theia.commands.executeCommand('che.workspace.addFolder', workspaceFolders); | ||
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. same comments i had for factory-initializer
You see here you are duplicating code. |
||
theia.window.showInformationMessage('Che Workspace: Finished cloning projects.'); | ||
} | ||
|
||
|
@@ -126,10 +126,6 @@ export class DevfileProjectsManager extends WorkspaceProjectsManager { | |
} | ||
|
||
return projects | ||
.filter(project => { | ||
const projectPath = project.clonePath ? path.join(instance.projectsRoot, project.clonePath) : path.join(instance.projectsRoot, project.name); | ||
return !fs.existsSync(projectPath); | ||
}) | ||
.map(project => new TheiaCloneCommand(project, instance.projectsRoot)); | ||
} | ||
|
||
|
@@ -170,7 +166,6 @@ export class WorkspaceConfigProjectsManager extends WorkspaceProjectsManager { | |
} | ||
|
||
return projects | ||
.filter(project => !fs.existsSync(instance.projectsRoot + project.path)) | ||
.map(project => new TheiaCloneCommand(project, instance.projectsRoot)); | ||
} | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
cloneCommand.execute ?
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.
I am not in favor of having logic implementations here. It should go to the command implementation.