Commit Graph

1162 Commits

Author SHA1 Message Date
Dandelion Mané e7b1fbd681
mirror: allow fetching all usernames (#1293)
This is a minor change to the Discourse mirror so that it supports a
query to get all users from the server. It will be convenient for a
followon change which makes `update` search for every user's likes.

I also modified createGraph so that it uses the new method, which
results in code that is cleaner and slightly more efficient.

Test plan: Unit tests updated.
2019-08-18 16:27:11 +02:00
Dandelion Mané f3ae0a8415
discourse fetcher: add support for likes (#1294)
For the Discourse plugin, we really want to be able to add a full record
of all of the users' liked posts as edges in the graph. It's a really
high-signal way to move cred, that also gives individual users a lot of
agency and way to engage.

However: we need an API to get this data. Initial searches of API docs
were un-promising; fisrt, we would need to query potentially every post
to get its likes individually (makes it very expensive to find the likes
on old posts), and second, the likes did not come with timestamp
information. For a while, I thought we were at an impasse.

I then went fishing in the Discourse implementation for a solution (yay
open source!). Lots of the API is un-documented, since it's whatever
they happen to add to run Discourse. And it turns out there's a
`user_actions` API ([source]) which can provide all of a user's actions
in order, and having your content liked by someone else is considered an
action. Best of all, these actions come with timestamps.

The upshot is that instead of querying every post to get its likes, we
can query every user to get likes.  Iterating over all users can still
be slow, but it's far better than iterating over all posts; plus we can
implement caching so that we only infrequently check in on inactive
users.

I've added a `likesByUser` method to the Discourse fetch interface that
provides this information. I've also added a snapshot test for it (and
updated all of the snapshots). I also rolled in a slight refactor to
error handling in the fetcher.

The mirror doesn't yet use this information (will come later).

[source]: 82e07cb0f4/app/controllers/user_actions_controller.rb (L3)

Test plan: `yarn test` passes. Snapshots look good.
2019-08-18 16:20:33 +02:00
William Chargin 64f282fff2 discourse: consolidate parallel `MAX` queries (#1296)
Summary:
As mentioned in <https://github.com/sourcecred/sourcecred/pull/1266#discussion_r312345441>.

Test Plan:
Running `yarn test` passes.

wchargin-branch: discourse-single-max-query
2019-08-17 12:58:55 +02:00
Dandelion Mané b50ba67797
add discourse declaration and createGraph (#1292)
This commit adds the logic needed for creating a contribution graph
based on the Discourse data. We first have a declaration with
specifications for the node and edge types in the plugin. We also have a
`createGraph` module which creates a conformant graph from the Mirror
data. The graph creation is thoroughly tested.

Test plan: Inspect unit tests, run `yarn test`. I also have (yet
unpublished) code which loads the graph into the UI, and it appears
fine.
2019-08-17 04:20:27 +02:00
Dandelion Mané 69831d6961
mirror: make a data interface (#1291)
This is a quick fixup so that the coming createGraph module can be
properly tested.

Shout out to @Beanow for anticipating this need in a [review comment].

[review comment]: https://github.com/sourcecred/sourcecred/pull/1266#discussion_r314305108

Test plan: trivial refactor, run `yarn test`
2019-08-15 20:12:20 +02:00
Dandelion Mané 2f8e1c61e4
Add a Discourse API mirror (#1266)
The mirror wraps a SQLite database which will store all of the data we
download from Discourse.

On a call to `update`, it downloads new data from the server and stores
it. Then, when it is asked for information like the topics and posts, it
can just pull from its local copy. This means that we don't need to
re-download the content every time we load a Discourse instance, which
makes the load more performant, more robust to network failures, etc.

Thanks to @wchargin, whose work on the GraphQL mirror for GitHub (#622)
inspired this mirror.

Test plan: I've written unit tests that use a mock fetcher to validate
the update logic. I've also used this to do a full load of the real
SourceCred Discourse instance, and to create a corresponding graph
(using subsequent commits).

Progress towards #865.
2019-08-15 16:08:04 +02:00
Dandelion Mané fd95be68a9
Add class for fetching data from Discourse (#1265)
The `DiscourseFetcher` class abstracts over fetching from the Discourse
API, and post-processing and filtering the result into a form that's
convenient for us.

Testing is a bit tricky because the Discourse API keys are sensitive
(they are admin keys) and so I'm reluctant to commit them, even for our
test instance. As a workaround, I've added a shell script which
downloads some data from the SourceCred test instance, and saves it with
a filename which is an encoding of the actual endpoint. Then, in
testing, we can use a mocked fetch which actually hits the snapshots
directory, and thus validate the processing logic on "real" data from
the server. We also test that the fetch headers are set correctly, and
that we handle non-200 error codes appropriately.

Test plan: In addition to the included tests, I have an end-to-end test
which actually uses this fetcher to fully populate the mirror and then
generate a valid SourceCred graph.

This builds on API investigations
[here](https://github.com/sourcecred/sourcecred/issues/865#issuecomment-478026449),
and is general progress towards #865. Thanks to @erlend-sh, without whom
we wouldn't have a test instance.
2019-08-15 13:22:06 +02:00
Dandelion Mané 610ace0cff
chore(package): update webpack to version 4.39.2 (#1285) 2019-08-14 16:11:47 +02:00
William Chargin 68aad8b205
Remove non-standard bare-`catch` blocks (#1281)
Summary:
In ES6, the [`try` statement grammar][1] requires a catch parameter; the
parameter is only optional in the latest draft of ECMAScript, which is
of course not yet ratified as any actual standard.

Even though we don’t officially pledge to support Node 8, this is
currently the only breakage, and it’s easy enough to fix.

[1]: https://www.ecma-international.org/ecma-262/6.0/#sec-try-statement

Test Plan:
Running `yarn start` on Node v8.11.4 no longer raises a syntax error.

wchargin-branch: catch-parameter
2019-08-13 09:41:45 -07:00
Dandelion Mané e256b73f3b
Attempt to fix CI flakes (#1243) (#1282)
This is my latest salvo in trying to fix the persistent CI flakes we've
been having. They center on flow failing with `Out of retries,
exiting!`. Here's a representative failure [1].

My approach here is based on a discussion in a [GitHub thread] which
suggests that setting `server.max_workers=1` in the config can fix it.
Unfortunately, since it's in the flowconfig and is not a command line
option, I needed to fork the flowconfig into a CI and non-CI version.

Test plan: Merge it, and see if the flake goes away.

[1]: https://circleci.com/gh/sourcecred/sourcecred/1609?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link
[GitHub thread]: https://github.com/atlassian/react-beautiful-dnd/issues/1007
2019-08-13 18:22:03 +02:00
William Chargin 607a6d426d Fix type error in FileUploader (#1280)
Summary:
Introduced in #1277.

Test Plan:
Run `yarn start` and visit <http://localhost:8080/test/FileUploader/>.
Conduct the test plan as specified on that page.

wchargin-branch: fileuploader-target
2019-08-13 18:20:54 +02:00
Dandelion Mané 95b8974f6a
Make SourceCred a public package (#1284)
I'm mostly motivated by wanting to get greenkeeper lockfile
auto-updating working (see #1269) although this is also a first step
towards making SourceCred usable from NPM (#1232).

For now, see this as us making sure we claim the sourcecred package name
on npm (see: https://www.npmjs.com/package/sourcecred).

I also fixed the license spec so that it's valid SPDX.
2019-08-13 17:46:23 +02:00
Dandelion Mané 75bded3a1d
Update lockfile (#1283) 2019-08-13 17:39:50 +02:00
William Chargin 91ebe9c2b5 gitignore: remove OS-specific configurations (#1279)
Summary:
To elaborate a bit: The repository-level `.gitignore` file is for
artifacts that are generated _by the code/build of that project_. This
includes `node_modules/`, `bin/`, `build/`, etc. These should be
necessary for all users of the project.

The user-level `.gitignore_global` file is for files that _your system_
generates. These are swap files (`.swp` `.swo` `.swa` for Vim), file
system metadata (`.DS_Store` for macOS, `Thumbs.db` for Windows), trash
directories, etc.

(See `man gitignore` for details about the two files. Take a look at
[the `.gitignore` for Git itself][git-gitignore] as an example.)

[git-gitignore]: https://github.com/git/git/blob/master/.gitignore

It doesn’t make sense to put the latter category of patterns into the
project’s `.gitignore`. You can’t accommodate every programming
environment under the sun. The file would be hundreds of lines.

By removing these patterns from the `.gitignore`, we help teach users
about how to configure `.gitignore_global` to set up their own
environment properly, once and for all.

This reverts commit 816c954f3d.

Test Plan:
The `.gitignore` now only contains patterns specific to SourceCred.

wchargin-branch: gitignore-project-only
2019-08-13 17:34:40 +02:00
greenkeeper[bot] 027de6d3f0 chore(package): update flow-bin to version 0.105.0 2019-08-13 17:03:50 +02:00
greenkeeper[bot] e31485e7fc chore(package): update eslint-plugin-flowtype to version 4.0.0 2019-08-13 17:03:37 +02:00
Dandelion Mané 816c954f3d gitignore: ignore .DS_Store files
They are created by MacOS indexing.

Test plan: They no longer pollute my tree.
2019-08-13 16:26:15 +02:00
William Chargin 09493eb368 rasterize: replace backtick command substitution
Summary:
Backticks are discouraged relative to the `$(…)` form for command
substitution, because they are harder to read and do not nest without
exponential escaping:

```shell
$ foo=$(echo $(echo hi $(echo bye)))  # clear
$ foo=`echo \`echo hi \\\`echo bye\\\`\``  # hmm
```

In this context, command substitution should not be used at all; `PWD`
is a special variable that always contains the current working
directory. The new version of the code will be correct even if the
current working directory ends with whitespace that would be stripped
off by the command substitution.

Test Plan:
Prepended an `echo` to the relevant line, and verified that the script
has the same output before and after this change.

wchargin-branch: fix-backticks
2019-08-13 15:39:51 +02:00
Dandelion Mané a7ccf7ff6d Update logo
This adds a new version of the logo, based on the work by @ericronne in
PR #1261, but regenerated using an algorithmic approach, which can be
found in [this notebook]. Also, the color scheme has changed.

Thanks to @lbStrobbe for a lot of creative feedback, and to everyone who
participated in the [feedback thread] and the original [logo issue] on
GitHub.

Besides committing the rasterized assets, this commit also updates the
favicon.

[feedback thread]: https://discourse.sourcecred.io/t/more-logo-explorations/142
[this notebook]: https://observablehq.com/@decentralion/sourcecred-logo-explorations
[logo issue]: https://github.com/sourcecred/pm/issues/5
2019-08-09 14:28:23 +02:00
Eric Ronne d205fe5a99 Revised color logo 2019-08-08 16:53:35 +02:00
Dandelion Mané c62ddccfec
Release version 0.4.0 (#1271)
Test plan: `yarn test --full`
2019-08-07 20:12:11 +02:00
Dandelion Mané fae015496c
Include full projects on sourcecred.io (#1270)
This updates the deploys script so that we now load full projects for
@libp2p, @ipld, @sourcecred, and @filecoin-project.

I'd like to support @ipfs, but we need to tackle #1256 first.
2019-08-07 20:07:31 +02:00
Dandelion Mané 26c0910a1f
TimelineExplorer: Enable changing selected type (#1268)
The code is mostly ported from the legacy app. However, we no longer
assume that we are showing every type for every plugin. Instead, the
types are manually selected. For now, we permit the GitHub user type,
and the GitHub repo type, as these are the two types that are included
in filtered timeline cred.

Test plan: Manual inspection is necessary, since this frontend is mostly
untested. I've done that inspection. Also, `yarn test` passes.
2019-08-07 17:54:04 +02:00
Dandelion Mané a0ec3d65c6
Update `yarn.lock` (#1267)
Since Greenekeeper isn't updating it automatically.

Test plan: `yarn test`
2019-08-07 14:18:43 +02:00
greenkeeper[bot] baf2431f18 chore(package): update eslint to version 6.1.0 (#1245) 2019-08-07 13:48:31 +02:00
greenkeeper[bot] cc68b71029 chore(package): update eslint-plugin-react to version 7.14.3 (#1252) 2019-08-07 13:41:10 +02:00
greenkeeper[bot] 877fca416e chore(package): update eslint-plugin-import to version 2.18.1 (#1241) 2019-08-07 13:40:57 +02:00
greenkeeper[bot] 7d64b15519 chore(package): update webpack to version 4.37.0 2019-08-07 13:40:35 +02:00
greenkeeper[bot] 9a6c9bca3a chore(package): update eslint-plugin-flowtype to version 3.12.1 2019-08-07 13:35:54 +02:00
Dandelion Mané ee5f2a9a56 MapUtil.pushValue returns the array
Minor change to the API for MapUtil.pushValue. Now it returns the
resultant array. I've found this convenient in at least one case, and
previously we weren't returning anything, so it's a cheap change.

Test plan: Unit test added.
2019-08-06 21:36:42 +02:00
William Chargin 9d3fe3b80d yarn.lock: update out-of-date `flow-bin` entry
Summary:
In #1259, `flow-bin` was upgraded to 0.104.0 in `package.json`, but no
corresponding change was made in the lock file.

Test Plan:
Running `yarn` is now a no-op.

wchargin-branch: lock-flow-bin-0.104.0
2019-08-06 20:58:56 +02:00
William Chargin ee581f647f deps: pin an exact version of Prettier
Summary:
[Prettier docs] recommend pinning an exact version because their semver
policy does not extend to stylistic changes, and so patch releases may
change the formatting output.

Given some recent discussion about formatting skew of unknown cause,
this seems like a reasonable safety measure.

Generated with `yarn add --dev --exact prettier`.

[Prettier docs]: https://prettier.io/docs/en/install.html

wchargin-branch: prettier-exact
2019-08-06 12:49:00 +02:00
greenkeeper[bot] 744c11214d chore(package): update flow-bin to version 0.104.0 2019-07-27 18:49:14 +01:00
Dandelion Mané d5a1ca30b4 Fixup project for move of example repos
I moved sourcecred/example-git{,hub} to the @sourcecred-test org.

This commit fixes the build given that move.

I've realized that in #1233 I in-advertently made some Git tests that
depend on a snapshot un-updateable. I'm going to compound on that slight
technical debt by skipping the tests that depended on that snapshot. I
recognize and accept that I'll need to pay this down when I resuscitate
the git plugin.

Test plan: `yarn test --full`.
2019-07-23 02:36:28 +01:00
Dandelion Mané ca4fb2bc5d Remove deprecated commands and adapters
This commit removes the `pagerank` and `analyze` commands (both of which
never saw real usage), removes the outdated adapter-based `loadGraph`
method, and removes all traces of the analysis adapters.

It builds on work in #1233 and #1136.

Test plan: `yarn test --full` passes.
2019-07-23 01:31:18 +01:00
Dandelion Mané b4c2846ed0 Update CHANGELOG for #1233 2019-07-23 01:01:09 +01:00
Dandelion Mané c15e97b4d4 change the world: track projects not repos
This commit swaps usage over to the new implementation of `cli/load`
(the one that wraps `api/load`) and makes changes throughout the project
to accomodate that we now track instances by Project rather than by
RepoId.

Test plan: Unit tests updated; run `yarn test --full`. Also, for safety:
actually load a project (by whole org, why not) and verify that the
frontend still works.
2019-07-23 01:01:09 +01:00
Dandelion Mané e31269283a re-implement src/cli/load
The new implementation wraps `api/load`.

Test plan: I've ported over the tests from the old `cli/load`. Run `yarn
test`.
2019-07-23 01:01:09 +01:00
Dandelion Mané 1f7ee2ed1c deprecate cli/load
This commit deprecates `cli/load` so that we can write a new
implementation, and then make an atomic switch.

Test plan: `yarn test --full`
2019-07-23 01:01:09 +01:00
Dandelion Mané 4ae502bfd3 remove old-style git loading, and its testing
I'm re-organizing SC data to be oriented on the graph, rather than on
plugin-specific data structures. So there is no longer a need for the
git loading logic which orients around saving a repository.json file
that's been potentially merged across repos, or indeed the logic for
merging repositories at all. So I'm removing `git/loadGitData`,
`git/mergeRepository`, and relatives.

Test plan: `yarn test --full` passes.
2019-07-23 01:01:09 +01:00
Dandelion Mané 37b39a7e0a
remove dep on `mkdirp` (#1253)
There's no need for us to depend on `mkdirp`, because the `fs-extra`
module already has `fs.mkdirp` and `fs.mkdirpSync`. This commit removes
the dep from our `package.json`, and removes all explicit imports of it.

Test plan: `yarn test --full` passes. `git grep "import mkdirp"` has no
hits.
2019-07-23 00:28:49 +01:00
Dandelion Mané d0660c9366
add `api/load` (#1251)
This adds a new module, `api/load`, which implements the logic that will
underly the new `sourcecred load` command. The `api` package is a new
folder that will contain the logic that powers the CLI (but will be
callable directly as we improve SourceCred). As a heuristic, nontrivial
logic in `cli/` should be factored out to `api/`.

In the future, we will likely want to refactor these APIs to
make them more atomic/composable. `api/load` does "all the things" in
terms of loading data, computing cred, and writing it to disk. I'm going
with the simplest approach here (mirroring existing functionality) so
that we can merge #1233 and realize its many benefits more easily.

This work is factored out of #1233. Thanks to @Beanow for [review]
of the module, which resulted in several changes (e.g. organizing it
under api/, having the TaskReporter be dependency injected).

[review]: https://github.com/sourcecred/sourcecred/pull/1233#pullrequestreview-263633643

Test plan: `api/load` is tested (via mocking unit tests). Run `yarn test`
2019-07-22 15:41:24 +01:00
Dandelion Mané aa72bee217 Make `TaskReporter` an easily-tested interface
This commit refactors the `util/taskReporter` module so that
`TaskReporter` is an interface; the class previously called
`TaskReporter` is renamed to `LoggingTaskReporter`. We also export a
`TestTaskReporter` which implements the interface, and is very easy to
test.

The motivation: This will make it much easier to write tested code that
uses a `TaskReporter`, as now the test code can provide a
`TestTaskReporter` and check that all tasks get finished, that task
ids are as expected, etc.

Test plan: The `TestTaskReporter` is tested. Run `yarn test`.
2019-07-22 15:15:33 +01:00
Dandelion Mané 6bd7fe1154 Replace `Object.freeze` with `deepFreeze`
Throughout the codebase, we freeze objects when we want to ensure that
their properties are never altered -- e.g. because they are a plugin
declaration, or are being re-used for various test cases.

We generally use `Object.freeze`. This has the disadvantage that it does
not work recursively, so a frozen object's mutable fields and properties
can still be mutated. (E.g. if `const obj = Object.freeze({foo: []})`,
then `obj.foo.push(1)` will succeed in mutating the 'frozen' object).

Sometimes we anticipate this and explicitly freeze the sub-fields (which
is tedious); sometimes we forget (which invites errors). This change
simply replaces all instances of Object.freeze with [deep-freeze], so we
don't need to worry about the issue at all anymore.

Test plan: `yarn test` passes (after updating snapshots);
`git grep Object.freeze` returns no hits.

[deep-freeze]: https://www.npmjs.com/package/deep-freeze
2019-07-21 16:21:12 +01:00
Dandelion Mané e4c96f3a18 Add `github/loadGraph`
This is a replacement for `github/loadGithubData` which returns a
combined Graph rather than a combined RelationalView. This provides a
major benefit, which is that we can use the (robust) Graph merge logic
rather than the (buggy) relational view merge.

Test plan: This function is untested. It basically pipelines a few APIs
together. I think that flow is basically sufficient to validate that it
works, and writing a unit test will be frustrating (mostly will involve
re-integrating the funcitonality via mocks). A future commit makes this
part of the pipeline that generates snapshot tests, so it is de-facto
integration tested.
2019-07-21 15:38:10 +01:00
Dandelion Mané 0a34c8b036 add github/specToProject
This module builds on the project logic added in #1238, and makes it
easy to create projects based on a simple string configuration.
Basically, the spec `foo/bar` creates a project containing just the repo
foo/bar, and the spec `@foo` creates a project containing all of the
repos from the user/organization named foo.

This is pulled out of #1233, but I've enhanced it to support
organizations out of the box.

The method is thoroughly tested.
2019-07-21 13:12:34 +01:00
Dandelion Mané daa7409abb Add util/taskReporter
It's a lightweight utility for reporting task progress in a CLI.

It's inspired by execDependencyGraph.

Test plan: `yarn test`; unit tests included.
2019-07-21 12:32:38 +01:00
Dandelion Mané 0889a0a5d1 Use url encoding and make _getProjectIds async
Test plan: `yarn test --full` still passes. Also, I've ensured that the
async `_getProjectIds` is still usable in our webpack configs (via
modifying and testing the dependent commits).
2019-07-21 12:24:10 +01:00
Dandelion Mané 9b105ee4ce Add `core/project` and `core/project_io`
This creates a new `Project` type which will replace `RepoId` as the
index type for saving and loading data.

The basic data type is added to `project.js`. Rather than having a
`RepoIdRegistry`, I intend to infer the registry at build time by
scanning for available projects saved in the sourcecred directory. I've
added the `project_io` module for this task. It has methods for setting
up a project subdirectory, and loading the `Project` info from that
subdirectory.

To ensure that projects ids can be encoded even if they have symbols
like `/` and `@`, we base64 encode them.

To ensure that project ids can be retrieved at build time, the
`getProjectIds` method is factored out into its own plain ECMAScript
module. For all non-build time needs, it is re-exported from
`project_io`.

Test plan: Unit tests added; run `yarn test`.
2019-07-21 12:24:10 +01:00
Dandelion Mané aa28c932c5 Another stab at fixing CI flakiness
See #1243 for context. This is basically a more aggressive version of
pull #1230 -- instead of just running unit tests in isolation, we also
run flow in isolation, and kill the servers afterwards.

Test plan: See how this fares in CI :)
2019-07-19 15:35:44 +01:00