Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Setup Studio module #4943

Merged
merged 3 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 17 additions & 103 deletions extension/src/setup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { WebviewMessages } from './webview/messages'
import { validateTokenInput } from './inputBox'
import { findPythonBinForInstall } from './autoInstall'
import { run, runWithRecheck, runWorkspace } from './runner'
import { isStudioAccessToken } from './token'
import { Studio } from './studio'
import {
PYTHON_EXTENSION_ACTION,
pickFocusedProjects,
Expand Down Expand Up @@ -51,13 +51,7 @@ import { createFileSystemWatcher } from '../fileSystem/watcher'
import { EventName } from '../telemetry/constants'
import { WorkspaceScale } from '../telemetry/collect'
import { gitPath } from '../cli/git/constants'
import {
Flag,
ConfigKey,
DOT_DVC,
Args,
SubCommand
} from '../cli/dvc/constants'
import { DOT_DVC, Args, SubCommand } from '../cli/dvc/constants'
import { GLOBAL_WEBVIEW_DVCROOT } from '../webview/factory'
import { getValidInput } from '../vscode/inputBox'
import { Title } from '../vscode/title'
Expand Down Expand Up @@ -87,6 +81,7 @@ export class Setup
private readonly config: Config
private readonly status: Status
private readonly internalCommands: InternalCommands
private readonly studio: Studio

private readonly webviewMessages: WebviewMessages
private readonly getHasData: () => boolean | undefined
Expand Down Expand Up @@ -117,10 +112,6 @@ export class Setup

private dotFolderWatcher?: Disposer

private studioAccessToken: string | undefined = undefined
private studioIsConnected = false
private shareLiveToStudio: boolean | undefined = undefined

private focusedSection: SetupSection | undefined = undefined

constructor(
Expand Down Expand Up @@ -160,6 +151,12 @@ export class Setup
this.setCommandsAvailability(false)
this.setProjectAvailability()

this.studio = new Studio(
internalCommands,
this.studioConnectionChanged,
julieg18 marked this conversation as resolved.
Show resolved Hide resolved
() => this.getCwd()
)

this.webviewMessages = this.createWebviewMessageHandler()

void this.sendDataToWebview()
Expand Down Expand Up @@ -311,34 +308,12 @@ export class Setup
}
}

public async removeStudioAccessToken() {
public removeStudioAccessToken() {
if (!this.getCliCompatible()) {
return
}

if (this.dvcRoots.length !== 1) {
const cwd = getFirstWorkspaceFolder()
if (!cwd) {
return
}
return await this.accessConfig(
cwd,
Flag.GLOBAL,
Flag.UNSET,
ConfigKey.STUDIO_TOKEN
)
}

const cwd = this.dvcRoots[0]

await this.accessConfig(cwd, Flag.LOCAL, Flag.UNSET, ConfigKey.STUDIO_TOKEN)

return await this.accessConfig(
cwd,
Flag.GLOBAL,
Flag.UNSET,
ConfigKey.STUDIO_TOKEN
)
return this.studio.removeStudioAccessToken(this.dvcRoots)
}

public async saveStudioAccessToken() {
Expand All @@ -357,12 +332,12 @@ export class Setup
return
}

await this.accessConfig(cwd, Flag.GLOBAL, ConfigKey.STUDIO_TOKEN, token)
await this.studio.saveStudioAccessTokenInConfig(cwd, token)
return this.updateStudioAndSend()
}

public getStudioAccessToken() {
return this.studioAccessToken
return this.studio.getStudioAccessToken()
}

public sendInitialWebviewData() {
Expand Down Expand Up @@ -438,14 +413,14 @@ export class Setup
isPythonEnvironmentGlobal,
isPythonExtensionInstalled: this.config.isPythonExtensionInstalled(),
isPythonExtensionUsed,
isStudioConnected: this.studioIsConnected,
isStudioConnected: this.studio.getStudioIsConnected(),
needsGitCommit,
needsGitInitialized,
projectInitialized,
pythonBinPath: getBinDisplayText(pythonBinPath),
remoteList,
sectionCollapsed: collectSectionCollapsed(this.focusedSection),
shareLiveToStudio: !!this.shareLiveToStudio
shareLiveToStudio: !!this.studio.getShareLiveToStudio()
})
this.focusedSection = undefined
}
Expand All @@ -454,7 +429,7 @@ export class Setup
const webviewMessages = new WebviewMessages(
() => this.getWebview(),
() => this.initializeGit(),
(offline: boolean) => this.updateStudioOffline(offline),
(offline: boolean) => this.studio.updateStudioOffline(offline),
() => this.isPythonExtensionUsed(),
() => this.updatePythonEnvironment()
)
Expand Down Expand Up @@ -707,18 +682,10 @@ export class Setup
}

private async updateStudioAndSend() {
await this.updateIsStudioConnected()
await this.studio.updateIsStudioConnected()
return this.sendDataToWebview()
}

private async updateIsStudioConnected() {
await this.setStudioValues()
const storedToken = this.getStudioAccessToken()
const isConnected = isStudioAccessToken(storedToken)
this.studioIsConnected = isConnected
return setContextValue(ContextKey.STUDIO_CONNECTED, isConnected)
}

private watchDvcConfigs() {
const createWatcher = (watchedPath: string) =>
createFileSystemWatcher(
Expand Down Expand Up @@ -760,51 +727,6 @@ export class Setup
])
}

private async setStudioValues() {
const cwd = this.getCwd()

const previousStudioAccessToken = this.studioAccessToken

if (!cwd) {
this.studioAccessToken = undefined
this.shareLiveToStudio = undefined

if (previousStudioAccessToken) {
this.studioConnectionChanged.fire()
}
return
}

const [studioAccessToken, shareLiveToStudio] = await Promise.all([
this.accessConfig(cwd, ConfigKey.STUDIO_TOKEN),
(await this.accessConfig(cwd, ConfigKey.STUDIO_OFFLINE)) !== 'true'
])

this.studioAccessToken = studioAccessToken
this.shareLiveToStudio = shareLiveToStudio

if (previousStudioAccessToken !== this.studioAccessToken) {
this.studioConnectionChanged.fire()
}
}

private async updateStudioOffline(shareLive: boolean) {
const offline = !shareLive

const cwd = this.getCwd()

if (!cwd) {
return
}

await this.accessConfig(
cwd,
Flag.GLOBAL,
ConfigKey.STUDIO_OFFLINE,
String(offline)
)
}

private getCwd() {
if (!this.getCliCompatible()) {
return
Expand All @@ -814,14 +736,6 @@ export class Setup
: getFirstWorkspaceFolder()
}

private accessConfig(cwd: string, ...args: Args) {
return this.internalCommands.executeCommand(
AvailableCommands.CONFIG,
cwd,
...args
)
}

private accessRemote(cwd: string, ...args: Args) {
return this.internalCommands.executeCommand(
AvailableCommands.REMOTE,
Expand Down
129 changes: 129 additions & 0 deletions extension/src/setup/studio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { EventEmitter } from 'vscode'
import { isStudioAccessToken } from './token'
julieg18 marked this conversation as resolved.
Show resolved Hide resolved
import { AvailableCommands, InternalCommands } from '../commands/internal'
import { getFirstWorkspaceFolder } from '../vscode/workspaceFolders'
import { Args, ConfigKey, Flag } from '../cli/dvc/constants'
import { ContextKey, setContextValue } from '../vscode/context'

export class Studio {
protected studioConnectionChanged: EventEmitter<void>
private studioAccessToken: string | undefined = undefined
private studioIsConnected = false
private shareLiveToStudio: boolean | undefined = undefined
private readonly getCwd: () => string | undefined
private readonly internalCommands: InternalCommands
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class would be handling token requests and responses when we implement Studio token authentication.


constructor(
internalCommands: InternalCommands,
studioConnectionChanged: EventEmitter<void>,
getCwd: () => string | undefined
) {
this.internalCommands = internalCommands
this.studioConnectionChanged = studioConnectionChanged
this.getCwd = getCwd
}

public getStudioAccessToken() {
return this.studioAccessToken
}

public getStudioIsConnected() {
return this.studioIsConnected
}

public getShareLiveToStudio() {
return this.shareLiveToStudio
}

public async removeStudioAccessToken(dvcRoots: string[]) {
if (dvcRoots.length !== 1) {
const cwd = getFirstWorkspaceFolder()
if (!cwd) {
return
}

return await this.accessConfig(
cwd,
Flag.GLOBAL,
Flag.UNSET,
ConfigKey.STUDIO_TOKEN
)
}

const cwd = dvcRoots[0]

await this.accessConfig(cwd, Flag.LOCAL, Flag.UNSET, ConfigKey.STUDIO_TOKEN)

return await this.accessConfig(
cwd,
Flag.GLOBAL,
Flag.UNSET,
ConfigKey.STUDIO_TOKEN
)
}

public saveStudioAccessTokenInConfig(cwd: string, token: string) {
return this.accessConfig(cwd, Flag.GLOBAL, ConfigKey.STUDIO_TOKEN, token)
}

public async updateIsStudioConnected() {
await this.setStudioValues()
const storedToken = this.getStudioAccessToken()
const isConnected = isStudioAccessToken(storedToken)
this.studioIsConnected = isConnected
return setContextValue(ContextKey.STUDIO_CONNECTED, isConnected)
}

public async updateStudioOffline(shareLive: boolean) {
const offline = !shareLive

const cwd = this.getCwd()

if (!cwd) {
return
}

await this.accessConfig(
cwd,
Flag.GLOBAL,
ConfigKey.STUDIO_OFFLINE,
String(offline)
)
}

private async setStudioValues() {
const cwd = this.getCwd()

const previousStudioAccessToken = this.studioAccessToken

if (!cwd) {
this.studioAccessToken = undefined
this.shareLiveToStudio = undefined

if (previousStudioAccessToken) {
this.studioConnectionChanged.fire()
}
return
}

const [studioAccessToken, shareLiveToStudio] = await Promise.all([
this.accessConfig(cwd, ConfigKey.STUDIO_TOKEN),
(await this.accessConfig(cwd, ConfigKey.STUDIO_OFFLINE)) !== 'true'
])

this.studioAccessToken = studioAccessToken
this.shareLiveToStudio = shareLiveToStudio

if (previousStudioAccessToken !== this.studioAccessToken) {
this.studioConnectionChanged.fire()
}
}

private accessConfig(cwd: string, ...args: Args) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

return this.internalCommands.executeCommand(
AvailableCommands.CONFIG,
cwd,
...args
)
}
}
Loading