Commit Graph

614 Commits

Author SHA1 Message Date
Dandelion Mané 96d08dc97f
Detect a hardcoded list of bots (#718)
This commit adds a hardcoded list of known bots. Building on #713, it
categorizes those userlikes with the bot subtype. (Note that those users
may not be bots in the GitHub ontology - GitHub doesn't actually have a
clear record of which userlikes are bots.)

Progress towards #696.

Test plan:
Observe the single snapshot change, which demonstrates that @credbot is
now correctly categorized as a bot.
2018-08-29 15:01:48 -07:00
William Chargin 761b5a0875
Allow combining repositories at load time (#711)
Summary:
As a first pass toward support for analyzing whole organizations, we
allow loading multiple repositories with `sourcecred load`, combining
them into a single relational view and a single Git graph at load time.

Test Plan:
Run

```
node bin/sourcecred.js \
    load \
    sourcecred/example-git \
    sourcecred/example-github \
    sourcecred/sourcecred \
    --output sourcecred/examples \
    ;
```

and select `sourcecred/examples` from the web view. Filter “Repository”
nodes, and note that there are three.

Note that loading a single repository without `--output` still works,
that loading a single repository with `--output` still works (respecting
the alias name), and loading not exactly one repository without
`--output` yields an appropriate error message.

Note that `yarn sharness-full` still works.

wchargin-branch: load-combined
2018-08-29 14:52:26 -07:00
Dandelion Mané 2001d3a699
Update GitHub example data (#716)
I've added [a post by a bot]. Change generated by running:
```sh
src/plugins/github/fetchGithubRepoTest.sh -u
```

Test plan: `yarn travis --full` passes. Note that I properly re-archived the
GitHub repository.

Closes #714.

[a post by a bot]: https://github.com/sourcecred/example-github/issues/6#issuecomment-417104047
2018-08-29 14:24:00 -07:00
Dandelion Mané dda9c5feff
Subtype GitHub userlikes for Users and Bots (#713)
Userlikes now have an additional piece of data encoded in their address:
whether they are a USER or a BOT. Userlikes are still handled
identically by the RelationalView, which cuts down on code duplication.
I haven't added ORGANIZATIONs but it will be trivial to do once we're
interested in tracking them.

Note that this is basically the same as how we treat comments: comments
are subtyped to review comments, issue comments, and pull comments.

This is the initial step towards solving #696.

Test plan: Existing unit tests pass (and caught a few bugs during
development!). New test cases were added to the parser. Observe that all
the snapshot changes make sense.

Note: As of this commit, every GitHub userlike is classified as a user,
and the subtypes are not used in the application, so this commit causes
no change in observable behavior.
2018-08-29 14:00:22 -07:00
Dandelion Mané a5c909689a
Users have 1000 cred in aggregate (#709)
This commit changes the cred normalization algorithm so that the total
cred of all GitHub user nodes always sums to 1000. For rationale on the
change, see #705.

Fixes #705.

Note that this introduces a new way for PageRank to fail: if the
graph has no GitHub userlike nodes, then PageRank will throw an error
when it attempts to normalize. This will result in a message being
displayed to the user, and a more helpful error being printed to
console. If we need the cred explorer to display graphs that have no
userlike nodes, then we can modify the codepath so that it falls back to
normalizing based on all nodes instead of on the GitHub userlike nodes
specifically.

Test plan: There is an included unit test which verifies that the
new argument gets threaded through the state properly. But this is
mostly a config change, so it's best tested by actually inspecting
the cred explorer. I have done so, and can verify that the behavior is
as expected: the sum of users' cred now sums to 1000, and e.g. modifying
the weight on the repository node doesn't produce drastic changes to
cred scores.
2018-08-29 12:20:57 -07:00
Dandelion Mané 5b47c504b9
Implement scoreByConstantTotal (#708)
This commit adds the logic for computing scores so that the total score,
summed across all nodes matching a NodePrefix, is a fixed constant.

See #705 for context.

Test plan: The logic is quite simple, and adequate unit tests are
included.

Note to reviewer: There is a spurious whitespace diff in the test file
because the tests for the previous test block were not correctly scoped.
2018-08-29 12:03:31 -07:00
Dandelion Mané 3e77f486f2
Stop persisting users' weight choices (#706)
Storing the user's weights in localStore enables a workflow where a
user chooses their preferred weights, and brings those weights with them
across projects and contexts. However, this is the wrong workflow:
actually, a project chooses its weights, and when a user visits a
particular project, they want to sync up with the project's choice.
Giving the user the ability to modify the weights and recalculate is
still important, so that they can propose improvements to the project
maintainer. But implicitly keeping their modified weights, and even
bringing them to other projects the user inspects, is
counter-productive.

This commit removes this dubious feature. (It's a feature we were likely
to drop anyway, as it conflicts with #703.) As an added bonus, this code
is untested, which means the feature is technical debt—so removing it
reduces our technical debt! It also removes at least one known bug.

Test plan: There are no tests. I manually verified that the frontend
still works, and that it no longer persists weights across refresh.
2018-08-29 11:46:48 -07:00
Dandelion Mané 332915ae8a
Update README.md (#700)
The README has been brought up to date, and many small improvements were made. 
See #700 for details.

Test plan: Thoroughly reviewed.
2018-08-23 22:04:43 -07:00
William Chargin 66cf3b3aba
ensure-flow.sh: simplify, removing dep on GNU grep (#602)
Summary:
By using Git’s magic pathspecs instead of post-processing stream
operations, we reduce the pipeline to a single operation. Git implements
its own version of `grep`, so this should be platform-independent.
Previously, we had needed the `-z` argument to `grep(1)`, which is a GNU
extension.

Fixes #594.

Test Plan:
Ensure that the script passes with no output. Then,

```shell
mkdir -p src/flow-typed/
touch src/foo.js src/flow-typed.js src/flow-typed/foo.js
git add src/foo.js src/flow-typed.js src/flow-typed/foo.js
cd scripts
./ensure-flow.js
```

and ensure that script exits with code 1, empty stdout, and stderr with:

```
../src/flow-typed.js
../src/flow-typed/foo.js
../src/foo.js
```

This verifies that the pathspec is properly excluding the root directory
`flow-typed`, but not files that just happen to have `flow-typed` in
their paths.

wchargin-branch: simplify-ensure-flow
2018-08-22 11:44:20 -07:00
William Chargin 0c2908dbfb
Retry GitHub queries with exponential backoff (#699)
Summary:
This patch adds independent exponential backoff to each individual
GitHub GraphQL query. We remove the fixed `GITHUB_DELAY_MS` delay before
each query in favor of this solution, which requires no additional
configuration (thus resolving a TODO in the process).

We use the NPM module `retry` with its default settings: namely, a
maximum of 10 retries with factor-2 backoff starting at 1000ms.
Empirically, it seems very unlikely that we should require much more
than 2 retries for a query. (See Test Plan for more details.)

This is both a short-term unblocker and a good kind of thing to have in
the long term.

Test Plan:
Note that `yarn test --full` passes, including `fetchGithubRepoTest.sh`.
Consider manual testing as follows.

Add `console.info` statements in `retryGithubFetch`, then load a large
repository like TensorFlow, and observe the output:

```shell
$ node bin/sourcecred.js load --plugin github tensorflow/tensorflow 2>&1 | ts -s '%.s'
0.252566 Fetching repo...
0.258422 Trying...
5.203014 Trying...
[snip]
1244.521197 Trying...
1254.848044 Will retry (n=1)...
1260.893334 Trying...
1271.547368 Trying...
1282.094735 Will retry (n=1)...
1283.349192 Will retry (n=2)...
1289.188728 Trying...
[snip]
1741.026869 Ensuring no more pages...
1742.139978 Creating view...
1752.023697 Stringifying...
1754.697116 Writing...
1754.697772 Done.
```

This took just under half an hour, with 264 queries total, of which:
  - 225 queries required 0 retries;
  - 38 queries required exactly 1 retry;
  - 1 query required exactly 2 retries; and
  - 0 queries required 3 or more retries.

wchargin-branch: github-backoff
2018-08-22 11:37:29 -07:00
William Chargin d839fcae95
build_static_site.sh: create target if nonexistent (#695)
Summary:
The current version of the build script has the safe but annoying
property that the target directory must be an existing, empty directory.
It seems reasonable and convenient to allow the build script to create
the directory with `mkdir -p`. It still fails if the directory is not
empty or is a file.

Test Plan:
Unit tests updated; run `yarn sharness-full`.

wchargin-branch: build-mkdir-p
2018-08-21 15:35:13 -07:00
William Chargin 3216f5596e
Add `GitState`, `Environment` to the `VersionInfo` (#692)
Summary:
The version number displayed in the application now displays much more
specific information. It now lists the Git commit from which the build
was constructed, and will identify whether we have accidentally deployed
a development instance (which would be slow) or an instance with
uncommitted changes (which would be bad).

The version information is computed during the initialization of the
Webpack config. For development, this means that it is computed when you
run `yarn start`, and not updated thenafter. If the stale information
presents actual confusion, we would need to backport Webpack 4’s support
for runtime values in `DefinePlugin` to Webpack 3 (or upgrade Webpack
by a major version).

Test Plan:
The logic for `GitState` and `Environment` has existing tests. With both
a clean tree and a dirty tree, run `yarn start` and build the static
site, and check that the resulting versions are correct.

wchargin-branch: use-rich-version-types
2018-08-16 13:38:13 -07:00
William Chargin 01071866be
Add `GitState`, `Environment` types to `version` (#691)
Summary:
These types will shortly be added to the global `VersionInfo`. For now,
we include the types and validation logic only.

Test Plan:
Unit tests suffice.

wchargin-branch: add-rich-version-types
2018-08-16 13:28:29 -07:00
Dandelion Mané 2d28bd5de4
Re-introduce a simplified git plugin (#685)
This commit re-introduces the git plugin, now that it has been radically
simplified as described in [1]. The new git plugin only has nodes for
commits and only has commit has-parent edges. As compared to the version
that was removed in #628, this plugin is far leaner. It doesn't bloat
the graph (for `sourcecred/sourcecred`, the git plugin data is just
164k), and as such doesn't incur much performance penalty.

Re-incorporating the git plugin also brings some tangible benefits. We
already had git nodes in the graph, as the GitHub plugin attaches them
to pull requests. Without any git plugin, these nodes are displayed as
"uknown nodes" with ugly descriptions. Also, including a git plugin,
even one that is very minimal, communicates to users that git is a
source of information to SourceCred, and that they can expect more from
it in the future.

Note that this commit breaks backcompat for existing repositories that
were locally loaded after #628. As such, it is best to
`rm -rf $SOURCECRED_DIRECTORY` and start with fresh data. Also, due to a
known bug in the WeightConfig, you should reset your browser's local
storage.

Test plan: After removing the SourceCred directory and the stale
localStorage, the cred explorer nicely displays git commits, and
connects them via has_parent edges. The NodeType filter allows filtering
to commits as expected, and the WeightConfig shows node and edge weights
for the Git plugin's nodes and edges.

[1]: https://github.com/sourcecred/sourcecred/issues/627#issuecomment-413435447
2018-08-16 13:20:41 -07:00
Dandelion Mané 024ca3c262
Add `git/minimalPluginAdapter` (#690)
The minimal git plugin adapter only provides commit nodes and has_parent
edges. See #627 for context.

I forked this from `git/pluginAdapter.js`, and then deleted the
nodeTypes and edgeTypes which are no longer in scope.

Test plan: This is a fork of untested "glue" code, and is itself still
untested.
2018-08-16 12:13:42 -07:00
Dandelion Mané a460704ea8
Add `createMinimalGraph` for a tiny git graph (#689)
This implements the approach suggested in [1]. Instead of forking the
git plugin entirely, we'll fork the createGraph method and the
pluginAdapter so that we have instances that produce a lightweight git
graph.

createMinimalGraph is a fork of createGraph that only adds commit nodes
and has_parent edges. New unit tests ensure that only the whitelisted
nodes and edges appear.

Supersedes #683 and #684.

Test plan: `yarn test`

[1]: https://github.com/sourcecred/sourcecred/issues/627#issuecomment-413623784
2018-08-16 11:38:36 -07:00
William Chargin ae6e269d9d
Don’t pass through REACT_APP_* env vars (#688)
Summary:
We don’t use or want these. Injecting an arbitrary family of variables
from the client’s host environment seems like a Bad Idea.

Test Plan:
The usual `yarn start`, static site, and `yarn test --full` still work.

wchargin-branch: remove-reactapp-vars
2018-08-16 11:33:43 -07:00
William Chargin e531761a26
Simplify `getClientEnvironment` (#687)
Summary:
Cargo-culting `reduce` doesn’t make something “functional” or “good”;
forcing a `for`-loop into a `reduce` with impure callback is abhorrent.

Test Plan:
Into `config/stopship.js`, write:

```js
console.log(JSON.stringify(require("./env")()));
```

Then run `NODE_ENV=test node config/stopship.js` before and after this
commit and note that the output is identical.

wchargin-branch: simplify-getClientEnvironment
2018-08-16 11:27:37 -07:00
William Chargin c84a1c01e8
Remove remaining public URL logic (#686)
Summary:
Now that the main functionality of #643 has been implemented, we no
longer have any use for the “public URL” property. In fact, its presence
is actively harmful, as it suggests that the gateway may be known before
runtime, which is confusing and false.

Closes #643.

Test Plan:
Running `yarn start` works. Building the static site works.
Invoking `git grep -i 'public.\?url'` finds no matches.
Also, `yarn test --full` passes.

wchargin-branch: remove-public-url
2018-08-16 11:19:09 -07:00
Dandelion Mané ac8b9147c2
Cleanup unnecessary lint suppresions (#682)
We often construct case statements over union-typed variables, and then
in the default case, we use a `(type: empty)` assertion to ensure that
failing to account for all the cases results in a flow error.

In the past, we created an extra line for this assertion, which required
some eslint suppressions. We've realized it's cleaner to inline the type
assertion in the runtime error that we throw in these defaults.

This code cleans everything to the new style, and removes every existing
`// no-unused-expressions` invocation in the codebase.

Test plan: `yarn test`
2018-08-16 11:15:00 -07:00
Dandelion Mané f1afd5a248
Reverse the order of CHANGELOG entries (#681)
It's more consistent to prepend entries to the [Unreleased] section of
the changelog, so that entries are all in reverse-chronological order.
Since we've appended the first few entries, we reverse them now.

Test plan: Not needed
2018-08-16 11:14:52 -07:00
Dandelion Mané e68fe19487
Rename cred explorer table columns (#680)
The 'Score' column is renamed to 'Cred' (and its prop is renamed as
well). The column which shows how a connection or aggregation
contributes to a node's cred, as a percentage, has been rendered
nameless. It is pretty self explanatory, and the previous name
("Connection") was meaningless.

Test plan: Unit tests, also I inspected the frontend.
2018-08-15 22:22:21 -07:00
Dandelion Mané cdb76d15a6
Display version string in the app's footer (#677)
Some CSS magic was required.
Also creates `src/app/version.js` for storing the version string.

Test plan: Visual inspection of the footer in both Chrome and Firefox,
both on a page with very little content (the cred explorer without a
repository loaded), and on a page with more than a screen height's of
content (the homepage, or cred explorer with a large repository loaded).
In all cases, the footer unobtrusively appears in the lower-left hand
corner at the bottom of the screen, (after scrolling past all content,
if applicable).
2018-08-15 17:34:54 -07:00
William Chargin c6a43d3b61
Fix iteration order in the rasterizer script (#676)
Summary:
The initial logo checkin in #637 included the 32px raster image, but
generated it in the _wrong order_ in the rasterizer script. This commit
fixes that heinous bug once and for all.

Test Plan:
Running `rasterize.sh` does not change the output.

wchargin-branch: rasterize-32px
2018-08-15 17:24:38 -07:00
William Chargin 5ac2494586
Load plugin data even when hosted at non-root (#679)
Summary:
This commit approximately completes the implementation of #643.\* Plugin
adapters are now provided an `Assets` object at `load` time, which they
can use to resolve their plugin-specific API routes.

\* “Approximately” because there are some non-essential pieces of legacy
code that should be cleaned up.

Test Plan:
Unit tests modified, but it would be good to also manually test this.
Run `./scripts/build_static_site.sh` to build the site to, say,
`/tmp/gateway/`. Then spin up a static HTTP server serving `/tmp/` and
navigate to `/gateway/` in the browser. Note that the entire application
works.

wchargin-branch: use-assets-in-PluginAdapters
2018-08-15 17:21:51 -07:00
William Chargin b252a6b5de
Load repo registry even when hosted at non-root (#678)
Summary:
This commit is the next step in #643. It makes the `RepositorySelect`
robust to being hosted at arbitrary gateways by accepting `Assets` and
resolving the repository registry API route appropriately.

Test Plan:
Unit tests modified, but it would be good to also manually test this.
Run `./scripts/build_static_site.sh` to build the site to, say,
`/tmp/gateway/`. Then spin up a static HTTP server serving `/tmp/` and
navigate to `/gateway/` in the browser. Note that you can navigate
around the application and load the repository registry on the prototype
without any console warnings or errors, although you cannot yet load
actual graph data.

wchargin-branch: use-assets-in-RepositorySelect
2018-08-15 17:12:24 -07:00
William Chargin 19af47a664
Wire `Assets` into React components (#675)
Summary:
This commit takes the next step toward #643 by exposing `Assets` to our
React components at top level. Components will be expected to pass them
down as appropriate; this commit does not add any actual uses.

Test Plan:
Apply the following patch:

```diff
diff --git a/src/app/Page.js b/src/app/Page.js
index 24c2602..7ac2641 100644
--- a/src/app/Page.js
+++ b/src/app/Page.js
@@ -24,6 +24,10 @@ export default class Page extends React.Component<{|
                 <Link to="/" className={css(style.navLink, style.navLinkTitle)}>
                   SourceCred
                 </Link>
+                <img
+                  alt="fav"
+                  src={this.props.assets.resolve("/favicon.png")}
+                />
               </li>
               {routeData.map(({navTitle, path}) =>
                 NullUtil.map(navTitle, (navTitle) => (
```

Then, observe that the favicon loads correctly and updates across page
loads and refreshes in the following situations:
  - under `yarn start`;
  - after building the static site and serving from root;
  - after building the static site and serving from another gateway.

wchargin-branch: use-withAssets
2018-08-15 16:54:53 -07:00
William Chargin c4ecb979b3
Extract `Assets` from router with `withAssets` (#674)
Summary:
This is the last piece of major infrastructure for #643. It will enable
components like `Page` and `CredExplorerApp` to receive `Assets` as a
prop.

A previous iteration of the same functionality used the new Context API
in React v16.3. This did a good job of solving the problem in production
code, and was convenient. However, it is currently intractable to test
with the current state of Enzyme. It’s plausible that this might improve
in the future, so if threading down the props becomes to onerous, we
might check in to see how our testing libraries are doing. I expect that
the threading should not be too bad, given that we do the same thing
with `localStore`, which has worked (as far as I’m aware) without a
hitch.

Test Plan:
Unit tests added; `yarn test` suffices.

wchargin-branch: withAssets
2018-08-15 16:44:28 -07:00
William Chargin 4bbbfeebdb
Add a `.gitignore` for Sharness (#673)
Summary:
This is copied from the Sharness repository’s `test/.gitignore`, and is
also the same as Git’s `t/.gitignore` minus a Git-specific exclusion.

Suggested by @decentralion.

Test Plan:
Run `yarn sharness` and interrupt it (SIGINT) while `make` is running.
Note that `sharness/` now contains a `trash directory.*`, which Git
ignores.

wchargin-branch: sharness-gitignore
2018-08-15 16:31:00 -07:00
William Chargin ce2867a8d5
Use relative paths for router links (#672)
Summary:
As the next step for #643, this patch enables the app to be rendered at
non-root gateways by incorporating the relative-path history
implementation developed in #666. The app is not fully functional:
our React components do not yet know how to resolve assets, and so
fetches of resources like the repository will be against the wrong URLs.

Test Plan:
  - Note that `yarn start` still works.
  - Run `./scripts/build_static_site.sh` to build the site into, say,
    `/tmp/gateway`.
  - Run a static web server from `/tmp/gateway/` and note that (a) the
    paths listed in the page source are relative, and (b) everything
    works as intended, with no console messages in either Chrome or
    Firefox.
  - Run a static web server from `/tmp/` and navigate to `/gateway/` in
    the browser. Note that the app loads properly, and that refreshes
    work (i.e., the `pushState` paths are real paths). Note that the
    repository registry cannot yet be loaded, and so PageRank cannot be
    run.

wchargin-branch: relative-router
2018-08-15 15:35:12 -07:00
William Chargin 91f0459753
Use relative paths for lexically static assets (#671)
Summary:
This is the first observable step toward #643. Assets whose paths are
known as literals at server-side rendering time are now referenced via
relative paths. This means that the favicon and JavaScript bundle can be
loaded from an arbitrary gateway. The actual bundle code will still only
work when loaded from `/`.

This commit stands alone so that the enclosing change to the Webpack
config can be in as small a change as possible.

Test Plan:
  - Note that `yarn start` still works.
  - Run `./scripts/build_static_site.sh` to build the site into, say,
    `/tmp/gateway`.
  - Run a static web server from `/tmp/gateway/` and note that (a) the
    paths listed in the page source are relative, and (b) everything
    works as intended, with no console messages in either Chrome or
    Firefox.
  - Run a static web server from `/tmp/` and navigate to `/gateway/` in
    the browser. Note that the favicon and JavaScript are correctly
    noted, but that the router raises an error because it is trying to
    load a non-existent route. (This behavior is unchanged.)

wchargin-branch: relative-lexically-static
2018-08-15 15:30:23 -07:00
Dandelion Mané 094582be32 PagerankTable displays aggregated connections
Previously, expanding a node would display the individual connections
that contributed cred to that node. For nodes with high degree, this was
a pretty noisy UI.

Now, expanding a node displays "aggregations": for every type of
adjacent connection (where type is the union of the edge type and the
adjacent node type), we show a summary of the total cred from
connections of that type. The result is a much more managable summary
view. Naturally, these aggregations can be further expanded to see the
individual connections.

Closes #502.

Test plan: The new behavior is unit tested. You can also launch the cred
explorer and experience the UI directly. I have used the new UI a lot,
as well as demo'd it to people, and I like it quite a bit.
2018-08-15 15:28:59 -07:00
Dandelion Mané 8df0056f08 Add `aggregationKey` to give aggregations keys
For the group of aggregations returned by aggregation operation (e.g.
the set of aggregations returned by a call to `flatAggregate`), the keys
are unique.

Test plan: `yarn test`
2018-08-15 15:28:59 -07:00
Dandelion Mané bdf4fef2f5 Pull `Badge` out as a shared functional component
Test plan: Trivial refactor; `yarn test` suffices
2018-08-15 15:28:59 -07:00
Dandelion Mané 783a5e7d57
Add CHANGELOG.md (#670)
Also, update CONTRIBUTING.md to guide contributors to update the
changelog.

Test plan: Unnecessary
2018-08-15 15:20:59 -07:00
Dandelion Mané be79e3cb1c
Add some margin on the TableRow score column (#669)
The TableRow currently has some margin on the left, but not on the
right. This is visually unbalanced, especially when expanded so depth>0,
as the content on the right is at the very edge of the shaded rectangle.

This commit cleans that up a bit!

Test plan: Visual inspection (see screenshots in the pull request). I
don't think unit tests are necessary for small visual tweaks like this.
2018-08-15 15:10:29 -07:00
William Chargin 621a93851c
Resolve a relative path to the application root (#665)
Summary:
This is necessary for #643. If we’re serving `/prototype/index.html`, we
need to to use `..` to refer to the root of the site. This patch adds
`rootFromPath`, which performs the relevant transformation. (The
implementation is trivial, but figuring out exactly what the
specification should be was not!)

Test Plan:
Unit tests added; `yarn test` suffices.

wchargin-branch: rootFromPath
2018-08-15 13:03:19 -07:00
William Chargin c1997d041f
Add an `Assets` resolver (#664)
Summary:
This will enable clients to obtain the path to a static asset, even when
the app is not hosted at the root of a server, as outlined in #643.

This module will be used for simple assets (images, etc.) and API data
(fetches from `/api/**`) alike.

This supersedes #663. It includes the logic from that PR (`Assets`)
without the React-specific context bindings (`AssetsContext`).

Test Plan:
Unit tests included; `yarn test` suffices.

wchargin-branch: assets-resolver
2018-08-15 12:46:09 -07:00
William Chargin ad0e98ac2c
Add `createRelativeHistory` history implementation (#666)
Summary:
See #643 and the module docstring on `createRelativeHistory.js` for
context and explanation.

This patch adds `history@^3.0.0` as an explicit dependency—previously,
we were depending on it only implicitly through `react-router` (which
was fine then, but is not now). The dependency is chosen to match the
version specified in `react-router`’s `package.json`.

Test Plan:
Extensive unit tests included, with full coverage; `yarn test` suffices.

wchargin-branch: createRelativeHistory
2018-08-15 12:01:27 -07:00
Dandelion Mané 00bc9a9461
Add pluralized node names (#648)
This is preparation for #502 - we want to be able to describe groups of
nodes, e.g. "52 repositories", so we need a plural form for every node
name.

As a fly-by fix, I removed the parentheses around the node names in the
fallback adapter, as these proved to look ugly/inconsistent in the UI.

Test plan: `yarn test` is sufficient.
2018-08-15 11:58:12 -07:00
Dandelion Mané f100cd02cc
PagerankTable filter defaults to GitHub users (#653)
We humans tend to find information about humans more interesting than
information about commits or pulls. The UI should accomodate this by
defaulting to displaying GitHub user nodes in the cred explorer.

This is implemented as a new nullable argument to the PageRankTable. If
not present, then the filter defaults to showing all nodes. If the
default filter is present but doesn't match any available type, an error
is thrown.

Test plan: The new behavior is tested. Also, I checked it in the UI and
it works.

Closes #651
2018-08-15 11:44:44 -07:00
Dandelion Mané e3a4d1f2b9
ConnectionRow now shows the connection score (#658)
Previously, the ConnectionRow showed the score of the node that was the
source of the connection. I believe the UI will be more consistent and
useful if it instead shows the connection score, i.e. how important that
connection was to the node in scope. This combos well with PR #657.

Test plan: The change is very simple, and covered by unit tests. I also
verified the behavior by examining the cred explorer.
2018-08-14 15:40:49 -07:00
William Chargin c890fe03b4
Add Node’s `path.normalize` for the browser (#650)
Summary:
This function normalizes paths like `foo/bar//../baz` to `foo/baz`. The
implementation is directly copied from Node’s source code, which is
available under an MIT License.

I looked for a suitable NPM package, and rejected `path-normalize` and
`normalize-path`. (The former is closer and explicitly purports to be
the right thing, but actually isn’t.)

Test Plan:
Unit tests added, with full coverage except for one branch; I include a
proof that the branch is unreachable.

Tested on Node v8.9.4, Node v10.0.0, and Node v10.8.0. Tests pass in
each case. In the latter two cases, inconsistencies between the
implementation and the actual `path.posix.normalize` would cause a test
failure. In the former case, they do not. (All such cases verified.)

wchargin-branch: path-normalize
2018-08-14 13:04:53 -07:00
Dandelion Mané bf65860178
Change the PagerankTable component cycle (#657)
Currently, the PagerankTable creates components in the following
pattern:

```
NodeRow (depth=0)
 > ConnectionRowList (depth=1)
  > ConnectionRow (depth=2)
   > ConnectionRowList (depth=3)
```

This commit changes the cycle to the following:

```
NodeRow  (depth=0)
 > ConnectionRowList (depth=0)
  > ConnectionRow (depth=0)

NodeRow (padding=true, depth=1)
  > ConnectionRowList (depth=1)
    > ConnectionRow (depth=1)
```

This has some nice properties:

First, the context visually resets every time we return to a NodeRow, which
makes it feasible to change the score column to always have a context
dependent meaning:
- for a node row, the score is the score of that node.
- for a connection row, the score is the score contribution of that
connection
- (as of #502): for an aggregation row, the score is the score
contribution of that aggregation

We think this will be visually clear thanks to the padding around the
new NodeRow, along with the new color block indicating a new scope.

This design also ensures that every NodeRow has the full width available
to it (rather than getting crushed into a progressively smaller area of
the table), which will be very convenient for when we add renderers for
the nodes.

Thanks to @theliamcrawford as the idea for this came during a user study
with him.

Test plan:
The updated unit tests should be comprehensive. Also, try expanding some
rows in the cred explorer and verify that the behavior is as described.
2018-08-13 21:33:12 -07:00
Dandelion Mané 83969371d6
Tweak the cred explorer highlight color (#659)
William and I were experimenting, and felt that this color is slightly
more pleasing / harmonious with the rest of the site, and still quite
legibile.

Test plan: Examine the new UI, and conclude that the color choice is
harmonious and legible :). Screenshot included with the PR.

Paired with @wchargin
2018-08-13 21:27:21 -07:00
William Chargin c315af4dbb
Annotate adapter set constructor return types (#661)
Summary:
Due to <https://github.com/facebook/flow/issues/6400>, patches like the
following weren’t raising Flow errors:

```diff
diff --git a/src/app/adapters/adapterSet.test.js b/src/app/adapters/adapterSet.test.js
index 67dd3ed..ccc6ac6 100644
--- a/src/app/adapters/adapterSet.test.js
+++ b/src/app/adapters/adapterSet.test.js
@@ -77,6 +77,7 @@ describe("app/adapters/adapterSet", () => {
       const x = new TestStaticPluginAdapter();
       const fallback = new FallbackStaticAdapter();
       const sas = new StaticAdapterSet([x]);
+      sas.wat();
       return {x, fallback, sas};
     }
     it("errors if two plugins have the same name", () => {
```

A `flow type-at-pos` check indicated that the type of `sas` was indeed
inferred as `any`.

This patch applies the usual nonsensical fix. Better safe than spooky.

Test Plan:
The above patch now raises a Flow error.

wchargin-branch: annotate-adapterset-constructors
2018-08-13 21:27:02 -07:00
William Chargin 4081e0d008
Use trailing slashes for all routes (#660)
Summary:
See justification in the added unit test.

Test Plan:
Added unit test, with justification.

Also, `yarn sharness-full` passes, and `yarn start` still works.

wchargin-branch: route-trailing-slashes
2018-08-13 21:25:20 -07:00
Dandelion Mané 080edb380d
TableRows can create vertical padding (#656)
This commit adds the `showPadding` prop to `TableRow`s. If showPadding
is true, then the row will have vertical padding above the row, and
below the last child of the row. The padding will match the background
color of the given row. The padding is implemented as extra `tr`
elements that themselves contain empty tds.

Test plan: The new behavior is pretty thoroughly covered by new unit
tests. Additionally, if you want to see padding in the live UI, you can
apply the following (slightly contrived) diff.

```
diff --git a/src/app/credExplorer/pagerankTable/Connection.js b/src/app/credExplorer/pagerankTable/Connection.js
index 3a882cd..633525b 100644
--- a/src/app/credExplorer/pagerankTable/Connection.js
+++ b/src/app/credExplorer/pagerankTable/Connection.js
@@ -70,7 +70,7 @@ export class ConnectionRow extends React.PureComponent<ConnectionRowProps> {
         depth={depth}
         description={connectionView}
         connectionProportion={connectionProportion}
-        showPadding={false}
+        showPadding={depth % 3 === 0}
         score={sourceScore}
       >
         <ConnectionRowList
```
2018-08-13 19:11:19 -07:00
Dandelion Mané 7f18e389ea
Separate TableRow `depth` from `indent` (#655)
Currently, as we expand nodes or connections in the PagerankTable, the
rows both get more indented and attain a deeper color. Both of these
behaviors are controlled by the `depth` parameter.

We're going to switch the UI to a cyclic structure, where as you drill
down, once you get back to a particular node, the indentation resets to
base, but the color - which now indicates nested depth - continues to
change. This commit sets that change up, by splitting the behvaior into
two parameters: `depth`, which controls the color, and `indent`, which
controls the indentation level.

As a small additional tweak, the indentation formula is changed so that
buttons are always indented by 5 pixels. This results in a cleaner
display for nodes that have `depth>0` but `indent==0` (as the button
doesn't look squahsed against the color boundary).

Test plan:
The change is very simple; inspecting the updated snapshots should be
persuasive.
2018-08-13 18:07:13 -07:00
Dandelion Mané c5e20f9400
Factor out TableRow as a reusable abstraction (#652)
We currently have two components which create rows in our PagerankTable:
the `NodeRow` and `ConnectionRow`. Work on #502 will result in the
addition of a new one, the `AggregationRow`. It's time to stop
duplicating logic (and testing) of the shared behavior for these rows,
like depth-based styling, row expansion/collapse, etc. This commit pulls
all the common logic to rendering rows into a single, thoroughly tested
`TableRow` component.

There is one observable change in the UI: when a connection percentage
is not available (i.e. for NodeRows), we now leave the column empty
rather than placing a dash in the column. I think this is visually
cleaner.

Test plan: Unit tests pass, and this part of the code base is thoroughly
tested, so that's a pretty reliable indicator. I also poked around the
live PagerankTable in the cred explorer, just to be safe.
2018-08-13 12:31:16 -07:00