From 7e2cf89153c257cd4d44b4d414c763cb947702d9 Mon Sep 17 00:00:00 2001 From: seeyoo <38161479+seeyoo@users.noreply.github.com> Date: Tue, 16 Jun 2020 16:05:00 +0800 Subject: [PATCH 1/2] Add user custom init script feature --- images/remote-workspace/initialize/index.js | 13 +++- package.json | 2 +- src/client/@components/workspace-form.tsx | 2 + src/client/@utils/index.ts | 1 + src/client/@utils/localStorage.ts | 14 ++++ src/client/@views/home-view.tsx | 74 +++++++++++++++++++-- src/shared/types/raw-workspace.ts | 4 ++ yarn.lock | 8 +-- 8 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 src/client/@utils/index.ts create mode 100644 src/client/@utils/localStorage.ts diff --git a/images/remote-workspace/initialize/index.js b/images/remote-workspace/initialize/index.js index e3cd549..4937e9f 100644 --- a/images/remote-workspace/initialize/index.js +++ b/images/remote-workspace/initialize/index.js @@ -13,13 +13,14 @@ const v = require('villa'); /** @type {import('../../../bld/shared').WorkspaceMetadata} */ // @ts-ignore -const {projects} = require('/root/workspace/metadata.json'); +const {projects, customInitScript} = require('/root/workspace/metadata.json'); main(async () => { // prepare projects console.info('Checking project hosts...'); + // #region SSH initialize let hostSet = new Set( projects .map(project => (project.git.url.match(/@(.+?):/) || [])[1]) @@ -59,7 +60,16 @@ main(async () => { ...process.env, GIT_SSH_COMMAND: 'ssh -i /root/.ssh/initialize-identity', }; + // #endregion + if (customInitScript) { + let scriptPath = `/root/workspace/custom-init-script.sh`; + console.info('Running user custom init script...'); + FSE.writeFileSync(scriptPath, customInitScript); + await spawn('bash', [scriptPath], {cwd: '/root/workspace/'}); + } + + // #region Per project initialize for (let { name, git: {url, branch = 'master', newBranch = branch}, @@ -142,6 +152,7 @@ main(async () => { }).catch(console.error); } } + // #endregion }); /** diff --git a/package.json b/package.json index e1c7c4a..6410796 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "ts-node": "^8.4.1", "tslib": "^1.10.0", "tslint": "^5.20.0", - "typescript": "^3.7.2", + "typescript": "^3.7.5", "typescript-tslint-plugin": "^0.5.4" } } diff --git a/src/client/@components/workspace-form.tsx b/src/client/@components/workspace-form.tsx index 3a93062..de08650 100644 --- a/src/client/@components/workspace-form.tsx +++ b/src/client/@components/workspace-form.tsx @@ -23,6 +23,7 @@ export interface WorkspaceFormProps { workspace: WorkspaceMetadata | undefined; defaultWorkspaceName?: string; defaultParams?: Dict; + customInitScript?: string; onSubmitSuccess(data: CreateWorkspaceOptions): void; } @@ -236,6 +237,7 @@ export class WorkspaceForm extends Component { owner: localStorage.email, projects: this.selectedProjectTemplates.map(({params, ...rest}) => rest), services: this.selectedServiceTemplates.map(({params, ...rest}) => rest), + customInitScript: this.props.customInitScript, }; options = _.cloneDeepWith(options, value => { diff --git a/src/client/@utils/index.ts b/src/client/@utils/index.ts new file mode 100644 index 0000000..3fcbe13 --- /dev/null +++ b/src/client/@utils/index.ts @@ -0,0 +1 @@ +export * from './localStorage'; diff --git a/src/client/@utils/localStorage.ts b/src/client/@utils/localStorage.ts new file mode 100644 index 0000000..d451c42 --- /dev/null +++ b/src/client/@utils/localStorage.ts @@ -0,0 +1,14 @@ +/** + * Save customize init script, set to empty or null to delete + */ +export function saveCustomInitScript(content: string): void { + if (content === null || content === '') { + localStorage.removeItem('customInitScript'); + } else { + localStorage.setItem('customInitScript', content); + } +} + +export function loadCustomInitScript(): string { + return localStorage.getItem('customInitScript') || ''; +} diff --git a/src/client/@views/home-view.tsx b/src/client/@views/home-view.tsx index dcc8dbe..852f8e4 100644 --- a/src/client/@views/home-view.tsx +++ b/src/client/@views/home-view.tsx @@ -1,13 +1,15 @@ -import {Checkbox, PageHeader} from 'antd'; +import {Button, Checkbox, Modal, PageHeader, message} from 'antd'; import {CheckboxChangeEvent} from 'antd/lib/checkbox'; +import TextArea from 'antd/lib/input/TextArea'; import {RouteComponentProps} from 'boring-router-react'; -import {observable} from 'mobx'; +import {computed, observable} from 'mobx'; import {observer} from 'mobx-react'; -import React, {Component, ReactNode, createRef} from 'react'; +import React, {ChangeEvent, Component, ReactNode, createRef} from 'react'; import {RawTemplatesConfig, WorkspaceMetadata} from '../../../bld/shared'; import {VersionInfo, WorkspaceForm, WorkspaceList} from '../@components'; import {WorkspaceRoute} from '../@routes'; +import {loadCustomInitScript, saveCustomInitScript} from '../@utils'; export interface HomeViewProps extends RouteComponentProps { @@ -30,6 +32,12 @@ export class HomeView extends Component { @observable private formKey = 0; + @observable + private toShowCustomizeModal = false; + + @observable + private customInitScriptContent = loadCustomInitScript(); + render(): ReactNode { let editingWorkspace = this.editingWorkspace; @@ -60,8 +68,18 @@ export class HomeView extends Component { cancel + editingWorkspace ? ( + + ) : ( + ) } /> @@ -71,12 +89,36 @@ export class HomeView extends Component { templates={this.templates} workspace={editingWorkspace} onSubmitSuccess={this.onWorkspaceFormSubmitSuccess} + customInitScript={this.customInitScriptContent} /> + {this.customizeModalRendering} ); } + @computed + get customizeModalRendering(): ReactNode { + return ( + +

+ Your personal customize script will be saved in browser storage. +
Supported syntx: bash +

+ +
+ ); + } + componentDidMount(): void { this.loadTemplates().catch(console.error); } @@ -103,6 +145,28 @@ export class HomeView extends Component { this.toShowAllWorkspaces = target.checked; }; + private onShowCustomizeModal = (): void => { + this.customInitScriptContent = loadCustomInitScript(); + this.toShowCustomizeModal = true; + }; + + private onSaveCustomizeSettings = (): void => { + this.toShowCustomizeModal = false; + saveCustomInitScript(this.customInitScriptContent); + + message.success('Saved'); + }; + + private onCloseCustomizeSettings = (): void => { + this.toShowCustomizeModal = false; + }; + + private onCustomInitScriptInputChange = ( + e: ChangeEvent, + ): void => { + this.customInitScriptContent = e.target.value; + }; + private async loadTemplates(): Promise { let response = await fetch('/api/templates'); let {data} = (await response.json()) as { diff --git a/src/shared/types/raw-workspace.ts b/src/shared/types/raw-workspace.ts index c7954b6..c02565b 100644 --- a/src/shared/types/raw-workspace.ts +++ b/src/shared/types/raw-workspace.ts @@ -21,6 +21,10 @@ export interface RawWorkspace { * editing. */ params?: Dict; + /** + * A script that allow user to customize their workspace at create or edit. + */ + customInitScript?: string; } export interface RawWorkspaceProjectGit { diff --git a/yarn.lock b/yarn.lock index d03220d..cdfab7d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6803,10 +6803,10 @@ typescript-tslint-plugin@^0.5.4: mock-require "^3.0.2" vscode-languageserver "^5.1.0" -typescript@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb" - integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ== +typescript@^3.7.5: + version "3.7.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" + integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== ua-parser-js@^0.7.18: version "0.7.20" From ce3e39176bc5659d01cc4374237136ee9140378e Mon Sep 17 00:00:00 2001 From: seeyoo <38161479+seeyoo@users.noreply.github.com> Date: Tue, 16 Jun 2020 16:23:06 +0800 Subject: [PATCH 2/2] Add .bld-cache to prettier ignore --- .prettierignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.prettierignore b/.prettierignore index 14446d0..ca134d4 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ **/bld/** +**/.bld-cache/** **/coverage/** **/.cache/** **/*-workdir/**