From 9fddf4ee7037acfebd2a92d75f49311fbb27074f Mon Sep 17 00:00:00 2001 From: Matt Seddon Date: Mon, 24 May 2021 11:52:59 +1000 Subject: [PATCH 1/5] move creation of sets inline --- extension/src/Repository/index.ts | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/extension/src/Repository/index.ts b/extension/src/Repository/index.ts index 70a153ecf8..e1dc48171e 100644 --- a/extension/src/Repository/index.ts +++ b/extension/src/Repository/index.ts @@ -36,21 +36,12 @@ export class RepositoryState implements DecorationState, SourceControlManagementState { public dispose = Disposable.fn() - public tracked: Set - public deleted: Set - public modified: Set - public new: Set - public notInCache: Set - public untracked: Set - - constructor() { - this.tracked = new Set() - this.deleted = new Set() - this.modified = new Set() - this.new = new Set() - this.notInCache = new Set() - this.untracked = new Set() - } + public tracked: Set = new Set() + public deleted: Set = new Set() + public modified: Set = new Set() + public new: Set = new Set() + public notInCache: Set = new Set() + public untracked: Set = new Set() } export class Repository { From 53f43553c116887f9e4a32b7cfb264d9c1f85b2a Mon Sep 17 00:00:00 2001 From: Matt Seddon Date: Mon, 24 May 2021 12:00:12 +1000 Subject: [PATCH 2/5] move updateTracked inside of class --- extension/src/Repository/index.test.ts | 14 +++--- extension/src/Repository/index.ts | 61 +++++++++++++++----------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/extension/src/Repository/index.test.ts b/extension/src/Repository/index.test.ts index 6888fbe344..dd49e768e0 100644 --- a/extension/src/Repository/index.test.ts +++ b/extension/src/Repository/index.test.ts @@ -175,7 +175,7 @@ describe('Repository', () => { { path: model } ] as ListOutput[]) - expect(repository.getState()).toEqual(new RepositoryState()) + expect(repository.getState()).toEqual(new RepositoryState(dvcRoot)) await repository.resetState() @@ -204,11 +204,12 @@ describe('Repository', () => { ) expect(repository.getState()).toEqual({ + dvcRoot, + deleted, dispose: Disposable.fn(), - new: emptySet, modified: emptySet, + new: emptySet, notInCache: emptySet, - deleted, tracked, untracked: emptySet }) @@ -272,7 +273,7 @@ describe('Repository', () => { ]) mockedGetAllUntracked.mockResolvedValueOnce(untracked) - expect(repository.getState()).toEqual(new RepositoryState()) + expect(repository.getState()).toEqual(new RepositoryState(dvcRoot)) await repository.resetState() @@ -303,11 +304,12 @@ describe('Repository', () => { ) expect(repository.getState()).toEqual({ + deleted, dispose: Disposable.fn(), - new: new Set(), + dvcRoot, modified, + new: new Set(), notInCache, - deleted, tracked, untracked }) diff --git a/extension/src/Repository/index.ts b/extension/src/Repository/index.ts index e1dc48171e..11cddc1d22 100644 --- a/extension/src/Repository/index.ts +++ b/extension/src/Repository/index.ts @@ -7,7 +7,7 @@ import { } from './views/SourceControlManagement' import { DecorationProvider, DecorationState } from './DecorationProvider' import { Deferred } from '@hediet/std/synchronization' -import { status, listDvcOnlyRecursive } from '../cli/reader' +import { status, listDvcOnlyRecursive, ListOutput } from '../cli/reader' import { dirname, join } from 'path' import { observable, makeObservable } from 'mobx' import { getExecutionOptions } from '../cli/execution' @@ -36,12 +36,43 @@ export class RepositoryState implements DecorationState, SourceControlManagementState { public dispose = Disposable.fn() + private dvcRoot: string + public tracked: Set = new Set() public deleted: Set = new Set() public modified: Set = new Set() public new: Set = new Set() public notInCache: Set = new Set() public untracked: Set = new Set() + + private filterRootDir(dirs: string[] = []) { + return dirs.filter(dir => dir !== this.dvcRoot) + } + + private getAbsolutePath(files: string[] = []): string[] { + return files.map(file => join(this.dvcRoot, file)) + } + + private getAbsoluteParentPath(files: string[] = []): string[] { + return this.filterRootDir( + files.map(file => join(this.dvcRoot, dirname(file))) + ) + } + + public updateTracked(listOutput: ListOutput[]): void { + const trackedPaths = listOutput.map(tracked => tracked.path) + + const absoluteTrackedPaths = this.getAbsolutePath(trackedPaths) + + this.tracked = new Set([ + ...absoluteTrackedPaths, + ...this.getAbsoluteParentPath(trackedPaths) + ]) + } + + constructor(dvcRoot: string) { + this.dvcRoot = dvcRoot + } } export class Repository { @@ -70,31 +101,11 @@ export class Repository { private decorationProvider?: DecorationProvider private sourceControlManagement: SourceControlManagement - private filterRootDir(dirs: string[] = []) { - return dirs.filter(dir => dir !== this.dvcRoot) - } - - private getAbsolutePath(files: string[] = []): string[] { - return files.map(file => join(this.dvcRoot, file)) - } - - private getAbsoluteParentPath(files: string[] = []): string[] { - return this.filterRootDir( - files.map(file => join(this.dvcRoot, dirname(file))) - ) - } - - public async updateList(): Promise { + private async updateTracked(): Promise { const options = getExecutionOptions(this.config, this.dvcRoot) const listOutput = await listDvcOnlyRecursive(options) - const trackedPaths = listOutput.map(tracked => tracked.path) - - const absoluteTrackedPaths = this.getAbsolutePath(trackedPaths) - this.state.tracked = new Set([ - ...absoluteTrackedPaths, - ...this.getAbsoluteParentPath(trackedPaths) - ]) + this.state.updateTracked(listOutput) } private getChangedOutsStatuses( @@ -162,7 +173,7 @@ export class Repository { public async resetState() { const statusesUpdated = this.updateStatuses() - const slowerTrackedUpdated = this.updateList() + const slowerTrackedUpdated = this.updateTracked() await statusesUpdated this.sourceControlManagement.setState(this.state) @@ -195,7 +206,7 @@ export class Repository { this.config = config this.decorationProvider = decorationProvider this.dvcRoot = dvcRoot - this.state = this.dispose.track(new RepositoryState()) + this.state = this.dispose.track(new RepositoryState(dvcRoot)) this.sourceControlManagement = this.dispose.track( new SourceControlManagement(this.dvcRoot, this.state) From 31b4199d0cb58971d3cd6a81d1090578e1724464 Mon Sep 17 00:00:00 2001 From: Matt Seddon Date: Mon, 24 May 2021 12:02:15 +1000 Subject: [PATCH 3/5] move updateUntracked inside of repository state --- extension/src/Repository/index.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/extension/src/Repository/index.ts b/extension/src/Repository/index.ts index 11cddc1d22..e0ad7d5bb3 100644 --- a/extension/src/Repository/index.ts +++ b/extension/src/Repository/index.ts @@ -70,6 +70,10 @@ export class RepositoryState ]) } + public updateUntracked(untracked: Set): void { + this.untracked = untracked + } + constructor(dvcRoot: string) { this.dvcRoot = dvcRoot } @@ -162,8 +166,9 @@ export class Repository { this.state.notInCache = status['not in cache'] || new Set() } - public async updateUntracked() { - this.state.untracked = await getAllUntracked(this.dvcRoot) + private async updateUntracked() { + const untracked = await getAllUntracked(this.dvcRoot) + this.state.updateUntracked(untracked) } private updateStatuses() { From 4d03f3ca554af22cd8c518d41834e5dcd7c70924 Mon Sep 17 00:00:00 2001 From: Matt Seddon Date: Mon, 24 May 2021 12:05:34 +1000 Subject: [PATCH 4/5] move updateStatus inside of repository state --- extension/src/Repository/index.ts | 98 +++++++++++++++---------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/extension/src/Repository/index.ts b/extension/src/Repository/index.ts index e0ad7d5bb3..c0e31b61ec 100644 --- a/extension/src/Repository/index.ts +++ b/extension/src/Repository/index.ts @@ -59,6 +59,53 @@ export class RepositoryState ) } + private getChangedOutsStatuses( + fileOrStage: StatusesOrAlwaysChanged[] + ): PathStatus[] { + return fileOrStage + .map(entry => (entry as StageOrFileStatuses)?.[ChangedType.CHANGED_OUTS]) + .filter(value => value) + } + + private reduceStatuses( + reducedStatus: Partial>>, + statuses: PathStatus[] + ) { + return statuses.map(entry => + Object.entries(entry).map(([relativePath, status]) => { + const absolutePath = join(this.dvcRoot, relativePath) + const existingPaths = reducedStatus[status] || new Set() + reducedStatus[status] = existingPaths.add(absolutePath) + }) + ) + } + + private reduceToChangedOutsStatuses( + filteredStatusOutput: StatusOutput + ): Partial>> { + const statusReducer = ( + reducedStatus: Partial>>, + entry: StatusesOrAlwaysChanged[] + ): Partial>> => { + const statuses = this.getChangedOutsStatuses(entry) + + this.reduceStatuses(reducedStatus, statuses) + + return reducedStatus + } + + return Object.values(filteredStatusOutput).reduce(statusReducer, {}) + } + + public updateStatus(statusOutput: StatusOutput) { + const status = this.reduceToChangedOutsStatuses(statusOutput) + + this.modified = status.modified || new Set() + this.deleted = status.deleted || new Set() + this.new = status.new || new Set() + this.notInCache = status['not in cache'] || new Set() + } + public updateTracked(listOutput: ListOutput[]): void { const trackedPaths = listOutput.map(tracked => tracked.path) @@ -112,58 +159,11 @@ export class Repository { this.state.updateTracked(listOutput) } - private getChangedOutsStatuses( - fileOrStage: StatusesOrAlwaysChanged[] - ): PathStatus[] { - return fileOrStage - .map(entry => (entry as StageOrFileStatuses)?.[ChangedType.CHANGED_OUTS]) - .filter(value => value) - } - - private reduceStatuses( - reducedStatus: Partial>>, - statuses: PathStatus[] - ) { - return statuses.map(entry => - Object.entries(entry).map(([relativePath, status]) => { - const absolutePath = join(this.dvcRoot, relativePath) - const existingPaths = reducedStatus[status] || new Set() - reducedStatus[status] = existingPaths.add(absolutePath) - }) - ) - } - - private reduceToChangedOutsStatuses( - filteredStatusOutput: StatusOutput - ): Partial>> { - const statusReducer = ( - reducedStatus: Partial>>, - entry: StatusesOrAlwaysChanged[] - ): Partial>> => { - const statuses = this.getChangedOutsStatuses(entry) - - this.reduceStatuses(reducedStatus, statuses) - - return reducedStatus - } - - return Object.values(filteredStatusOutput).reduce(statusReducer, {}) - } - - private async getStatus(): Promise>>> { + private async updateStatus() { const options = getExecutionOptions(this.config, this.dvcRoot) const statusOutput = (await status(options)) as StatusOutput - return this.reduceToChangedOutsStatuses(statusOutput) - } - - public async updateStatus() { - const status = await this.getStatus() - - this.state.modified = status.modified || new Set() - this.state.deleted = status.deleted || new Set() - this.state.new = status.new || new Set() - this.state.notInCache = status['not in cache'] || new Set() + this.state.updateStatus(statusOutput) } private async updateUntracked() { From 955878cfb2c125619442ffac778e9dc38627d92f Mon Sep 17 00:00:00 2001 From: Matt Seddon Date: Mon, 24 May 2021 12:14:54 +1000 Subject: [PATCH 5/5] add getState method to state --- extension/src/Repository/index.test.ts | 10 +++------- extension/src/Repository/index.ts | 27 ++++++++++++++++---------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/extension/src/Repository/index.test.ts b/extension/src/Repository/index.test.ts index dd49e768e0..49ff3f2f64 100644 --- a/extension/src/Repository/index.test.ts +++ b/extension/src/Repository/index.test.ts @@ -51,6 +51,7 @@ beforeEach(() => { describe('Repository', () => { const dvcRoot = resolve(__dirname, '..', '..', 'demo') + const emptyState = new RepositoryState(dvcRoot).getState() describe('ready', () => { it('should wait for the state to be ready before resolving', async () => { @@ -116,7 +117,6 @@ describe('Repository', () => { expect(repository.getState()).toEqual( expect.objectContaining({ - dispose: Disposable.fn(), deleted: emptySet, notInCache: emptySet, new: emptySet, @@ -175,7 +175,7 @@ describe('Repository', () => { { path: model } ] as ListOutput[]) - expect(repository.getState()).toEqual(new RepositoryState(dvcRoot)) + expect(repository.getState()).toEqual(emptyState) await repository.resetState() @@ -204,9 +204,7 @@ describe('Repository', () => { ) expect(repository.getState()).toEqual({ - dvcRoot, deleted, - dispose: Disposable.fn(), modified: emptySet, new: emptySet, notInCache: emptySet, @@ -273,7 +271,7 @@ describe('Repository', () => { ]) mockedGetAllUntracked.mockResolvedValueOnce(untracked) - expect(repository.getState()).toEqual(new RepositoryState(dvcRoot)) + expect(repository.getState()).toEqual(emptyState) await repository.resetState() @@ -305,8 +303,6 @@ describe('Repository', () => { expect(repository.getState()).toEqual({ deleted, - dispose: Disposable.fn(), - dvcRoot, modified, new: new Set(), notInCache, diff --git a/extension/src/Repository/index.ts b/extension/src/Repository/index.ts index c0e31b61ec..a5b970e3f6 100644 --- a/extension/src/Repository/index.ts +++ b/extension/src/Repository/index.ts @@ -38,11 +38,11 @@ export class RepositoryState private dvcRoot: string - public tracked: Set = new Set() public deleted: Set = new Set() public modified: Set = new Set() public new: Set = new Set() public notInCache: Set = new Set() + public tracked: Set = new Set() public untracked: Set = new Set() private filterRootDir(dirs: string[] = []) { @@ -121,6 +121,17 @@ export class RepositoryState this.untracked = untracked } + public getState() { + return { + deleted: this.deleted, + modified: this.modified, + new: this.new, + notInCache: this.notInCache, + tracked: this.tracked, + untracked: this.untracked + } + } + constructor(dvcRoot: string) { this.dvcRoot = dvcRoot } @@ -137,11 +148,7 @@ export class Repository { } public getState() { - return this.state - } - - public getTracked() { - return this.state.tracked + return this.state.getState() } @observable @@ -181,15 +188,15 @@ export class Repository { const slowerTrackedUpdated = this.updateTracked() await statusesUpdated - this.sourceControlManagement.setState(this.state) + this.sourceControlManagement.setState(this.state.getState()) await slowerTrackedUpdated - this.decorationProvider?.setState(this.state) + this.decorationProvider?.setState(this.state.getState()) } private setState() { - this.sourceControlManagement.setState(this.state) - this.decorationProvider?.setState(this.state) + this.sourceControlManagement.setState(this.state.getState()) + this.decorationProvider?.setState(this.state.getState()) } public async updateState() {