d is a CLI tool to help manage multi-packages workspace - mostly flutter
workspace. d is written typescript and powered by deno. We decided deno
as the language for d carefully. The main reason is not to has any dependency
on dart and flutter.
melos is a very powerful tool to help manage multi-packages workspace.
The biggest weak point of melos is that it depends on dart and dart's
third-party libraries even though melos is a tool to manage dart/flutter
projects. Therefore, sometimes, melos users might run into problems regarding
to dart/flutter pub get or melos bootstrap.
This project is under developing actively.
- d
- x86_64
- arm64
- x86_64
- arm64: Thanks to LukeChannings/deno-arm64
$ curl -fsSL https://d-install.jerry.company | bashIf you are a bash or a zsh user, you may need to add the following to the
end of your ~/.bashrc or ~/.zshrc:
export D_HOME="$HOME/.d"
export PATH="$D_HOME/bin:$PATH"If you are a fish user, please execute the following:
$ mkdir -p $HOME/.config/fish/conf.d
$ echo "set -gx D_HOME $HOME/.d" \
> $HOME/.config/fish/conf.d/d.fish
$ exec $SHELL -l
$ fish_add_path $D_HOME/binYou can install the specific version of d like:
$ curl -fsSL https://d-install.jerry.company | bash -s vX.Y.ZPlease find the released versions at https://github.com/fenv-org/d/releases.
The install script installs d to $HOME/.d directory by default. However, you
also specify another location like:
$ curl -fsSL https://d-install.jerry.company \
| D_INSTALL_DIR=[other_directory] bashIf there already exists any other CLI command d in your shell environment, you
can install d as any other name instead of d. For example, oh-my-zsh has a
pre-defined zsh function d to show directory history. In this case, the
feature will be useful.
To give any other name to d, sets D_CLI environment variable.
echo 'export D_CLI=other_command` >> ~/.bashrcThe above is an example for bash users. Please add D_CLI according to your
favorite shell.
And then, install d according to above installation instructions. d
installer will install d with the name you gave instead of d.
Let's assume the workspace's directory structure is:
workspace
├> app
│ └> pubspec.yaml
└> packages
├> package-a
│ └> pubspec.yaml
├> package-b
│ └> pubspec.yaml
├> package-c
│ └> pubspec.yaml
└> package-d
├> pubspec.yaml
└> example
├> ios
├> android
└> pubspec.yaml
And the dependency relations are:
apprequirespackage-bandpackage-cpackage-brequirespackage-aandpackage-dpackage-crequirespackage-d
d CLI needs a configuration file d.yaml. You can place the file any where in
the repository.
If you place d.yaml under app, the d.yaml should look like:
version: v1
name: "Workspace name here"
packages:
include:
- .
- ../packages/**
exclude:
- "*example*"Or if you place d.yaml file under workspace, the d.yaml should look like,
instead:
version: v1
name: "Workspace name here"
packages:
include:
- app
- packages/**
exclude:
- "*example*"Then, we need to specify dependency relations among packages in pubspec.yaml
of each packages. Just leave the dependent package names.
-
workspace/app/pubspec.yaml... dependencies: ... package-b: # No need to specify "path". `d` will take care on behalf of you. package-c: ... ...
-
workspace/packages/package-b/pubspec.yamlname: package-b ... dependencies: ... package-a: package-d: ... ...
-
workspace/packages/package-c/pubspec.yamlname: package-c ... dependencies: ... package-d: ... ...
To analyze the dependencies among linked packages, you should run d bootstrap
when you initially make a workspace and whenever the dependencies among managed
packages are changed. d bootstrap does 1. analyzing the dependencies among
packages, 2. generating pubspec_overrides.yaml when needed, and 3. running
flutter pub get.
You can run it on any child directory of the directory that has d.yaml file.
d will find the nearest d.yaml file from the current working directory to
upward.
workspace/app>$ d bs # bs is an alias of `bootstrap`.Then, d will generate .d directory on the workspace root and
pubspec_overrides.yaml files on some directories. Hence, we recommend to list
up .d/ and pubspec_overrides.yaml to .gitignore file.
d supports to define functions in d.yaml and execute them with d func
command.
version: v1
name: ...
packages: ...
functions:
<function_name>:
description: "Describe what this function is" # Optional
exec: "Write bash scripts here" # Mandatory
options: # Optional
earlyExit: true/false # Defaults to `true`.
concurrency: positive integer # Defaults to `5`.
# Package filters
includeHasFile: string array
excludeHasFile: string array
includeHasDir: string array
excludeHasDir: string array
# Dependency filters
includeDependency: string array
excludeDependency: string array
includeDirectDependency: string array
excludeDirectDependency: string array
includeDevDependency: string array
excludeDevDependency: string arrayThe function in d supports patterns and arguments as well.
functions:
echo:{abcd}:{efgh}:
description: echo strings
exec: |
echo "abcd=$abcd"
echo "efgh=$efgh"
echo '$1='$1
echo '$2='$2
echo "package_name=$PACKAGE_NAME"
options:
includeHasFile:
- pubspec.yaml
excludeHasFile:
- pubspec_overrides.yaml
includeDependency:
- flutterFor example, assuming we have the above sample function, we can run
d func echo:hello:world -- good night. In that case, $abcd and $efgh will
be replaced with hello and world respectively. And, $1 and $2 will be
replaced with good and night respectively.
This feature will enable to write the following function:
functions:
build:{platform}:{phase}:{flavor}:
exec: flutter build $platform --$phase --flavor=$flavor $@
options:
includeDependency:
- flutter$ d func build:ipa:release:store -- --no-codesignbootstrap is a command to find and link packages specified in d.yaml. After
bootstrapping, d can run various commands for each linked packages
considering their dependency relationship.
bootstrap supports package filters.
$ d bootstrap [--config <PATH-TO-d.yaml>]
# or
$ d bs [--config <PATH-TO-d.yaml>]pub is a command to run flutter pub <subcommand> [args...] command in each
bootstrapped packages. You can run any arbitrary flutter pub's subcommand with
this command.
pub supports package filters and
dependency filters.
$ d pub [--config <PATH-TO-d.yaml>] get
$ d pub [--config <PATH-TO-d.yaml>] upgradebuild_runner is a command to run dart run build_runner build/run/clean
command in every bootstrapped package where has a dev dependency on the
build_runner package. br is an alias of build_runner.
build_runner supports package filters and
dependency filters.
-
build_runner build$ d build_runner build --delete-conflicting-outputs # or shortly $ d br b -d -
build_runner run$ d build_runner run --delete-conflicting-outputs \ '$WORKSPACE_PATH'/target.dart -- \ [script args...] # or shortly $ d br r -d \ '$WORKSPACE_PATH'/target.dart -- \ [script args...] -
build_runner clean$ d build_runner clean # or shortly $ d br c
run is a command to run any arbitrary command in every bootstrapped package.
run supports package filters and
dependency filters.
$ d run -- 'pwd'$ d run --no-early-exit \
--id "ios" \
--if "ios/Podfile" \
-- \
'cd ios
pod install || pod install --repo-update'$ d run \
-- \
'
set -x
echo $WORKSPACE_PATH
echo $PACKAGE_PATH
echo $PACKAGE_NAME
'func is a command that run a pre-defined function in d.yaml. func supports
package filters and
dependency filters.
Refer to the
How to define functions in d.yaml section
for more information.
test is a command to run flutter test [args...] command in every
bootstrapped package that has any file matching test/**/*_test.dart.
test supports package filters and
dependency filters.
$ d test --no-early-exit \
--reporter expanded \
--file-reporter \
json:'$WORKSPACE_PATH'/reports/tests_'$PACKAGE_NAME'.jsongraph is a command to describe the dependency relationship among linked
packages. graph command can be executed even if not bootstrapped yet.
$ d graphclean is a command to remove files that are automatically generated by d
such as a bootstrap cache directory .d/ and pubspec_overrides.yaml files.
In addition, By specifying -f or --flutter, d can run flutter clean for
each package.
# Remove auto-generated files. You need to run `d bootstrap` again.
$ d clean
# or
# Run `flutter clean` as well as removing auto-generated files.
$ d clean [--flutter]update is a command to self-update the d CLI or to list the available
versions.
# Updates `d` to the latest version.
$ d update
# Updates `d` to the specific version `X.Y.Z`.
# Downgrade as well as upgrade is supported.
$ d update vX.Y.Z# Show all available versions.
$ d update [--show-list | -l][--early-exit]:- Exit as soon as possible when any failure happens on any package.
- By default, enabled.
[--no-early-exit]:- Unlikely
--early-exit, execute the given command in all packages even though runs into any kind of failure in a package.
- Unlikely
[-c|--concurrency] <parallelism>:- Specifies the maximum parallelism. Defaults to 5.
[--include-has-file|--if] <fileOrGlob>:- Includes only packages where have any file that specifies the given pattern. The pattern can be a relative file path from the package root directory or a relative glob pattern from the package root directory.
- Can be repeated.
- Prioritize
--exclude-has-fileoption.
[--exclude-has-file|--ef] <fileOrGlob>:- Excludes packages where have any file that specifies the given pattern. The pattern can be a relative file path from the package root directory or a relative glob pattern from the package root directory.
- Can be repeated.
[--include-has-dir|--id] <dirOrGlob>:--idis an alias.- Includes only packages where have any directory that specifies the given pattern. The pattern can be a relative directory path from the package root directory or a relative glob pattern from the package root directory.
- Can be repeated.
- Prioritize
--exclude-has-diroption.
[--exclude-has-dir|--ed] <dirOrGlob>:- Excludes packages where have any directory that specifies the given pattern. The pattern can be a relative directory path from the package root directory or a relative glob pattern from the package root directory.
- Can be repeated.
--include-dependency:- Includes only packages where have a dependency on the given package.
- Can be repeated.
- Prioritize
--exclude-dependencyoption.
--exclude-dependency:- Excludes packages where have a dependency on the given package.
- Can be repeated.
--include-direct-dependency:- Includes only packages where have a "direct" dependency on the given package.
- Can be repeated.
- Prioritize
--exclude-direct-dependencyoption.
--exclude-direct-dependency:- Excludes packages where have a "direct" dependency on the given package.
- Can be repeated.
--include-dev-dependency:- Includes only packages where have a "dev" dependency on the given package.
- Can be repeated.
- Prioritize
--exclude-dev-dependencyoption.
--exclude-dev-dependency:- Excludes packages where have a "dev" dependency on the given package.
- Can be repeated.
d provides some pre-defined environment variables. These environment variables
can be used in any command.
$WORKSPACE_PATH: The absolute path of the directory whered.yamlfile is located.$PACKAGE_PATH: The absolute path of the package root where a command is running on at the moment.$PACKAGE_NAME: The name of the package where a command is running on at the moment.