pkgraph 3.0.0 pkgraph: ^3.0.0 copied to clipboard
A tool for studying and visualizing Dart package dependencies.
pkgraph #
This tool allows the user to gather Dart package data from a pub server or local package and load the dependency graph into a Neo4j database. It is a work-in-progress, additional documentation will be forthcoming.
For now, it works, though it isn't terrible efficient.
Running #
To run, just give it a package name and let it churn for awhile.
Note that right now you'll need to have Neo4j running on localhost
,
and it will need to have authentication turned off. There is a script
in the scripts/
directory that will run Neo4j, appropriately
configured, in a Docker container.
pub run pkgraph w_common
It is also possible to start your traversal at a local package or
application that may not be published to a pub server. Just pass
the --local
flag and any package names you pass will be interpreted
as local paths to directories that contain pubspec.yaml
files,
presumably Dart packages.
pub run pkgraph --local projects/secret_dart_app
If you're interested in the actual dependency versions resulting from the pub
solver, it is possible to create SOLVED_TO
edges between the version of the
package you're interested in and the solved dependency versions. Note that it
is only possible to do this with a local package since it requires the
pubspec.lock
file.
pub run pkgraph --local --solved projects/secret_dart_app
Example Queries #
Once you have some data loaded into a Neo4j database, what can you do with it? There are some examples that might be useful or inspirational.
match (:Package {name: "w_common"})
-[:HAS_VERSION]->(:Version)-[:MAY_USE]->(:Version)<-[:HAS_VERSION]-
(d:Package)
return distinct d.name
The query above will find all packages that are depended upon by at
least one version of the w_common
package.
match (:Source {url: "https://pub.dartlang.org"})<-[:HOSTED_ON]-
(:Package {name: "state_machine"})-[:HAS_VERSION]->
(state_machine:Version)-[:MAY_USE]->
(w_common:Version)<-[:HAS_VERSION]-
(:Package {name: "w_common"})
return state_machine.version as state_machine,
collect(w_common.version) as w_common
This query will display a table of each available version of the
state_machine
that depends on the w_common
package along with the
possible versions of the w_common
package that it can use.
match (p:Package)-[:HAS_VERSION]-(v:Version)
where v.dart2 = true
return p.name as package, collect(v.version) as versions
order by p.name asc
Dart 2 is out, have you heard? This query returns all the packages that support Dart 2 and a list of specific versions that for each.
Known Issues #
In theory, the queries the tool runs should be idempotent, and should just update nodes with new data. This means you should be able to run it against an already-populated database without any trouble.
However, I haven't verified this and there are no tests for it, so it is probably safer to blow away your database before re-running. Or you could add a test suite, whatever suits you.
Future Work #
In addition to the work items listed below, there are, let's say ample, additional items sprinkled throughout the source code.
- Handle git dependencies
- Parse author strings when possible to separate the name and email
- Allow a combination of local, pub, and even git packages
- Serialize the package version cache for reuse on subsequent runs
Feel free to report issues if you find bugs or have suggestions to improve the tool.
Roadmap #
Eventually the tool should be able to run as a cron job and pull in a variety of packages of mixed type (local, public, and private). I'd like it to also be able to execute a handful of potentially useful queries and display results in a reasonable fashion. A nifty web interface to view those results and maybe even control the tool itself would be bonus points.