Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b212aab
Let's do some nodegits
BinaryMuse Feb 15, 2017
f064145
Use nodegit for GSOS#getStatusesForChangedFiles
kuychaco Feb 16, 2017
cfd9b49
Only select item in staging view when clicked or dragged over
kuychaco Feb 16, 2017
4049b12
:shirt:
BinaryMuse Feb 16, 2017
49a2fce
Convert GSOS#getRemotes to nodegit
Feb 16, 2017
3c02de8
Ensure tooltip is closed if showing when component unmounts
Feb 16, 2017
79a90fe
Add `firstImplementer` helper
Feb 18, 2017
82e2932
Revert GSOS to original (pre-nodegit) form
Feb 18, 2017
2a8d23a
Allow an AsyncQueue to be injected into GSOS
Feb 18, 2017
7085c7e
Implement set/getOwnPropertyDescriptor/getPrototypeOf in firstImpementer
Feb 18, 2017
99dbc5a
Extract Nodegit strategy
Feb 18, 2017
a0be11e
Use CompositeGitStrategy as default strategy
Feb 18, 2017
14c9cbe
Convert GSOS tests to generic strategies test
Feb 18, 2017
57887e3
sdescribe(cmd, desc) -> forCommand(cmd).describe(desc)
Feb 22, 2017
d1b156c
Return assignment from Proxy `set`
Feb 22, 2017
c0d2b1d
Make getRemotes test work independent of order
Feb 22, 2017
0443f6a
Redirect ALL methods that exist on the strategy under test to that st…
Feb 22, 2017
cac1741
Show non-implemented strategy tests as pending
Feb 22, 2017
72b1d00
:art:
Feb 22, 2017
3d0ec93
:fire: .only
Feb 22, 2017
2bc7061
:art:
Feb 22, 2017
1495e5a
Ensure proper returns from firstImplementer
Feb 22, 2017
75f1e81
Always test every method on every strategy
Feb 22, 2017
313300c
Only test gpgExec on strategies where it actually exists
Feb 22, 2017
450b0ca
Implement getPrototypeOf in firstImplementer correctly
Feb 23, 2017
2ab6105
Change the way strategies get tested
BinaryMuse Feb 23, 2017
410525c
:art:
Feb 23, 2017
68d7995
Drop the nodegit strategy like a hot potato 🍠
Feb 23, 2017
d588ec2
Merge remote-tracking branch 'origin/master' into mkt-composite-git-s…
Feb 23, 2017
6611be9
:shirt:
Feb 23, 2017
c840e26
:art:
Feb 23, 2017
84b6575
:fire: unused code
Feb 23, 2017
d50cce6
Be more specific with firstImplementer tests
Feb 23, 2017
17308d3
Use reduceRight to produce correct prototype
Feb 23, 2017
40d9a6f
Test firstImplementer set and getOwnPropertyDescriptor
Feb 23, 2017
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
22 changes: 22 additions & 0 deletions lib/composite-git-strategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os from 'os';

import {firstImplementer} from './helpers';
import AsyncQueue from './async-queue';
import GitShellOutStrategy from './git-shell-out-strategy';

export default {
create(workingDir, options = {}) {
return this.withStrategies([GitShellOutStrategy])(workingDir, options);
},

withStrategies(strategies) {
return function createForStrategies(workingDir, options = {}) {
const parallelism = options.parallelism || Math.max(3, os.cpus().length);
const commandQueue = new AsyncQueue({parallelism});
const strategyOptions = {...options, queue: commandQueue};

const strategyInstances = strategies.map(Strategy => new Strategy(workingDir, strategyOptions));
return firstImplementer(...strategyInstances);
};
},
};
9 changes: 7 additions & 2 deletions lib/git-shell-out-strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@ export default class GitShellOutStrategy {

constructor(workingDir, options = {}) {
this.workingDir = workingDir;
const parallelism = options.parallelism || Math.max(3, os.cpus().length);
this.commandQueue = new AsyncQueue({parallelism});
if (options.queue) {
this.commandQueue = options.queue;
} else {
const parallelism = options.parallelism || Math.max(3, os.cpus().length);
this.commandQueue = new AsyncQueue({parallelism});
}

}

// Execute a command and read the output using the embedded Git environment
Expand Down
62 changes: 62 additions & 0 deletions lib/helpers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,68 @@
import fs from 'fs-extra';
import {ncp} from 'ncp';


function descriptorsFromProto(proto) {
return Object.getOwnPropertyNames(proto).reduce((acc, name) => {
Object.assign(acc, {
[name]: Reflect.getOwnPropertyDescriptor(proto, name),
});
return acc;
}, {});
}

/**
* Takes an array of targets and returns a proxy. The proxy intercepts property accessor calls and
* returns the value of that property on the first object in `targets` where the target implements that property.
*/
export function firstImplementer(...targets) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This isn't nearly as scary as you made it sound 😉

return new Proxy({__implementations: targets}, {
get(target, name) {
if (Reflect.has(target, name)) {
return target[name];
}

const firstValidTarget = targets.find(t => Reflect.has(t, name));
if (firstValidTarget) {
return firstValidTarget[name];
} else {
return undefined;
}
},

set(target, name, value) {
const firstValidTarget = targets.find(t => Reflect.has(t, name));
if (firstValidTarget) {
// eslint-disable-next-line no-return-assign
return firstValidTarget[name] = value;
} else {
// eslint-disable-next-line no-return-assign
return target[name] = value;
}
},

// Used by sinon
getOwnPropertyDescriptor(target, name) {
const firstValidTarget = targets.find(t => Reflect.getOwnPropertyDescriptor(t, name));
const compositeOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor(target, name);
if (firstValidTarget) {
return Reflect.getOwnPropertyDescriptor(firstValidTarget, name);
} else if (compositeOwnPropertyDescriptor) {
return compositeOwnPropertyDescriptor;
} else {
return undefined;
}
},

// Used by sinon
getPrototypeOf(target) {
return targets.reduceRight((acc, t) => {
return Object.create(acc, descriptorsFromProto(Object.getPrototypeOf(t)));
}, Object.prototype);
},
});
}

export function readFile(absoluteFilePath, encoding = 'utf8') {
return new Promise((resolve, reject) => {
fs.readFile(absoluteFilePath, encoding, (err, contents) => {
Expand Down
4 changes: 2 additions & 2 deletions lib/models/repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from 'path';
import {Emitter, Disposable} from 'atom';
import {autobind} from 'core-decorators';

import GitShellOutStrategy from '../git-shell-out-strategy';
import CompositeGitStrategy from '../composite-git-strategy';
import FilePatch from './file-patch';
import Hunk from './hunk';
import HunkLine from './hunk-line';
Expand Down Expand Up @@ -33,7 +33,7 @@ export class CommitError extends Error {

export default class Repository {
static async open(workingDirectoryPath, gitStrategy) {
const strategy = gitStrategy || new GitShellOutStrategy(workingDirectoryPath);
const strategy = gitStrategy || CompositeGitStrategy.create(workingDirectoryPath);
if (await strategy.isGitRepository()) {
const historySha = await strategy.getConfig('atomGithub.historySha');
const history = historySha ? JSON.parse(await strategy.getBlobContents(historySha)) : {};
Expand Down
12 changes: 10 additions & 2 deletions lib/views/git-timings-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,19 @@ class MarkerSpan extends React.Component {
});
}

@autobind
handleMouseOut(e) {
closeTooltip() {
this.tooltipDisposable && this.tooltipDisposable.dispose();
this.tooltipDisposable = null;
}

@autobind
handleMouseOut(e) {
this.closeTooltip();
}

componentWillUnmount() {
this.closeTooltip();
}
}


Expand Down
Loading