borg 1.4.4

  • Readme
  • Changelog
  • Example
  • Installing
  • 50

Dart borg Build Status codecov pubspec_lock version #

Dart borg is a command-line tool to support development teams working on large scale Dart and Flutter mono repositories.

Commands available in the latest release:

CommandDescription
probeChecks consistency of specified and resolved Dart dependencies across repository
evolveUpgrades all external dependencies consistently across repository
bootExecutes pub get / flutter packages get for multiple packages across repository
initCreates an initial borg configuration file to automate application of frequently used options

Feature roadmap:

versionMajor feature
1.5Ability to define commands in the configuration file
1.6List outdated packages (requires Dart 2.8)
1.7Pinning configuration of a new package with pubspec.lock without upgrading configuration of other packages in repository
1.8Upgrade of only selected (not all) external dependencies consistently across repository

Installation #

The tool is implemented in Dart, please make sure Dart runtime is installed on your system.

Type in the command line pub global activate borg

After this, you should be able to execute the tool from command-line: borg.

If the tool cannot be found, please make sure that your Dart system cache is in your PATH.

Command-line interface #

The tool scans repository for Dart packages and automatically finds them.

The command-line interface provides options to include and exclude locations for recursive scans (the glob syntax is supported).

The tool is self documented, please execute it to get detailed information on the command-line options:

$ borg
Command-line tool for consistent configuration management of Dart packages in a mono repository

Usage: borg <command> [arguments]

Global options:
-h, --help    Print this usage information.

Available commands:
  boot     Executes "pub get" for multiple packages in repository
  evolve   Upgrade Dart dependencies consistently across multiple packages
  init     Generates configuration file borg.yaml in current directory
  probe    Checks consistency of Dart dependendencies across multiple packages

Run "borg help <command>" for more information about a command.

Command: borg probe #

Inconsistency detection #

In case of detected inconsistencies the tool provides aggregated report on detected issues and returns with exit code 1:

$ borg probe
Scanning for pubspec.yaml files... 2 files found
Analyzing dependency specifications...

Scanning for pubspec.lock files... 2 files found
Analyzing dependencies...

yaml: inconsistent use detected
        Version 2.2.0 is used by:
                ./pubspec.lock
        Version 2.2.1 is used by:
                ./test/pubspec.lock

FAILUE: Inconsistent use of external dependencies detected!

Output in case of consistent configuration #

In case of consistent usage of dependencies the tool returns with exit code 0:

$ borg probe 
Scanning for pubspec.yaml files... 2 files found
Analyzing dependency specifications...

Scanning for pubspec.lock files... 2 files found
Analyzing dependencies...

SUCCESS: All packages use consistent set of external dependencies

Output in case of suspicious input #

The tool issues a warning and exits with code 2 in case scan did not find pubspec.lock files:

$ borg probe --exclude .
Scanning for pubspec.yaml files... 0 files found

WARNING: No configuration files selected for analysis

Command: borg evolve #

This command upgrades all external dependencies of all selected packages consistently across repository:

$ borg evolve
Scanning for pubspec.yaml files... 3 files found

Resolving 11 direct external dependencies used by all found packages...
        resolved 61 direct and transitive external dependencies

Commencing evolution of 3 Dart packages...
[1/3] Evolving . ...
        json_annotation: 3.0.0 => 3.0.1

[2/3] Evolving test/evolve_integration_test_sets/package_with_pubspec_lock ... => up-to-date
[3/3] Evolving test/evolve_integration_test_sets/package_without_pubspec_lock ...
        pubspec.lock does not exist, creating one... => up-to-date

SUCCESS: 3 packages have been processed

The command supports dry mode to preview upgrade without modifying existing pubspec files.

Path to Dart SDK #

Internally, borg relies on the Dart pub tool to manage configuration of Dart packages. By default, it assumes pub to be available at the path. If this is not the case, path to Dart SDK can be specified as a command-line argument:

borg evolve --dartsdk=~/dart

Flutter support #

borg supports repositories with apps using Flutter. For such repositories, path to Flutter SDK should be supplied as a command-line argument.

borg evolve --fluttersdk=dev/flutter

Alternatively, path to Flutter SDK can be set with the environment variable FLUTTER_ROOT. Usage of fluttersdk in borg command line is not required in this case.

Command: borg boot #

Executes pub get for multiple packages in a repository.

Packages to bootstrap can be specified as arguments. If no arguments supplied, the command bootstraps all scanned packages.

Borg supports bootstrapping of both Dart and Flutter packages:

  • Flutter packages are bootstrapped using flutter packages get command. The tool recognizes Flutter packages by their dependency on the package flutter. If path to the root of Flutter SDK is not specified, bootstrapping of such package results in fatal errors with message to the user.

  • Dart packages are always bootstrapped with pub get. The reason for this is that pub get has much higher performance than its Flutter counterpart.

Incremental bootstrapping #

Execution of pub get / flutter packages get can take several minutes for large repositories of tens and hundreds of packages. On the other hand, developer's workspace is updated typically in small steps, only several packages at a time. Therefore, there should be no need to bootstrap the entire repository all the time, only the packages with changed pubspec files and packages depending on them.

Every time borg boot is finished successfully, it records git commit at the end of its execution and stores to file .dart_tool/borg/context.yaml. When developer executes the command in incremental boostrapping mode (borg boot --mode=incremental), the tool compares the repository changes since the last successful boot and executes pub get / flutter packages get only for packages with changed configuration and packages depending on them.

In some cases incremental bootstrapping is not available and basic bootstrapping is enforced:

  • Developer uses command line to bootstrap specific packages
  • borg boot detects Dart version update since the last successful bootstrapping
  • borg boot detects Flutter SDK update since the last successful bootstrapping

Please note that borg boot --mode=incremental switches borg boot to incremental mode for subsequent runs. This means that you do not need to specify boot mode every time you run borg boot. boot borg --mode=basic switches back to the basic bootstrapping mode executing pub get / flutter packages get for all found packages.

Configuration file: borg.yaml #

In case configuration options have to be specified for every run of the tool, borg provides possibility to avoid long command lines with configuration file borg.yaml. Every time borg is executed, it checks out whether the file exists in the current directory, reads it out, and uses its content to provide default values for its arguments.

Since the configuration file defines default values for command-line arguments, it can be overriden by using command line.

The following configuration options can be specified:

YAML keyMeaning
includeList of locations to include for analysis (glob syntax supported)
excludeList of locations to exclude from analysis (glob syntax supported)
dart_sdkPath to Dart SDK
flutter_sdkPath to root directory of Flutter SDK

The initial configuration file can be generated by using borg init command:

$ borg init
Initial configuration file is created.

API #

If the standard command-line tool does not fit your use cases, its essential logic can be accessed via Dart API. In order to use it, just refer to the package borg as a dependency in your pubspec.yaml.

Please refer to the generated borg library documentation at pub.dev for details.

[1.4.4] - 2020-07-05 #

  • Production-grade incremental bootstrapping
  • Bootstrapping dependency analysis takes dependency overrides into account
  • Unit test coverage improvements

[1.4.3] - 2020-06-28 #

  • Improved performance of incremental bootstrapping for massive changes of packages configuration

[1.4.2] - 2020-06-08 #

Maturing of incremental bootstrapping implementation:

  • Correct handling of rolled back changes of pubspec files
  • Incremental bootstrapping is ignored when Dart version is changed between runs of borg boot
  • Incremental bootstrapping is ignored when Flutter SDK version is changed between runs of borg boot
  • Incremental bootstrapping is ignored when command line specifies packages to bootstrap
  • Incremental bootstrapping ignores previous bootstrapping of specific (not all) packages
  • Boot mode switch is persistent

[1.4.1] - 2020-06-04 #

  • Incremental bootstrapping takes dependencies between packages in the mono repository into account

[1.4.0] - 2020-06-04 #

  • Experimental support for incremental bootstrapping

[1.3.2] - 2020-06-01 #

  • Optimization: probe scans repository for packages only once
  • Optimization: more efficient scan of Flutter repositories by built-in filtering of generated Flutter plug-in packages in .symlinks directories
  • Optimization: Automatic detection of Dart packages in Flutter repositories and using faster pub get to bootstrap them i.s.o. flutter packages get

[1.3.1] - 2020-05-23 #

  • Bugfix: Incorrect bootstrapping of Flutter packages

[1.3.0] - 2020-05-23 #

  • borg boot -- Command to execute pub get for multiple packages across repository

[1.2.0+1] - 2020-05-20 #

  • README.md formatting fix

[1.2.0] - 2020-05-20 #

  • Configuration file support: borg.yaml

[1.1.0] - 2020-04-19 #

  • borg evolve -- command for consistent upgrade of all external dependencies across repository

[1.0.0] - 2020-04-02 #

  • Consistency check on package specifications in pubspec.yaml files

[0.1.2+1] - 2020-03-27 #

  • Dependency on args is relaxed to make compatible with stable Flutter release

[0.1.2] - 2020-03-27 #

  • Bugfix: Incorrect report generation

[0.1.1] - 2020-03-27 #

  • Bugfix: Dependency types are ignored during consistency analysis

[0.1.0] - 2020-03-27 #

  • Consistency check on use of Dart dependencies

example/main.dart

/*
 * MIT License
 *
 * Copyright (c) 2020 Alexei Sintotski
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

import 'package:args/command_runner.dart';

import 'src/commands/boot_command.dart';
import 'src/commands/evolve_command.dart';
import 'src/commands/init_command.dart';
import 'src/commands/probe_command.dart';

void main(List<String> args) => CommandRunner<void>(
      'borg',
      'Dart borg is a command-line tool to support development teams working on '
          'large scale Dart and Flutter mono repositories.',
    )
      ..addCommand(ProbeCommand())
      ..addCommand(EvolveCommand())
      ..addCommand(InitCommand())
      ..addCommand(BootCommand())
      ..run(args);

Use this package as an executable

1. Install it

You can install the package from the command line:


$ pub global activate borg

2. Use it

The package has the following executables:


$ borg

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  borg: ^1.4.4

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:borg/borg.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
0
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
50
Learn more about scoring.

We analyzed this package on Jul 8, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.13

Health suggestions

Format bin/src/assert_pubspec_yaml_consistency.dart.

Run dartfmt to format bin/src/assert_pubspec_yaml_consistency.dart.

Format bin/src/commands/boot_command.dart.

Run dartfmt to format bin/src/commands/boot_command.dart.

Format bin/src/commands/evolve_command.dart.

Run dartfmt to format bin/src/commands/evolve_command.dart.

Fix additional 28 files with analysis or formatting issues.

Additional issues in the following files:

  • bin/src/commands/init_command.dart (Run dartfmt to format bin/src/commands/init_command.dart.)
  • bin/src/commands/probe_command.dart (Run dartfmt to format bin/src/commands/probe_command.dart.)
  • bin/src/options/boot_mode.dart (Run dartfmt to format bin/src/options/boot_mode.dart.)
  • bin/src/options/verbose.dart (Run dartfmt to format bin/src/options/verbose.dart.)
  • bin/src/resolve_dependencies.dart (Run dartfmt to format bin/src/resolve_dependencies.dart.)
  • bin/src/scan_for_packages.dart (Run dartfmt to format bin/src/scan_for_packages.dart.)
  • bin/src/utils/git.dart (Run dartfmt to format bin/src/utils/git.dart.)
  • bin/src/utils/platform_version.dart (Run dartfmt to format bin/src/utils/platform_version.dart.)
  • bin/src/utils/print_dependency_usage_report.dart (Run dartfmt to format bin/src/utils/print_dependency_usage_report.dart.)
  • lib/src/compute_package_dependency_correction.dart (Run dartfmt to format lib/src/compute_package_dependency_correction.dart.)
  • lib/src/configuration/configuration.dart (Run dartfmt to format lib/src/configuration/configuration.dart.)
  • lib/src/configuration/configuration.g.dart (Run dartfmt to format lib/src/configuration/configuration.g.dart.)
  • lib/src/configuration/factory.dart (Run dartfmt to format lib/src/configuration/factory.dart.)
  • lib/src/configuration/options/dart_sdk.dart (Run dartfmt to format lib/src/configuration/options/dart_sdk.dart.)
  • lib/src/configuration/options/flutter_sdk.dart (Run dartfmt to format lib/src/configuration/options/flutter_sdk.dart.)
  • lib/src/configuration/options/paths.dart (Run dartfmt to format lib/src/configuration/options/paths.dart.)
  • lib/src/context/borg_boot_context.dart (Run dartfmt to format lib/src/context/borg_boot_context.dart.)
  • lib/src/context/borg_context.dart (Run dartfmt to format lib/src/context/borg_context.dart.)
  • lib/src/context/borg_context_factory.dart (Run dartfmt to format lib/src/context/borg_context_factory.dart.)
  • lib/src/dart_package/dart_package.dart (Run dartfmt to format lib/src/dart_package/dart_package.dart.)
  • lib/src/dart_package/discover_dart_packages.dart (Run dartfmt to format lib/src/dart_package/discover_dart_packages.dart.)
  • lib/src/find_inconsistent_dependencies.dart (Run dartfmt to format lib/src/find_inconsistent_dependencies.dart.)
  • lib/src/find_inconsistent_dependency_specs.dart (Run dartfmt to format lib/src/find_inconsistent_dependency_specs.dart.)
  • lib/src/generic_dependency_usage_report.dart (Run dartfmt to format lib/src/generic_dependency_usage_report.dart.)
  • lib/src/get_all_external_package_dependency_specs.dart (Run dartfmt to format lib/src/get_all_external_package_dependency_specs.dart.)
  • lib/src/impact/impact_based_on_pubspec_yaml.dart (Run dartfmt to format lib/src/impact/impact_based_on_pubspec_yaml.dart.)
  • lib/src/utils/file_finder.dart (Run dartfmt to format lib/src/utils/file_finder.dart.)
  • lib/src/utils/file_io.dart (Run dartfmt to format lib/src/utils/file_io.dart.)

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.7.0 <3.0.0
args ^1.5.0 1.6.0
collection ^1.14.0 1.14.13 1.15.0-nnbd
functional_data ^0.3.0 0.3.0
glob ^1.2.0 1.2.0
json2yaml ^1.0.0 1.0.1
meta ^1.1.0 1.2.1
path ^1.6.0 1.7.0
plain_optional ^0.1.0 0.1.3
pubspec_lock ^2.0.0 2.0.1
pubspec_yaml ^2.0.0 2.0.1
yaml ^2.2.0 2.2.1
Transitive dependencies
async 2.4.2
charcode 1.1.3
js 0.6.2
node_interop 1.1.1
node_io 1.1.1
pedantic 1.9.1
source_span 1.7.0
string_scanner 1.0.5
sum_types 0.2.1+2
term_glyph 1.1.0
Dev dependencies
build_runner ^1.9.0
dependency_validator ^1.4.0
functional_data_generator ^0.3.0
test ^1.14.0
test_coverage ^0.4.0