• Stars
    star
    74
  • Rank 414,267 (Top 9 %)
  • Language
    Dart
  • License
    Other
  • Created almost 9 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Centralized tooling for Dart projects. Consistent interface across projects. Easily configurable.

Dart Dev Tools

Pub Build Status

Centralized tooling for Dart projects. Consistent interface across projects. Easily configurable.


Quick Start

Upgrading from v2? Check out the upgrade guide.

Looking for detailed guides on the available tools? Check out the additional docs.

Add dart_dev as a dev dependency in your project:

dart pub add --dev dart_dev

By default, this provides three core tasks:

  • analyze
  • format
  • test

Run any of these tools via the dart_dev command-line app:

$ dart run dart_dev analyze
[INFO] Running subprocess:
dart analyze .
--------------------------
Analyzing dart_dev...
No issues found!

We recommend adding a ddev alias:

alias ddev='dart run dart_dev'

Additional Dart developer tools can be added and every tool can be configured. To do this, create a tool/dart_dev/config.dart file like so:

// tool/dart_dev/config.dart
import 'package:dart_dev/dart_dev.dart';

final config = {
  // See the "Shared Configuration" section for more info on this.
  ...coreConfig,

  // Override or add new tools and configure them as desired.
  'analyze': AnalyzeTool(),
  'format': FormatTool(),
  'test': TestTool(),
  'serve': WebdevServeTool()
    ..webdevArgs = ['example:8080'],
};

Motivation & Goal

Most Dart projects eventually share a common set of development requirements (e.g. static analysis, formatting, test running, serving, etc.). The Dart SDK along with some core packages supply the necessary tooling for these developer tasks (e.g. dart analyze, dart format, or dart test).

While the core tooling gets us far, there are two areas in which we feel it falls short:

  1. Inconsistencies across projects in how these tools must be used in order to accomplish common developer tasks.

  2. Functionality gaps for more complex use cases.

With dart_dev, we attempt to address #1 by providing a way to configure all of these common developer tasks at the project level, and #2 by composing additional functionality around existing tools.

This package is built with configurability and extensibility in mind, with the hope that you and your teams will find value in creating your own tools and shared configurations. Ideally, you or your team can settle on a shared configuration that individual projects can consume; projects with unique requirements can tweak the configuration as necessary; and developers can rely on the convention of a simple, consistent command-line interface regardless of the project they are in.

Project-Level Configuration

Every task should be able to be configured at the project-level so that any variance across projects becomes a configuration detail that need not be memorized or referenced in order to run said task.

Consider formatting as an example. The default approach to formatting files is to run dartfmt -w .. But, some projects may want to exclude certain files that would otherwise be formatted by this command. Or, some projects may want to use pub run dart_style:format instead of dart format. Currently, there is no project-level configuration supported by the formatter, so these sorts of things just have to be documented in a README.md or CONTRIBUTING.md.

With dart_dev, this can be accomplished like so:

// tool/dart_dev/config.dart
import 'package:dart_dev/dart_dev.dart';
import 'package:glob/glob.dart';

final config = {
  'format': FormatTool()
    ..exclude = [Glob('lib/src/**.g.dart')]
    ..formatter = Formatter.dartStyle,
};
$ ddev format
[INFO] Running subprocess:
dart run dart_style:format -w <3 paths>
--------------------------------------
Unchanged ./lib/foo.dart
Unchanged ./lib/src/bar.dart
Formatted ./lib/src/baz.dart

Extending/Composing Functionality

Using existing tooling provided by (or conventionalized by) the Dart community should always be the goal, but the reality is that there are gaps. Certain use cases can be made more convenient and new use cases may arise.

Consider test running as an example. For simple projects, dart test is sufficient. In fact, the test package supports a huge amount of project-level configuration via dart_test.yaml, which means that for projects that are properly configured, dart test just works.

Unfortunately, at this time, projects that rely on builders must run tests via dart run build_runner test. Based on the project, you would need to know which test command should be run.

With dart_dev, the TestTool handles this automatically by checking the project's pubspec.yaml for a dependency on build_test. If present, tests will be run via dart run build_runner test, otherwise it falls back to the default of dart test.

# In a project without a `build_test` dependency:
$ ddev test
[INFO] Running subprocess:
dart test
----------------------------
00:01 +75: All tests passed!


# In a project with a `build_test` dependency:
$ ddev test
[INFO] Running subprocess:
dart run build_runner test
----------------------------
[INFO] Generating build script completed, took 425ms
[INFO] Creating build script snapshot... completed, took 13.6s
[INFO] Building new asset graph completed, took 960ms
[INFO] Checking for unexpected pre-existing outputs. completed, took 1ms
[INFO] Running build completed, took 12.4s
[INFO] Caching finalized dependency graph completed, took 71ms
[INFO] Creating merged output dir `/var/folders/vb/k8ccjw095q16jrwktw31ctmm0000gn/T/build_runner_testBkm6gS/` completed, took 260ms
[INFO] Writing asset manifest completed, took 3ms
[INFO] Succeeded after 12.8s with 1276 outputs (2525 actions)
Running tests...

00:00 +75: All tests passed!

Additionally, TestTool automatically applies --build-filter options to the dart run build_runner test command to help reduce build time and speed up dev iteration when running a subset of the available tests.

Generally speaking, these dart tool abstractions provide a place to address functionality gaps in the underlying tools or make certain use cases more convenient or efficient.

Shared Configuration

This package provides coreConfig as a minimal base configuration of dart_dev tools. It is the default configuration if your project does not have a tool/dart_dev/config.dart.

This shared config contains the following targets:

  • ddev analyze
  • ddev format
  • ddev test

The actual configuration of each of these targets can be found here: lib/src/core_config.dart

coreConfig is just a getter that returns a Map<String, DevTool> object, so extending it or customizing it is as easy as creating your own Map, spreading the shared config, and then adding your own entries:

// tool/dart_dev/config.dart
import 'package:dart_dev/dart_dev.dart';

final config = {
  ...coreConfig,

  // Override a target by including it after `...coreConfig`:
  'format': FormatTool()
    ..formatter = Formatter.dartFormat,

  // Add a custom target:
  'github': ProcessTool(
      'open', ['https://github.com/Workiva/dart_dev']),

  // etc.
};

Format on save

dart_dev can be used to facilitate formatting on save inside of JetBrains IDEs. For setup instructions, see below.

A Note on VS Code

A VS code extension exists to run either dartfmt or over_react_format on save. For information on it, see its project. However, that VS Code extension does not run dart_dev, but rather has its own logic to run a formatting command.

JetBrains IDEs (WebStorm, IntelliJ, etc.)

Webstorm exposes a File Watcher utility that can be used to run commands when a file saves. For this approach, all you need to do is set up the file watcher. Shoutout to @patkujawa-wf for creating the original inspiration of this solution!

NOTE: Before setting up the watcher, there are three basic limitations when using it:

  1. dart_dev's minimum must be at least version 3.6.0 in the projects that uses the watcher.
  2. Only dart_dev's FormatTool and OverReact Format's OverReactFormatTool are supported.
  3. Literals need to be used when possible when configuring the formatter. This primarily pertains to the formatter tool itself and setting the property that is responsible for line-length. For example:
    // Good
    final Map<String, DevTool> config = {
      // ... other config options
      'format': FormatTool()
        ..formatter = Formatter.dartStyle
        ..formatterArgs = ['-l', '120'],
    };
    
    // Bad
    
    // Example 1: Line-length as a variable
    const lineLength = 120;
    
    final Map<String, DevTool> config = {
      // ... other config options
      'format': FormatTool()
        ..formatter = Formatter.dartStyle
        ..formatterArgs = ['-l', lineLength],
    };
    
    // Example 2: Args as a variable
    const formatterArgs = ['-l', '120'];
    
    final Map<String, DevTool> config = {
      // ... other config options
      'format': FormatTool()
        ..formatter = Formatter.dartStyle
        ..formatterArgs = formatterArgs,
    };
    
    // Example 3: Formatter as a variable
    final formatter = FormatTool()
        ..formatter = Formatter.dartStyle
        ..formatterArgs = ['-l', '120'];
    
    final Map<String, DevTool> config = {
      // ... other config options
      'format': formatter,
    };

Setting Up the File Watcher

  1. Go into Webstorm's preferences. It doesn't matter what project you do this in, as you'll ultimately want to make the watcher global. More on that later, though!

  2. Navigate to the "File Watchers" settings. This is under "Preferences > Tools > File Watchers". The File Watcher pane should look something like:

    File Watcher Pane
  3. Clicking on the import icon on the bottom toolbar.

  4. Import the format_on_save.xml file found in this project, at "dart_dev/tool/file_watchers/format_on_save.xml".

  5. After importing, change the watcher scoping (AKA "level") to Global on the right hand side under the "level" column, which makes the watcher available for use in all projects.

  6. In each project, you will also have to enable the watcher by checking the box on the file watcher's row.

For additional reference on how the watcher is set up, see JetBrains File Watcher Configuration.

JetBrains File Watcher Configuration

Final File Watcher Configuration

  1. The Name: Webstorm treats this like the process name, so it's the identifier that will be used to display any output that the process is running. It can be whatever you like!
  2. File Type: Dart, since that's what the formatter was built for.
  3. Scope: Project Files will produce the desired effect, but if a different option works better for you then feel free! For more information on scoping, see the docs.
  4. Program: The executable to run. In this case, it can just be pub. If there are any issues, providing a full path to the executable may have the desired outcome. For pub, this is most likely /usr/local/bin/pub.
  5. Arguments: The rest of the command, and by default should be run dart_dev hackFastFormat "$FilePathRelativeToProjectRoot$". Here's the breakdown:
    • run dart_dev hackFastFormat: Simply the process to run.
    • "$FilePathRelativeToProjectRoot$": The environment variable that will target only the changed file.
  6. Output Paths to Refresh: "$FilePathRelativeToProjectRoot$".
  7. Working Directory: $ContentRoot$.
  8. Advanced Options: Uncheck all the boxes. Again, if you experiment and find having some of them checked is better then feel free! However, the expected behavior occurs when none of them are checked.

More Repositories

1

go-datastructures

A collection of useful, performant, and threadsafe Go datastructures.
Go
7,280
star
2

eva

A distributed database-system implementing an entity-attribute-value data-model that is time-aware, accumulative, and atomically consistent
Clojure
561
star
3

over_react

A library for building statically-typed React UI components using Dart.
Dart
420
star
4

react-dart

Dart Bindings for React JS
JavaScript
409
star
5

frugal

Thrift improved
Go
139
star
6

built_redux

an implementation of redux written in dart that enforces immutability
Dart
126
star
7

dart_codemod

A library that makes it easy to write and run automated code modifications on a codebase.
Dart
60
star
8

dependency_validator

A tool to help you find missing, under-promoted, over-promoted, and unused dependencies.
Dart
56
star
9

state_machine

Easily create a finite state machine and define legal state transitions. Listen to state entrances, departures, and transitions.
Dart
56
star
10

go-rest

A Go library that makes it easy to build a flexible and (mostly) unopinionated REST API with little ceremony.
Go
48
star
11

opentelemetry-dart

Dart
45
star
12

furious

Fast and modular async task library for Google App Engine.
Python
37
star
13

w_flux

A Dart app architecture library with uni-directional data flow inspired by RefluxJS and Facebook's Flux.
Dart
25
star
14

morphe

A Clojure utility for defining and applying aspects to function definitions.
Clojure
25
star
15

w_transport

A platform-agnostic transport library for sending and receiving data over HTTP and WebSocket.
Dart
23
star
16

aws-lambda-fsm-workflows

A Python framework for developing finite state machine-based workflows on AWS Lambda.
Python
21
star
17

dart_to_js_script_rewriter

A pub transformer that Rewrites Dart script tags to JavaScript script tags, eliminating 404s and speeding up initial loads. Use when building for deployment.
Dart
21
star
18

go-hystrimp

An ergonomic implementation of Hystrix fault-tolerance principles for Go developers.
Go
19
star
19

w_module

Base module classes with a well defined lifecycle for modular Dart applications.
Dart
18
star
20

fluri

Fluri is a fluent URI library for Dart built to make URI mutation easy.
Dart
18
star
21

gae-financials

Simple demo app to illustrate developing real world applications on Google App Engine.
Python
18
star
22

platform_detect

A library for detecting browser and platform type and version.
Dart
17
star
23

thrift-nats

A library that adds support for using NATS as a Thrift RPC transport.
Go
14
star
24

wf-uicomponents

Mobile-optimized, composable UI components that support a rich HTML5 user experience.
JavaScript
13
star
25

wGulp

Opinionated Suite of Gulp Tasks for JavaScript and TypeScript projects.
JavaScript
12
star
26

utiliva

A collection of helpful little utilities for Clojure.
Clojure
11
star
27

webdev_proxy

A simple HTTP proxy for the webdev serve command (a tool authored by the dart team) that adds support for rewriting certain requests, namely rewriting 404s to instead serve the root index (/index.html). This allows developers to work on browser applications (like our own) that use HTML5 routing while still being able to refresh and/or navigate directly to deep links.
JavaScript
11
star
28

r_tree

A recursive RTree library written in Dart.
Dart
10
star
29

scip-dart

Dart
10
star
30

opentracing_dart

This library is the Open Tracing API written in Dart. It is intended for use both on the server and in the browser.
Dart
10
star
31

w_common

A collection of helpful utilities for use in Dart projects.
Dart
10
star
32

styleguide

9
star
33

pdfjs_dart

Dart bindings for Mozilla's PDF.js library
JavaScript
7
star
34

wf-common

A collection of helpful utilities for use in JavaScript projects.
JavaScript
6
star
35

flowgraph

A Clojure library for fast, concurrent, asynchronous data processing using directed graphs. Decursus supports cyclic graphs. Though it is not distributed, it does have primitive tools for minimizing communication overhead in the event that some processing steps involve calls to distributed resources.
Clojure
6
star
36

over_react_test

A library for testing OverReact components
Dart
6
star
37

dart_transformer_utils

Utilities relating to code generation, Dart analyzer, logging, etc. for use in Pub transformers.
Dart
6
star
38

w_service

Dart
5
star
39

react_testing_library

Dart bindings for the JS dom-testing-library and react-testing-library packages, which provide simple and complete DOM/React testing utilities that encourage good testing practices.
Dart
5
star
40

tesserae

A Clojure library that abstracts over promises, futures, delays, etc. with chaining and cancellations.
Clojure
4
star
41

w-mobile-kit

A Swift library containing various custom UI components to provide functionality outside of the default libraries.
Swift
4
star
42

wf-grunt

Opinionated Suite of Grunt Tasks for JavaScript and TypeScript projects.
JavaScript
4
star
43

goverge

A golang multi package coverage reporting tool.
Python
3
star
44

workiva_analysis_options

Workiva's shared Dart static analysis options
Dart
3
star
45

autoPaw

JavaScript
3
star
46

over_react_codemod

Codemods to help consumers of over_react automate the migration of UI component code.
Dart
3
star
47

paw

A touch / touch gesture simulation library for JavaScript.
JavaScript
3
star
48

sockjs-dart-client

A Dart client library for SockJS.
Dart
3
star
49

lsif_indexer

Dart
2
star
50

eva-client-service

The Eva client service is an Eva peer which exposes Eva functionality to other languages through a REST interface.
Java
2
star
51

font_face_observer

Load and unload fonts in the browser with a Promise based API. Simple, small and efficient. It will use the FontFace api if available, otherwise it falls back to a Dart port of https://github.com/bramstein/fontfaceobserver
Dart
2
star
52

sockjs_client_wrapper

A Dart wrapper around the SockJS Client. Uses the js Dart package to interop with the JS lib.
JavaScript
2
star
53

eva-catalog

Provides a central repository (and client) for handling the configuration maps used to connect to EVA
Clojure
1
star
54

lazy-tables

A set of tools for lazy relational algebra
Clojure
1
star
55

test_html_builder

Dart builder that generates HTML files from templates for dart tests.
Dart
1
star
56

abide

A command line tool to manage analysis_options.yaml and check if it abides by requirements.
Dart
1
star
57

barometer

A thin clojure wrapper over Coda Hale's metrics library for the JVM.
Clojure
1
star
58

ichnaie

A handful of Clojure utilities for easing project integration with the OpenTracing API
Clojure
1
star
59

recide

Provides utilities for defining standard ex-info forms, as well as the capacity for checking at compile-time that they are being used as intended
Clojure
1
star