Skip to content

Commit 15893f7

Browse files
committed
Fix bad logic in GithubPackage#repositoryForProjectDirectory
If this function was called multiple times before the first call to Repository.open resolves, it ended up clobbering the cache, resulting in multiple Repository objects returned for the same working directory. Additionally, it depended on referential equality of the passed Directory object instead of the path of that Directory, causing different repos to be returned for Directories with the same working directory path.
1 parent 34c7236 commit 15893f7

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

lib/github-package.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,18 @@ export default class GithubPackage {
151151
}
152152

153153
async repositoryForProjectDirectory(projectDirectory) {
154-
let repository = this.repositoriesByProjectDirectory.get(projectDirectory);
154+
const projectDirectoryPath = projectDirectory.getPath()
155+
let repository = this.repositoriesByProjectDirectory.get(projectDirectoryPath);
155156
if (!repository) {
156157
repository = await Repository.open(projectDirectory);
157-
if (repository) { this.repositoriesByProjectDirectory.set(projectDirectory, repository); }
158+
if (this.repositoriesByProjectDirectory.has(projectDirectoryPath)) {
159+
// Someone else found and set the repo in the cache while we were nabbing it.
160+
// Defer to that repo.
161+
repository.destroy();
162+
repository = this.repositoriesByProjectDirectory.get(projectDirectoryPath);
163+
} else if (repository) {
164+
this.repositoriesByProjectDirectory.set(projectDirectoryPath, repository);
165+
}
158166
}
159167
return repository;
160168
}
@@ -164,11 +172,11 @@ export default class GithubPackage {
164172
}
165173

166174
destroyRepositoriesForRemovedProjectFolders() {
167-
const projectDirectories = this.project.getDirectories();
168-
for (const [projectDirectory, repository] of this.repositoriesByProjectDirectory) {
169-
if (projectDirectories.indexOf(projectDirectory) === -1) {
175+
const projectDirectoryPaths = this.project.getDirectories().map(dir => dir.getPath());
176+
for (const [projectDirectoryPath, repository] of this.repositoriesByProjectDirectory) {
177+
if (projectDirectoryPaths.indexOf(projectDirectoryPath) === -1) {
170178
repository.destroy();
171-
this.repositoriesByProjectDirectory.delete(projectDirectory);
179+
this.repositoriesByProjectDirectory.delete(projectDirectoryPath);
172180
}
173181
}
174182
}

test/github-package.test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/** @babel */
22

3+
import {Directory} from 'atom';
4+
35
import fs from 'fs';
46
import path from 'path';
57
import temp from 'temp';
68
import sinon from 'sinon';
9+
710
import {cloneRepository} from './helpers';
811
import GithubPackage from '../lib/github-package';
912

@@ -157,4 +160,27 @@ describe('GithubPackage', () => {
157160
assert.isNull(githubPackage.getActiveRepository());
158161
});
159162
});
163+
164+
describe('#repositoryForProjectDirectory', () => {
165+
it('returns the same repository over multiple overlapping calls', async () => {
166+
const workdirPath = await cloneRepository('three-files');
167+
const dir = new Directory(workdirPath);
168+
169+
const repo1 = githubPackage.repositoryForProjectDirectory(dir);
170+
const repo2 = githubPackage.repositoryForProjectDirectory(dir);
171+
172+
assert.equal(await repo1, await repo2);
173+
});
174+
175+
it('returns the same repository for different Directories with the same path', async () => {
176+
const workdirPath = await cloneRepository('three-files');
177+
const dir1 = new Directory(workdirPath);
178+
const dir2 = new Directory(workdirPath);
179+
180+
const repo1 = await githubPackage.repositoryForProjectDirectory(dir1);
181+
const repo2 = await githubPackage.repositoryForProjectDirectory(dir2);
182+
183+
assert.equal(repo1, repo2);
184+
});
185+
});
160186
});

0 commit comments

Comments
 (0)