diff --git a/spec/project-spec.js b/spec/project-spec.js index 2d38058fe..e7601253c 100644 --- a/spec/project-spec.js +++ b/spec/project-spec.js @@ -969,6 +969,67 @@ describe('Project', () => { }) }) + describe('.observeRepositories()', () => { + it('invokes the observer with current and future repositories', () => { + const observed = [] + + const directory1 = temp.mkdirSync('git-repo1') + const gitDirPath1 = fs.absolute(path.join(__dirname, 'fixtures', 'git', 'master.git')) + fs.copySync(gitDirPath1, path.join(directory1, '.git')) + + const directory2 = temp.mkdirSync('git-repo2') + const gitDirPath2 = fs.absolute(path.join(__dirname, 'fixtures', 'git', 'repo-with-submodules', 'git.git')) + fs.copySync(gitDirPath2, path.join(directory2, '.git')) + + atom.project.setPaths([directory1]) + + const disposable = atom.project.observeRepositories((repo) => observed.push(repo)) + expect(observed.length).toBe(1) + expect(observed[0].getReferenceTarget('refs/heads/master')).toBe('ef046e9eecaa5255ea5e9817132d4001724d6ae1') + + atom.project.addPath(directory2) + expect(observed.length).toBe(2) + expect(observed[1].getReferenceTarget('refs/heads/master')).toBe('d2b0ad9cbc6f6c4372e8956e5cc5af771b2342e5') + + disposable.dispose() + }) + }) + + describe('.onDidAddRepository()', () => { + it('invokes callback when a path is added and the path is the root of a repository', () => { + const observed = [] + const disposable = atom.project.onDidAddRepository((repo) => observed.push(repo)) + + const repositoryPath = path.join(__dirname, '..') + atom.project.addPath(repositoryPath) + expect(observed.length).toBe(1) + expect(observed[0].getOriginURL()).toContain('atom/atom') + + disposable.dispose() + }) + + it('invokes callback when a path is added and the path is subdirectory of a repository', () => { + const observed = [] + const disposable = atom.project.onDidAddRepository((repo) => observed.push(repo)) + + atom.project.addPath(__dirname) + expect(observed.length).toBe(1) + expect(observed[0].getOriginURL()).toContain('atom/atom') + + disposable.dispose() + }) + + it('does not invoke callback when a path is added and the path is not part of a repository', () => { + const observed = [] + const disposable = atom.project.onDidAddRepository((repo) => observed.push(repo)) + + atom.project.addPath(temp.mkdirSync('not-a-repository')) + expect(observed.length).toBe(0) + + disposable.dispose() + }) + }) + describe('.relativize(path)', () => { it('returns the path, relative to whichever root directory it is inside of', () => { atom.project.addPath(temp.mkdirSync('another-path')) diff --git a/src/project.js b/src/project.js index 4e51efcf8..8ccf60c0b 100644 --- a/src/project.js +++ b/src/project.js @@ -234,6 +234,38 @@ class Project extends Model { return this.emitter.on('did-change-files', callback) } + // Public: Invoke the given callback with all current and future + // repositories in the project. + // + // * `callback` {Function} to be called with current and future + // repositories. + // * `repository` A {GitRepository} that is present at the time of + // subscription or that is added at some later time. + // + // Returns a {Disposable} on which `.dispose()` can be called to + // unsubscribe. + observeRepositories (callback) { + for (const repo of this.repositories) { + if (repo != null) { + callback(repo) + } + } + + return this.onDidAddRepository(callback) + } + + // Public: Invoke the given callback when a repository is added to the + // project. + // + // * `callback` {Function} to be called when a repository is added. + // * `repository` A {GitRepository}. + // + // Returns a {Disposable} on which `.dispose()` can be called to + // unsubscribe. + onDidAddRepository (callback) { + return this.emitter.on('did-add-repository', callback) + } + /* Section: Accessing the git repository */ @@ -400,6 +432,9 @@ class Project extends Model { if (repo) { break } } this.repositories.push(repo != null ? repo : null) + if (repo != null) { + this.emitter.emit('did-add-repository', repo) + } if (options.emitEvent !== false) { this.emitter.emit('did-change-paths', this.getPaths())