Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit 129d5e7

Browse files
committed
Return a null object from the pool when a directory is not present
1 parent 1ec5774 commit 129d5e7

File tree

5 files changed

+189
-50
lines changed

5 files changed

+189
-50
lines changed

lib/github-package.js

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ export default class GithubPackage {
8383
this.workspace.addOpener(IssueishPaneItem.opener),
8484
);
8585

86-
this.deserialize(this.savedState);
87-
8886
this.rerender();
8987
}
9088

@@ -106,12 +104,6 @@ export default class GithubPackage {
106104
};
107105
}
108106

109-
async deserialize(state) {
110-
if (state.activeRepositoryPath) {
111-
await this.didChangeProjectPaths([state.activeRepositoryPath]);
112-
}
113-
}
114-
115107
@autobind
116108
rerender() {
117109
if (!this.element) {
@@ -207,44 +199,61 @@ export default class GithubPackage {
207199
return this.activeResolutionProgress;
208200
}
209201

210-
async scheduleActiveModelUpdate() {
211-
await this.activeModelQueue.push(this.updateActiveModels, {parallel: false});
202+
async scheduleActiveModelUpdate(isActivating = false) {
203+
await this.activeModelQueue.push(this.updateActiveModels.bind(this, isActivating), {parallel: false});
212204
}
213205

214-
@autobind
215-
async updateActiveModels() {
216-
let nextActiveRepository = null;
217-
let nextActiveResolutionProgress = null;
218-
let nextActiveProjectPath = null;
206+
async updateActiveModels(isActivating = false) {
207+
let foundActiveModels = false;
208+
209+
let nextActiveRepository = this.activeRepository;
210+
let nextActiveResolutionProgress = this.activeResolutionProgress;
211+
let nextActiveProjectPath = this.activeProjectPath;
212+
213+
const setByProjectPath = async projectPath => {
214+
if (!projectPath) {
215+
return;
216+
}
217+
218+
nextActiveProjectPath = projectPath;
219+
nextActiveRepository = await this.getRepositoryForWorkdirPath(nextActiveProjectPath);
220+
nextActiveResolutionProgress = await this.getResolutionProgressForWorkdirPath(nextActiveProjectPath);
221+
222+
foundActiveModels = true;
223+
};
219224

220225
const activeItem = this.workspace.getActivePaneItem();
221-
if (activeItem && typeof activeItem.getPath === 'function') {
222-
const projectPath = this.projectPathForItemPath(activeItem.getPath());
223-
if (projectPath) {
224-
nextActiveProjectPath = projectPath;
225-
await Promise.all([
226-
this.getRepositoryForWorkdirPath(projectPath).then(r => { nextActiveRepository = r; }),
227-
this.getResolutionProgressForWorkdirPath(projectPath).then(rp => { nextActiveResolutionProgress = rp; }),
228-
]);
226+
227+
if (activeItem) {
228+
if (typeof activeItem.getRepository === 'function') {
229+
// FilePatchController or other GitHub package pane
230+
const repository = activeItem.getRepository();
231+
if (!repository.isDestroyed()) {
232+
nextActiveRepository = repository;
233+
nextActiveResolutionProgress = this.props.activeResolutionProgress;
234+
nextActiveProjectPath = this.props.activeProjectPath;
235+
236+
foundActiveModels = true;
237+
}
238+
239+
} else if (typeof activeItem.getPath === 'function') {
240+
// TextEditor-like
241+
const projectPath = this.projectPathForItemPath(activeItem.getPath());
242+
await setByProjectPath(projectPath);
229243
}
230-
} else {
231-
nextActiveRepository = this.activeRepository;
232-
nextActiveResolutionProgress = this.activeResolutionProgress;
233-
nextActiveProjectPath = this.activeProjectPath;
234244
}
235245

236-
if (activeItem instanceof FilePatchController) {
237-
if (!activeItem.getRepository().isDestroyed()) {
238-
nextActiveRepository = activeItem.props.repository;
239-
nextActiveResolutionProgress = activeItem.props.resolutionProgress;
240-
nextActiveProjectPath = nextActiveRepository.getWorkingDirectoryPath();
241-
}
246+
if (!foundActiveModels && this.project.getPaths().length === 1) {
247+
// Single project
248+
await setByProjectPath(this.project.getPaths()[0]);
242249
}
243250

244-
if (!activeItem && this.project.getPaths().length === 1) {
245-
nextActiveProjectPath = this.project.getPaths()[0];
246-
nextActiveRepository = await this.getRepositoryForWorkdirPath(nextActiveProjectPath);
247-
nextActiveResolutionProgress = await this.getResolutionProgressForWorkdirPath(nextActiveProjectPath);
251+
if (!foundActiveModels && isActivating) {
252+
// Restore models from saved state
253+
if (this.savedState.activeRepositoryPath) {
254+
const projectPath = this.projectPathForItemPath(this.savedState.activeRepositoryPath);
255+
await setByProjectPath(projectPath);
256+
}
248257
}
249258

250259
this.setActiveModels(nextActiveProjectPath, nextActiveRepository, nextActiveResolutionProgress);

lib/models/workdir-context-pool.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import compareSets from 'compare-sets';
22

3-
import WorkdirContext from './workdir-context';
3+
import WorkdirContext, {nullWorkdirContext} from './workdir-context';
44

55
/**
66
* Manage a WorkdirContext for each open directory.
@@ -24,7 +24,7 @@ export default class WorkdirContextPool {
2424
* Access the context mapped to a known directory.
2525
*/
2626
getContext(directory) {
27-
return this.contexts.get(directory);
27+
return this.contexts.get(directory) || nullWorkdirContext;
2828
}
2929

3030
add(directory, options = {}) {

lib/models/workdir-context.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ export default class WorkdirContext {
113113
]);
114114
}
115115

116+
isPresent() {
117+
return true;
118+
}
119+
116120
isDestroyed() {
117121
return this.destroyed;
118122
}
@@ -170,3 +174,27 @@ export default class WorkdirContext {
170174
}
171175
}
172176
}
177+
178+
class NullWorkdirContext extends WorkdirContext {
179+
constructor() {
180+
super(null, {});
181+
182+
this.repositoryHolder.setValue(null);
183+
this.changeObserverHolder.setValue(null);
184+
this.resolutionProgressHolder.setValue(null);
185+
}
186+
187+
create() {
188+
return Promise.resolve();
189+
}
190+
191+
isPresent() {
192+
return false;
193+
}
194+
195+
destroy() {
196+
return Promise.resolve();
197+
}
198+
}
199+
200+
export const nullWorkdirContext = new NullWorkdirContext();

test/github-package.test.js

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,94 @@ describe('GithubPackage', function() {
6464
}
6565

6666
describe('activate()', function() {
67-
it('updates the active repository', async function() {
67+
it('uses models from preexisting projects', async function() {
68+
const workdirPath1 = await cloneRepository('three-files');
69+
const workdirPath2 = await cloneRepository('three-files');
70+
project.setPaths([workdirPath1, workdirPath2]);
71+
72+
await githubPackage.activate();
73+
74+
await assert.async.isNotNull(await githubPackage.getRepositoryForWorkdirPath(workdirPath1));
75+
await assert.async.isNotNull(await githubPackage.getRepositoryForWorkdirPath(workdirPath2));
76+
assert.isNull(githubPackage.getActiveRepository());
77+
});
78+
79+
it('uses an active model from a single preexisting project', async function() {
80+
const workdirPath = await cloneRepository('three-files');
81+
project.setPaths([workdirPath]);
82+
6883
await githubPackage.activate();
84+
85+
await assert.async.isNotNull(githubPackage.getActiveRepository());
86+
assert.equal(
87+
await githubPackage.getActiveRepository().getWorkingDirectoryPath(),
88+
workdirPath,
89+
);
90+
});
91+
92+
it('uses an active model from a preexisting active pane item', async function() {
6993
const workdirPath1 = await cloneRepository('three-files');
7094
const workdirPath2 = await cloneRepository('three-files');
7195
project.setPaths([workdirPath1, workdirPath2]);
72-
fs.writeFileSync(path.join(workdirPath1, 'a.txt'), 'change 1', 'utf8');
73-
fs.writeFileSync(path.join(workdirPath1, 'b.txt'), 'change 2', 'utf8');
96+
await workspace.open(path.join(workdirPath2, 'a.txt'));
7497

75-
await workspace.open(path.join(workdirPath1, 'a.txt'));
76-
const repository = await githubPackage.getRepositoryForWorkdirPath(workdirPath1);
77-
await until(() => githubPackage.getActiveRepository() === repository);
98+
await githubPackage.activate();
99+
100+
await assert.async.isNotNull(githubPackage.getActiveRepository());
101+
assert.equal(
102+
await githubPackage.getActiveRepository().getWorkingDirectoryPath(),
103+
workdirPath2,
104+
);
105+
});
106+
107+
it('uses an active model from serialized state', async function() {
108+
const workdirPath1 = await cloneRepository('three-files');
109+
const workdirPath2 = await cloneRepository('three-files');
110+
const workdirPath3 = await cloneRepository('three-files');
111+
project.setPaths([workdirPath1, workdirPath2, workdirPath3]);
112+
113+
await githubPackage.activate({
114+
activeRepositoryPath: workdirPath2,
115+
});
116+
117+
await assert.async.isNotNull(githubPackage.getActiveRepository());
118+
assert.equal(
119+
await githubPackage.getActiveRepository().getWorkingDirectoryPath(),
120+
workdirPath2,
121+
);
122+
});
123+
124+
it('prefers the active model from an active pane item to serialized state', async function() {
125+
const workdirPath1 = await cloneRepository('three-files');
126+
const workdirPath2 = await cloneRepository('three-files');
127+
project.setPaths([workdirPath1, workdirPath2]);
128+
await workspace.open(path.join(workdirPath2, 'b.txt'));
129+
130+
await githubPackage.activate({
131+
activeRepositoryPath: workdirPath1,
132+
});
133+
134+
await assert.async.isNotNull(githubPackage.getActiveRepository());
135+
assert.equal(
136+
await githubPackage.getActiveRepository().getWorkingDirectoryPath(),
137+
workdirPath2,
138+
);
139+
});
140+
141+
it('prefers the active model from a single project to serialized state', async function() {
142+
const workdirPath1 = await cloneRepository('three-files');
143+
const workdirPath2 = await cloneRepository('three-files');
144+
project.setPaths([workdirPath1]);
145+
146+
await githubPackage.activate({
147+
activeRepositoryPath: workdirPath2,
148+
});
149+
150+
await assert.async.isNotNull(githubPackage.getActiveRepository());
151+
assert.equal(
152+
await githubPackage.getActiveRepository().getWorkingDirectoryPath(),
153+
workdirPath1,
154+
);
78155
});
79156
});
80157

test/models/workdir-context-pool.test.js

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ describe('WorkdirContextPool', function() {
2828

2929
it('adds a WorkdirContext for a new working directory', function() {
3030
assert.equal(pool.size(), 0);
31-
assert.isUndefined(pool.getContext(workingDirectory));
31+
assert.isFalse(pool.getContext(workingDirectory).isPresent());
3232

3333
pool.add(workingDirectory);
3434

3535
assert.equal(pool.size(), 1);
36-
assert.isDefined(pool.getContext(workingDirectory));
36+
assert.isTrue(pool.getContext(workingDirectory).isPresent());
3737
});
3838

3939
it('optionally provides a preinitialized repository', async function() {
@@ -50,7 +50,7 @@ describe('WorkdirContextPool', function() {
5050
assert.equal(pool.size(), 1);
5151

5252
const context = pool.getContext(workingDirectory);
53-
assert.isDefined(context);
53+
assert.isTrue(context.isPresent());
5454

5555
pool.add(workingDirectory);
5656
assert.equal(pool.size(), 1);
@@ -79,7 +79,7 @@ describe('WorkdirContextPool', function() {
7979
it('removes a WorkdirContext for an existing working directory', function() {
8080
assert.equal(pool.size(), 1);
8181
pool.remove(existingDirectory);
82-
assert.isUndefined(pool.getContext(existingDirectory));
82+
assert.isFalse(pool.getContext(existingDirectory).isPresent());
8383
assert.equal(pool.size(), 0);
8484
});
8585

@@ -122,9 +122,34 @@ describe('WorkdirContextPool', function() {
122122

123123
assert.equal(pool.size(), 2);
124124

125+
assert.isFalse(pool.getContext(dir0).isPresent());
126+
assert.isTrue(pool.getContext(dir1).isPresent());
127+
assert.isTrue(pool.getContext(dir2).isPresent());
128+
125129
assert.isTrue(context0.isDestroyed());
126130
assert.isFalse(context1.isDestroyed());
127-
assert.isDefined(pool.getContext(dir2));
131+
});
132+
});
133+
134+
describe('getContext', function() {
135+
let dir;
136+
137+
beforeEach(async function() {
138+
dir = await cloneRepository('three-files');
139+
pool.add(dir);
140+
});
141+
142+
it('returns a context by directory', async function() {
143+
const context = pool.getContext(dir);
144+
assert.isTrue(context.isPresent());
145+
146+
const repo = await context.getRepositoryPromise();
147+
assert.strictEqual(dir, repo.getWorkingDirectoryPath());
148+
});
149+
150+
it('returns a null context when missing', function() {
151+
const context = pool.getContext('/nope');
152+
assert.isFalse(context.isPresent());
128153
});
129154
});
130155
});

0 commit comments

Comments
 (0)