Commit Graph

1256 Commits

Author SHA1 Message Date
Dandelion Mané eed115a995
Add to (and update) Discourse snapshots (#1422)
I made a new [test post][1] which has references. The Discourse
snapshots now include it, so we can give a realistic test of reference
and mention detection.

This will allow us to verify whether #1420 is affecting us, and fix it
if so.

Test plan: Commit was generated by running the snapshot updater. Other
snapshots have been updated and look OK. `yarn test` passes.

[1]: https://sourcecred-test.discourse.group/t/a-post-with-references/21
2019-10-24 11:28:16 -06:00
greenkeeper[bot] c560f508b1 Update flow-bin to the latest version 🚀 (#1421)
* chore(package): update flow-bin to version 0.110.0

* chore(package): update lockfile yarn.lock
2019-10-22 12:05:50 -06:00
William Chargin 01bdb2e94a
mirror: remove unused helper functions (#1351)
Summary:
The functions `isSqlSafe` and `_nontransactionallyFindUnusedTableName`
are unused, because we no longer need to dynamically generate SQL, and
all operations are clearly safe by construction.

Test Plan:
That `yarn flow` passes suffices.

wchargin-branch: mirror-prune-helpers
2019-10-19 18:14:40 -07:00
William Chargin b0b911cec4
mirror: use fixed temp table for transitive deps (#1350)
Summary:
The Mirror module extraction code calculates the set of transitive
dependencies and stores these results in a temporary table to avoid
unnecessary marshalling between JavaScript and C. We originally chose
the temporary table name dynamically, guaranteeing that it was unused.
However, this is unnecessary:

  - The temporary table namespace is unique to each database connection,
    so we need only consider possible conflicts in the same connection.
  - A `Mirror` instance exercises exclusive ownership of its database
    connection, per its constructor docs, so we need only consider
    conflicts within this module.
  - Temporary tables are only used in the `extract` method, so we need
    only consider conflicts in this method.
  - The `extract` method makes no open calls nor recursive calls, and
    does not yield control back to the event loop, so only one stack
    frame can be in `extract` at any time.
  - The `extract` method itself only creates the temporary table once.

Thus, the temporary table creation is safe. Furthermore, the failure
mode is simply that we raise an exception and fail cleanly; there is no
risk of data loss or corruption.

This patch replaces the dynamically generated table name with a fixed
name. On top of the work in #1313, this removes the last instance of SQL
queries that are not compile-time constant expressions.

Test Plan:
Running `yarn unit -f graphql/mirror` suffices.

wchargin-branch: mirror-fixed-temp-table
2019-10-19 18:12:59 -07:00
William Chargin ebdd20b576
mirror: clean up references to “EAV” primitives (#1349)
Summary:
The migration is complete; only EAV primitives remain, so they shall be
called simply “primitives”. See #1313 and adjacent commits for context.

Test Plan:
Running `git grep -iw eav` no longer returns any results.

wchargin-branch: mirror-eav-prune-names
2019-10-19 18:09:24 -07:00
William Chargin dbf22cdcfc
mirror: remove primitives test multiplexing logic (#1348)
Summary:
This logic now abstracts over only one implementation, and is no longer
needed.

Test Plan:
That `yarn unit -f graphql/mirror` passes is sufficient.

wchargin-branch: mirror-eav-prune-test-mux
2019-10-19 18:06:20 -07:00
William Chargin 0f52fb4c26
mirror: remove legacy tables (#1347)
Summary:
This data is now stored in EAV `primitives` table; see issue #1313 and
adjacent commits for details.

We simultaneously lift the restriction that GraphQL type and field names
be SQL-safe identifiers, as it’s no longer necessary.

Test Plan:
Some test cases queried the legacy primitives tables to check properties
about the database state. These queries have of course been removed;
note that each such removed query was already accompanied by an
equivalent query against the EAV `primitives` table.

Note that `yarn test --full` still passes, and that when manually
loading `sourcecred/example-github` the cache no longer has any of the
legacy tables.

wchargin-branch: mirror-eav-prune-tables
2019-10-19 18:02:22 -07:00
William Chargin 003efdffa7
mirror: remove legacy non-EAV `extract` (#1346)
Test Plan:
Existing tests suffice, retaining full coverage.

wchargin-branch: mirror-eav-prune-extract
2019-10-19 17:58:17 -07:00
William Chargin f577ae7c1e
identity: forbid underscores in GitHub logins (#1414)
Summary:
GitHub logins may not have underscores, because underscores are not
valid characters in DNS labels. We already have a good-enough regular
expression for validating GitHub usernames; this commit updates the
alias parser to use that.

Discourse usernames are more permissive than what is listed here, but we
leave that unchanged for now.

Test Plan:
Unit tests updated.

wchargin-branch: alias-no-underscore
2019-10-19 09:10:38 -07:00
William Chargin 28b25c2910
identity: require aliases to be anchored (#1413)
Summary:
All the documentation and tests seem to be assuming that aliases must be
anchored: `github/torvalds`, but not `some github/torvalds stuff`.
JavaScript regular expressions aren’t anchored by default; this commit
adds explicit anchoring and adds tests.

Test Plan:
Unit tests added.

wchargin-branch: alias-anchor
2019-10-19 09:06:09 -07:00
Dandelion Mané b2943390dc
add discourse references to the graph (#1410)
This commit modifies `discourse/createGraph` so that it finds all of the
same-server Discourse references in Discourse posts, and creates
appropriately typed references edges in response.

The unit tests have been updated with cases for both references that
should exist, and references that shouldn't (e.g. post index out of
bounds, or a reference to the wrong server).

Test plan: `yarn test --full` along with snapshot update.

This is progress towards [Discourse reference and mention detection][1].

[1]: https://discourse.sourcecred.io/t/discourse-reference-mention-detection/270
2019-10-18 10:56:53 -06:00
Robin van Boven e043347526 Support dashes in alias usernames. (#1412) 2019-10-17 13:21:39 -06:00
Dandelion Mané 78c34b5a36
Parse Discourse references from hyperlinks (#1405)
The `discourse/references` module now has a `linksToReferences` method
which extracts the parsed Discourse references from an array of
hyperlinks. The method is tested.

Test plan: Unit tests added; `yarn test` passes.

This is progress towards [Discourse reference and mention detection][1].

[1]: https://discourse.sourcecred.io/t/discourse-reference-mention-detection/270
2019-10-16 18:39:46 -06:00
greenkeeper[bot] f725f7c47a Update dotenv to the latest version 🚀 (#1411)
* chore(package): update dotenv to version 8.2.0

* chore(package): update lockfile yarn.lock
2019-10-16 16:32:49 -07:00
Robin van Boven 00cc8b2a54 Expand the blacklist, found new type inconsistencies (#1407)
- Bots being Users as a commit author
- Orgs being Users on a reaction

Repositories affected, check represents tested after patch:
- [x] prettier/prettier
- [x] lovell/sharp
- [x] facebook/jest
- [x] babel/babel-eslint
- [x] recharts/recharts
- [x] webpack-contrib/css-loader
- [x] yannickcr/eslint-plugin-react
- [x] vuejs/vuex
- [x] chimurai/http-proxy-middleware
- [x] sass/node-sass
- [x] lodash/lodash
- [x] vuejs/vue
- [x] reacttraining/react-router
- [x] axios/axios
- [x] webpack/webpack-dev-middleware
- [x] eslint/eslint
- [x] webpack/webpack
- [x] webpack/webpack-cli
- [x] sinonjs/sinon
- [x] neutrinojs/webpack-chain
- [x] webpack/webpack-dev-server

Found as part of https://github.com/teamopen-dev/sourcecred-stack-lookup

Test after this patch: pending, it's a lot of data after the cache invalidated 😅
2019-10-15 08:37:24 -07:00
William Chargin 0380088af2
mirror: update implementation notes for EAV tables (#1345)
Summary:
The notes used to focus on the legacy implementation with a minor note
about the EAV implementation; this change flips that relationship.

Test Plan:
None.

wchargin-branch: mirror-eav-impl-notes
2019-10-12 11:36:16 -07:00
William Chargin 809fd23def
mirror: read from EAV tables by default (#1344)
Summary:
This flips the switch for all production `Mirror` reads to use the
single `primitives` EAV table as their source of truth, rather than the
legacy type-specific primitives tables. For context and design
discussion, see issue #1313 and commits adjacent to this one.

Test Plan:
All relevant code paths are already tested (see test plans of commits
adjacent to this one). Running `yarn test --full` passes.

wchargin-branch: mirror-eav-flip
2019-10-12 11:28:55 -07:00
William Chargin e5a77488de
mirror: add EAV reading to `extract`, behind flag (#1343)
Summary:
This completes the end-to-end EAV mode pipeline, but does not yet set it
as default or use it in production.

A note about indentation: we take care to avoid reindenting the entire
block of `extract` test cases, which is over 900 lines long. As to the
implementation code, reindenting the legacy type-specific primitives
branch is not easily avoidable, but when we remove that branch we won’t
have to reindent the EAV mode branch: we can replace its `if` block with
two scope blocks (which is the right thing to do, anyway).

Test Plan:
We reuse existing tests, which suffice for full coverage in both
implementation branches. Note that these tests cover the case of object
types with no primitive fields (the `Feline` and `Socket` types), which
are more likely to fail in a broken EAV implementation than in a broken
type-specific primitives implementation due to deletion anomalies.

To check that all relevant calls to `mirror.extract(…)` have been
properly replaced with `extract(mirror, …)`, run

    yarn coverage -f graphql/mirror -t 'EAV primitives'

and note that the “else” path of the `if (fullOptions.useEavPrimitives)`
branch is not taken; then, run

    yarn coverage -f graphql/mirror -t 'legacy type-specific primitives'

and note that the “if” path of the same branch is not taken.

To check that the table hiding logic is working, invert the branch that
checks `if (fullOptions.useEavPrimitives)`, and note that every test
case using the table hiding logic fails (except for some of the error
handling test cases, which do not actually need to read primitive data).

Finally, `yarn test --full` passes after flipping the `useEavPrimitives`
default to `true`.

wchargin-branch: mirror-eav-extract
2019-10-12 11:23:35 -07:00
Dandelion Mané e1a73ac368
refactor discourse createGraph (#1409)
This is a minor refactor to re-organize the createGraph function in the
Discourse plugin to use a class under the hood. Using a hidden class
makes sense because there is a fair bit of shared state that's needed
while creating the graph.

The proximate cause for this refactor is tha adding reference edges will
bloat the `addPost` section of the function, which was already a little
too complex. Simply shoving in more complexity would make it unweidy. So
I opted for this minor refactor. It's internal-only (no public APIs are
changed).

Test plan: `yarn test` passes. As noted, refactor is internal-only.

This is progress towards [Discourse reference and mention detection][1].

[1]: https://discourse.sourcecred.io/t/discourse-reference-mention-detection/270
2019-10-11 13:46:49 -06:00
Dandelion Mané d4804a7a68
Add edge types for Discourse references (#1406)
Test plan: It's just a declaration change. `yarn flow` passes.

This is progress towards [Discourse reference and mention detection][1].

[1]: https://discourse.sourcecred.io/t/discourse-reference-mention-detection/270
2019-10-11 13:46:35 -06:00
Dandelion Mané eb008f40cc
discourse: factor out address module (#1404)
This will make it possible to depend on addresses in the reference
module.

Test plan: `yarn test` passes.

This is progress towards [Discourse reference and mention detection][1].

[1]: https://discourse.sourcecred.io/t/discourse-reference-mention-detection/270
2019-10-11 13:40:10 -06:00
Dandelion Mané 5e02a2caeb
Add logic for plucking hyperlinks from cooked html (#1403)
This commit adds a `parseLinks` method to a new module,
`plugins/discourse/references`. `parseLinks` allows us to extract the
hyperlinks from `<a>` tags in "cooked" html.

I added `htmlparser2` as a dependency to parse the html. There were a
lot of options to choose from; I chose htmlparser2 because it has a lot
of usage, reasonable performance, and suits our needs. We use this
dependency in a lightweight and local way, so we can always change it
later if needed.

One thing which was a bit odd: I wasn't able to import it using
`import`, and needed a `require` statement instead.

Test plan: Unit tests added; `yarn test` passes.

This is progress towards [Discourse reference and mention detection][1].

[1]: https://discourse.sourcecred.io/t/discourse-reference-mention-detection/270
2019-10-11 13:36:31 -06:00
Dandelion Mané f82c1bfbbe
Add post contents to the Discourse mirror (#1402)
This modifies the Discourse fetcher and mirror so that we now keep post
contents around, thus enabling future reference detection (and other
things). The post contents are stored and provided as retrieved from the
API, which is in "cooked" HTML form.

Test plan: Unit tests and snapshots updated. Observe that the snapshots
now include Discourse post contents.

This is progress towards [Discourse reference and mention detection][1].

[1]: https://discourse.sourcecred.io/t/discourse-reference-mention-detection/270
2019-10-11 13:31:01 -06:00
greenkeeper[bot] 65edd01dcf Update eslint-plugin-react to the latest version 🚀 (#1400)
* chore(package): update eslint-plugin-react to version 7.16.0

* chore(package): update lockfile yarn.lock
2019-10-04 09:22:12 -06:00
greenkeeper[bot] 74e7508f11 chore(package): update dependencies (#1394) 2019-10-03 12:03:25 -06:00
Dandelion Mané 026d3dc705
Upgrade flow to v109 (#1395)
We need one tiny change in test code, where Flow (correctly) detects an
error. I've added an error suppression comment because it is truly a
Flow error, but is appropriate as we are testing an error condition.

Test plan: `yarn test`
2019-10-03 10:41:51 -06:00
Dandelion Mané 1ff13b266e
Fix full build after #1391 (#1393)
In #1391, I updated the default alpha, but forgot to regenerate the load
snapshots. This caused a [nightly build failure][1]. This commit fixes
it.

Test plan: `yarn test --full` passes.

[1]: https://circleci.com/gh/sourcecred/sourcecred/2300
2019-09-30 17:37:04 -06:00
Dandelion Mané 64c17f7dba
Change default alpha to 0.2 (#1391)
SourceCred is currently quite sensitive to inadvertent 'tight loops' in
the cred, where (e.g.) one user recieves cred but doesn't have many out
edges, resulting in a feedback loop where that person gets
disproportinate cred. See [1] and [2] for some examples.

Per a [suggestion] from @mzargham, I'm going to bandaid this issue by
increasing the alpha parameter; I've increased it 4x from 0.05 to 0.2.
Subjectively, I think this improves the cred quality.

[1]: https://discourse.sourcecred.io/t/sneak-peek-sourcecred-discourse-plugin/171
[2]: https://discourse.sourcecred.io/t/preliminary-credsperiment-cred/219
[suggestion]: https://discourse.sourcecred.io/t/preliminary-credsperiment-cred/219/16?u=decentralion
2019-09-30 10:49:25 -06:00
Dandelion Mané 6e2af1070f
Expose alpha in TimelineExplorer (#1390)
This commit modifies the TimelineExplorer so that the user can both see
the chosen alpha value, and change it. Alpha has a pretty profound
impact on the final scores, and I want to tweak it for CredSperiment
week two, so this is an important addition.

Test plan: Modify the alpha, re-run cred calculation, and observe that
the scores change. `yarn test` passes.
2019-09-30 10:33:15 -06:00
Dandelion Mané 54ece536d3
Integrate the identity plugin (#1385)
This commit integrates the identity plugin, which was created in #1384.
It does this by adding explicit identity fields to the project
configuration, which are then applied when loading the graph in
`api/load.js`.

The actual integration is quite straightforward.

Test plan: The underlying logic is thoroughly tested; I added one new
test case to verify that it is integrated properly. Since the project
compat has changed, I've updated all the snapshots. Prior to merging
this PR, I will produce one "integration test", using this code to do
identity resolution for a real project (i.e. on the SourceCred instance
itself).
2019-09-20 12:08:27 +02:00
Dandelion Mané 9a9f211901
Add the identity plugin (#1384)
This commit adds the new SourceCred identity plugin. As described in the
README.md file:

This folder contains the Identity plugin. Unlike most other plugins, the
Identity plugin does not add any new contributions to the graph. Instead, it
allows collapsing different user accounts together into a shared 'identity'
node.

To see why this is valuable, imagine that a contributor has an account on both
GitHub and Discourse (potentially with a different username on each service).
We would like to combine these two identities together, so that we can
represent that user's combined cred properly. The Identity plugin enables this.

Specifically, the instance maintainer can provide a (locally unique) username
for the user, along with a list of aliases the user is known by, e.g.
`github/username` and `discourse/other_username`. The aliases are simple string
representations, that are intended to be easy to maintain by hand in a
configuration file. Then, the identity plugin will provide a list of
`NodeContraction`s that can be used by `Graph.contractNodes` to combine the
user identities as described.

The plugin is broken up into a few submoudles:
- `declaration.js` provides the PluginDeclaration. It has a single node
type (the identity node).
- `identity.js` declares the `Identity` type (a username and list of
aliases), allows constructing identity nodes, and does some validation
on the identity username.
- `alias.js` implements the logic for parsing aliases like
"github/decentralion" or "discourse/s_ben" into a node address.
- `nodeContractions.js` provides logic for turning a list of Identities
into a list of NodeContractions, suitable for use in
`Graph.contractNodes`.

The plugin is not yet integrated; that will come in a followon commit.

Test plan: Unit tests added; `yarn test` passes.
2019-09-20 11:50:59 +02:00
Dandelion Mané b86dcf742e
Make the Discourse plugin robust to errors (#1387)
Currently attempting to load the SourceCred discourse instance fails
with foreign key constraint errors.

Basically, we have a few weird situations:
- A post (which corresponds to the 'psuedo-topic' generated by creating
a new category) is picked up, but its topic is not detected, because
Discourse does not list these 'psuedo-topics' in the latest topic
endpoint. Attempting to add the post breaks the foreign key constraint.

- We have several likes which correspond to posts that don't exist.
Possibly they were deleted? I'm not sure.

Right now, the load process fails entirely when it hits these
exceptions, which is bad. It should print a warning instead, and
continue without the offending interactions. This commit effects that
change in behavior.

Test plan:

Before this commit, loading the SourceCred discourse with a clean cache
fails. After building with this commit, loading the SourceCred discourse
with a clean cache workes and prints the following warnings:

```
$ node bin/sourcecred.js discourse https://discourse.sourcecred.io credbot
  GO   load-discourse.sourcecred.io
  GO   discourse
  GO   discourse/topics
 DONE  discourse/topics: 3m 53s
  GO   discourse/posts
Warning: Encountered error 'FOREIGN KEY constraint failed' while adding
post https://discourse.so urcecred.io/t/214/1.
 DONE  discourse/posts: 2m 38s
  GO   discourse/likes
 DONE  discourse/likes: 50s
 DONE  discourse: 7m 21s
  GO   compute-cred
 DONE  compute-cred: 547ms
 DONE  load-discourse.sourcecred.io: 7m 22s
```

Also, unit tests have been added that verify the specific behavior
changes.
2019-09-20 11:21:53 +02:00
Robin van Boven d5d00aae5a Blacklist techtribe org, thumbsup reaction (#1386)
Fixes #1353

Tested manually by creating a docker image including the changes.
Running the dev-preview @passbolt command until completion.
(once hitting the github rate limit, once till #1354 happens)

No more problematic interactions show up during load.
2019-09-20 11:20:14 +02:00
Robin van Boven d6bbc939b2 Add more bots. (#1383)
Fixes #1381
2019-09-19 17:52:20 +02:00
Dandelion Mané 8f46d7d812
Fix bug when selecting "All users" in explorer (#1388)
This fixes a bug introduced in #1371, where selecting a type other than
"All users" and then trying to reselect "All users" would break the UI.

Test plan: Manual inspection; load an instance, try selecting a
different type, and then go back to "All users". It now works as
expected.
2019-09-19 14:01:17 +02:00
Dandelion Mané 007568d3f0
Add `sourcecred discourse` command (#1374)
This adds a new command, `discourse`, which makes it convenient to load
Discourse servers as standalone SourceCred projects.

For example, you could load the official SourceCred discourse via the
following:

```sh
export SOURCECRED_DISCOURSE_KEY=....
yarn backend
node bin/sourcecred.js discourse https://discourse.sourcecred.io credbot
yarn start
```

I've updated the README with instructions for using the plugin.

Test plan: No automated testing because I see this tool as a temporary
placeholder until we get the SourceCred instances setup. I manually
tested the error cases (e.g. providing an invalid server url) as well as
success cases like the one above. I validated that the weights file
argument is being interpreted correctly (i.e. trying to load invalid
weights produces an expected error message, loading valid weights
results in those weights being present in the UI).
2019-09-19 12:32:49 +02:00
Dandelion Mané 1449935651
GitHub plugin: Expose user addresses (#1382)
Allow getting the node address for a user, given the user's login. This
will be needed by the upcoming identity plugin.

If the login in question corresponds to a bot, then a bot address will
be returned. When we make the bot-set configuration (rather than
hardcoded), we'll need to change the signature of this function; I think
that's fine.

Test plan: Unit tests added. (Also, it's really simple.)
2019-09-18 14:50:52 +02:00
Dandelion Mané ac8ac7051f
add `Graph.contractNodes` (#1380)
This commit adds Graph.contractNodes, which allows collapsing certain
nodes in the graph into each other. This will enable the creation of a
SourceCred "identity" plugin, allowing identity resolution between users
different accounts on different services.

Test plan: Thorough unit tests have been added. `yarn test` passes.

Thanks to @wchargin for [review feedback][1] which significantly
improved this API.

[1]: https://github.com/sourcecred/sourcecred/pull/1380#discussion_r324958055
2019-09-18 13:59:49 +02:00
William Chargin ddf07c6714
Replace `PartialTimelineCredParams` with `$Shape` (#1379)
Summary:
Flow provides a utility type for this purpose; there’s no need to
implement, document, and keep it in sync ourselves:
<https://flow.org/en/docs/types/utilities/#toc-shape>

Test Plan:
As written, `yarn flow` passes. Changing the definition of `params` on
line 77 of `load.test.js` to add a key `foo: "wat"` or change the value
of `weights` to `{hmm: "hmm"}` yield appropriate type errors.

wchargin-branch: use-shape
2019-09-16 19:22:35 -07:00
William Chargin 3cb22565e5
mirror: update EAV primitives (#1342)
Summary:
This commit modifies `_updateOwnData` to write to both the old
type-specific primitives tables as well as the new EAV table. This
establishes the invariant that a node with non-null `last_update` will
always have primitive data (if its object type has primitive fields).

Test Plan:
Existing tests expanded. Commenting out each of the `updateEavPrimitive`
calls (independently) causes a test to fail. Note that every test that
queries an internal `primitives_*` table to inspect the database state
has been expanded to make an equivalent query against the `primitives`
table as well.

wchargin-branch: mirror-eav-update
2019-09-14 17:28:09 -07:00
William Chargin 463f3a073a
mirror: initialize EAV primitives at registration (#1341)
Summary:
This establishes the invariant that every object in the `objects` table
has all relevant rows in the `primitives` table, though those rows’
values are never yet set.

Test Plan:
Unit tests updated. Manually loading `sourcecred/example-github` and
running `.dump primitives` generates reasonable-looking output, with
lots of rows, including entries for nested fields and eggs. Verified
that the set of non-`id` columns on `Issue` equals the set of values for
the `fieldname` column of an `Issue` object, and likewise for `Commit`s,
thus covering each kind of field.

wchargin-branch: mirror-eav-init
2019-09-14 17:24:58 -07:00
William Chargin 0418dfe9dd
mirror: add `primitives` table for EAV migration (#1340)
Summary:
See #1313 for context. The plan is to set up dual-writes with `extract`
calls still reading from the old tables until the new ones are complete
and tested. The primary risk to production would be a fatal exception in
the new write paths, which seems like an acceptable risk.

Test Plan:
Unit tests pass.

wchargin-branch: mirror-eav-schema
2019-09-14 17:21:42 -07:00
William Chargin 976afb6665
mirror: test `registerObject` with nested fields (#1339)
Summary:
Prior to this commit, removing the `addLink.run({id, fieldname})` on
line 487 of `mirror.js` would cause test failures down the pipeline, but
not at the root cause. Such an error is now caught earlier.

Test Plan:
Comment out line 487 of `mirror.js` and observe that the newly added
test case fails, but the other `registerObject` test cases do not.

wchargin-branch: mirror-test-registerobject-nested
2019-09-14 17:16:24 -07:00
Dandelion Mané c58315fe4d
Hackily add support for mixed GitHub/Discourse projects (#1378)
For phase one of the CredSperiment, I need a SourceCred instance which combines GitHub and Discourse servers. I'll also need to be able to give it very specific configuration to collapse certain user identities together.

Shortly after launching the CredSperiment, I plan to come back and totally re-write SourceCred's command line interface and site building system, in a way that will throw away most of the existing codebase.

As such, I found it expedient to add rather hacky and untested support for loading combined GitHub/Discourse instances, so I can land the promised features. This PR does so by:

- adding sourcecred gen-project for constructing project.json files
- adding sourcecred load --project for loading a project.json file
- ensuring that load provides the right plugins based on the project that's in scope
- updating build_static_site so that it can use the new --project flag

Test plan:
I have done some end-to-end testing, but the overall commit stack lacks automated testing. This is a deliberate tradeoff: I'm planning to re-write this section of the codebase, and the testing ergonomics are not great, so I'd rather accept some technical debt, especially since I plan to pay it off soon.

See the pull request on GitHub for the individual constituent commits.
2019-09-12 17:35:21 +02:00
Dandelion Mané 7a0dd49b42
factor loadWeights into Common (#1377)
As suggested by @Beanow in [a review comment][1], this commit factors
loading weights from disk into a cli/common utility method.

The actual method is really generic, and we have a number of similar
constructions across the codebase (grep for `JSON.parse` to find them).
I considered factoring out a generic utility for loading and
deserializing JSON data from disk in general, but it didn't seem
valuable enough at this time.

Test plan: Unit tests added, existing tests pass.

[1]: https://github.com/sourcecred/sourcecred/pull/1374#discussion_r323149740
2019-09-12 15:55:05 +02:00
Dandelion Mané 0a0010f38e
Share default TimelineCredParameters (#1376)
At present, every place in the codebase that needs
TimelineCredParameters constructs them ad-hoc, meaning we don't have any
shared defaults across different consumers.

This commit adds a new type, `PartialTimelineCredParameters`, which
is basically `TimelineCredParameters` with every field marked optional.
Callers can then choose to override any fields where they want
non-default values. A new internal `partialParams` function promotes
these partial parameters to full parameters.

All the public interfaces for using params (namely,
`TimelineCred.compute` and `TimelineCred.reanalyze`) now accept optional
partial params. If the params are not specified, default values are
used; if partial params are provided, all the explicitly provided values
are used, and unspecified values are initialized to default values.

Test plan: A simple unit test was added to ensure that weights overrides
work as intended. `git grep "intervalDecay: "` reveals that there are no
other explicit parameter constructions in the codebase. All existing
unit tests pass.
2019-09-12 15:21:13 +02:00
Dandelion Mané def1fef192
Factor TimelineCredParameters into new module (#1375)
The `timelineCred.js` file is a bit of a beast. One way to start
slimming it down is to pull the parameters into their own file. This is
especially helpful as I'm planning a followon PR that will colocate the
default parameter values with their declaration.

The naming of everything in the `/timeline/` subdirectory is a bit
wonky: it reflects that at the time of creation, "Timeline" designated
an experimental version of SourceCred. Now, it is becoming canonical,
but the cumbersome naming persists. I haven't made any effort to tackle
the name debt here.

Test plan: `yarn test` passes; since this is merely a code
reorganization, this give me great confidence that the change is
correct. I also added a few small tests to the new module. Although the
behavior in question is already tested, I think setting up test files
liberally is a good practice, as the existence of the test file invites
the creation of more tests.
2019-09-12 15:12:17 +02:00
Dandelion Mané e1b9b07cac
group explorer types by plugin (#1373)
Now that we're adding support for the Discourse plugin, we'll start
having >1 plugin present in the frontend again. As such, we should
provide clear grouping of types in the frontend so that it's possible to
distinguish between a GitHub user and a Discourse user. This commit does
just that, by resurrecting code that we used when the GitHub and Git
plugins co-existed in the frontend.

Test plan: Launch the fronted and observe that node types in the filter
selection dropdown are grouped by the name of their plugin. Also,
clicking on the name of a plugin should filter to all nodes from that
plugin.
2019-09-11 02:28:42 +02:00
Dandelion Mané 093955dea1
scores command no longer assumes GitHub plugin (#1372)
Previously, the `sourcecred scores` command assumed that all users are
GitHub users, and assigned users an id based on their GitHub login.

Now, the command returns information on all users, regardless of which
plugin provided them. As such, we need to identify users differently.
Instead of a string id, they now have an array of address parts. That
array contains all of the parts of their corresponding node address.

For example, the GitHub user `@Beanow` would correspond to the address
array `["sourcecred", "github", "USERLIKE", "USER", "Beanow"]`

As a general convention, the first two components of any node's address
contain information about the plugin that owns that node. The first
component is the owner of the plugin, and the second is the name of the
plugin. Afterwards, the plugin may represent nodes in whatever manner it
sees fit.

Thanks to @Beanow and @vsoch for some feedback and discussion on this
design.

Test plan: Snapshots have been updated. `yarn test` passes.
2019-09-10 23:49:45 +02:00
Dandelion Mané b3ffd3758b
TimelineExplorer defaults to showing all users (#1371)
Now instead of always defaulting to GitHub users, it shows all
user-typed nodes. This will make SourceCred work non-hackily when there
is e.g. just a Discourse plugin in scope.

I also fixed an issue where it was loading the GitHub declaration in a
hardcoded way, instead of properly getting it from the TimelineCred's
plugin array.

Test plan: Manual UI inspection.
2019-09-10 22:50:39 +02:00