search ESC

Searching…

No results for "".

Type at least 2 characters to search.

Docs
You are viewing an older version (0.0.1). Go to the latest.

install.yaml Schema Reference

Canonical schema for the declarative install.yaml manifest consumed by plugin:install's manifest flow.

Overview

install.yaml is the declarative manifest that drives plugin:install's manifest flow. The file is parsed by ManifestParser (lib/src/installer/manifest_parser.dart) into a typed InstallManifest (lib/src/installer/install_manifest.dart) and consumed by ManifestInstaller, which translates each section into deferred InstallOperations on the PluginInstaller transaction. Nothing writes to disk until commit(dryRun:, force:) fires.

The schema is intentionally tolerant: every section except plugin_name is optional, every section factory returns a sensible empty default when absent, and partial manifests parse cleanly. Schema violations raise ManifestValidationException; raw YAML syntax errors raise FormatException.

Top-Level Fields

Field Type Required Default Source
plugin_name string yes (none) manifest_parser.dart:112
dependencies map no empty manifest_parser.dart:124
publish map no empty manifest_parser.dart:127
json_merge map no empty manifest_parser.dart:128
magic map no empty manifest_parser.dart:129
native map no empty manifest_parser.dart:132
env map no empty manifest_parser.dart:135
prompts list no empty manifest_parser.dart:136
placeholders map no empty manifest_parser.dart:137
post_install map no empty manifest_parser.dart:138
bootstrap_command string no null manifest_parser.dart:141

plugin_name

The plugin's pubspec package name. Used to scope .artisan/installed/.json reversibility records, the plugins.json registry entry, and the generated lib/app/_plugins.g.dart import line.

Validation regex (manifest_parser.dart:31):

^[a-z_][a-z0-9_]*$

The value must start with a lowercase letter or underscore, followed by any number of lowercase letters, digits, or underscores. An empty string raises ManifestValidationException('plugin_name must not be empty.').

plugin_name: example_plugin

dependencies

Pubspec mutations. The dependencies: map (note the YAML key is plural, but the typed model is PubspecDeps) carries three sub-keys, all optional.

Sub-key Type Translates to
pubspec Map dependencies: entries in the consumer's pubspec.yaml
dev_pubspec Map dev_dependencies: entries
pubspec_assets List Paths appended under flutter.assets:

Empty maps and missing keys are interchangeable; both produce an empty PubspecDeps.

dependencies:
  pubspec:
    intl: ^0.20.0
  dev_pubspec:
    mocktail: ^1.0.0
  pubspec_assets:
    - assets/example/

publish

Stub-name to target-path mapping. Each entry becomes a publishConfig operation: the named stub is read from the plugin's install/ directory, placeholder-substituted, and written to the target path inside the consumer project.

Key shape Value shape
Stub name (string) Target path (string)

Non-string values raise FormatException('publish entry "" must map to a String target path; got .').

publish:
  install/example_config.dart.stub: lib/config/example.dart

json_merge

Map of target JSON file path to merge spec. Each entry triggers a mergeJson operation: the source stub is parsed as JSON, then merged into the target file according to additive.

Field Type Required Default Notes
source string yes (none) Stub key whose content is parsed as JSON. Missing or non-string raises FormatException('json_merge entry missing required "source" string.').
additive bool no true When true, existing keys in the target file survive a collision. When false, source keys overwrite target keys.
json_merge:
  assets/lang/en.json:
    source: install/lang/en.json
    additive: true

magic

Magic-framework integration block. Every slot is optional; the section defaults to an empty integration when absent.

Field Type Translates to
provider string (PascalCase) injectProvider(provider)
config_factory string injectConfigFactory(name)
routes string injectRoute(name)

Validation regex for provider (manifest_parser.dart:34):

^[A-Z][A-Za-z0-9]*$

The value, when present, must be a PascalCase identifier (uppercase first letter, alphanumerics afterwards). A non-matching value raises ManifestValidationException('magic.provider "" does not match PascalCase regex ^[A-Z][A-Za-z0-9]*$.').

magic:
  provider: ExampleServiceProvider
  config_factory: exampleConfig
  routes: registerExampleRoutes

native

Per-platform native configuration. Each platform sub-section is independently optional.

native.android

Field Type Translates to
permissions List entries in AndroidManifest.xml
meta_data Map entries in AndroidManifest.xml
gradle.plugins List<{id, version?}> Gradle plugin block entries
gradle.dependencies List<{scope, notation}> Gradle dependency block entries

Gradle plugin entries without id raise FormatException('Gradle plugin missing required "id".'). Gradle dependency entries without both scope and notation raise FormatException('Gradle dependency entry requires both "scope" and "notation".').

native:
  android:
    permissions:
      - android.permission.INTERNET
    meta_data:
      io.flutter.embedded_views_preview: "true"
    gradle:
      plugins:
        - id: com.example.gradle.plugin
          version: "1.0.0"
      dependencies:
        - scope: implementation
          notation: "com.example:lib:1.0.0"

native.ios

Field Type Notes
info_plist Map Values may be String, bool, num, or List. Runtime-type branching happens in the dispatcher.
entitlements Map Same shape as info_plist.
podfile.platform_version string (optional) Informational in v1: no chain method consumes it yet.
podfile.pods List Pod declarations appended to target 'Runner'.
native:
  ios:
    info_plist:
      NSExampleUsageDescription: "Reason shown in iOS permission dialog"
      UIBackgroundModes: ["fetch"]
    entitlements:
      com.apple.security.keychain: true
    podfile:
      platform_version: "13.0"
      pods:
        - "ExamplePod"

native.macos

Shape mirrors native.ios exactly. Same field set (info_plist, entitlements, podfile.platform_version, podfile.pods), same dispatcher rules. See the Complete Example for a macOS block in context.

native.web

Field Type Translates to
head_scripts List HTML snippets injected before in web/index.html
meta_tags List> attribute maps appended to web/index.html
native:
  web:
    head_scripts:
      - ''
    meta_tags:
      - {name: "description", content: "Example plugin metadata"}

env

Environment variables to inject into the consumer's .env. Map of var name to spec.

Field Type Required Notes
default scalar yes Default value written into .env. Coerced via toString(). Missing raises FormatException('env entry missing required "default".').
comment string no Advisory documentation. The v1 dispatcher does NOT emit the comment into the .env file.

Non-map entries raise FormatException('env entry "" must be a map with "default" + optional "comment"; got .').

env:
  EXAMPLE_KEY:
    default: example_value
    comment: "Example plugin runtime config"

prompts

Ordered list of prompts driven immediately at the start of install (before any deferred operation runs). Prompt answers populate the prompt-result map that placeholders interpolates.

Field Type Required Notes
key string yes Unique within the prompts list. Duplicates raise ManifestValidationException('Duplicate prompt key "" in prompts list.').
type string yes One of string, bool, choice.
question string yes Human-readable question text.
default scalar no Stored as a String regardless of type for uniform placeholder substitution.
options List no For choice prompts: the valid option set. Empty for non-choice types.

Missing key, type, or question raises FormatException('Prompt entry requires "key", "type", and "question" strings.').

prompts:
  - {key: configPath, type: string, default: "~/.example.conf", question: "Config file path?"}
  - {key: mode, type: choice, options: [dev, staging, prod], default: dev, question: "Deployment mode?"}
  - {key: enableFeature, type: bool, default: false, question: "Enable optional feature?"}

placeholders

Map of placeholder key to value template. Values may reference prompt answers via {{ prompts.KEY }}. Whitespace around the dotted reference is optional, so {{prompts.x}} and {{ prompts.x }} are both accepted.

Reference regex (manifest_parser.dart:39):

\{\{\s*prompts\.([A-Za-z_][A-Za-z0-9_]*)\s*\}\}

Every {{ prompts.X }} reference must resolve to a declared prompt key. Unknown references raise ManifestValidationException('Placeholder "" references unknown prompt key "".').

placeholders:
  configFilePath: "{{ prompts.configPath }}"
  runtimeMode: "{{ prompts.mode }}"

post_install

Post-install shell operations plus a final info message. Every sub-field is optional.

Field Type Notes
run List<{cmd, args?}> Shell commands run unconditionally at commit phase. cmd is required; missing raises FormatException('Shell spec missing required "cmd".').
ask_to_run List<{prompt, cmd, args?}> Shell commands run only after user confirmation. The prompt fires immediately at install time; on yes the shell call is deferred. Missing prompt or cmd raises FormatException('ask_to_run entry requires "prompt" and "cmd" strings.').
message string Optional info message emitted after a Success result.
post_install:
  run:
    - cmd: dart
      args: [format, lib/config/example.dart]
  ask_to_run:
    - prompt: "Run pub get now?"
      cmd: flutter
      args: [pub, get]
  message: |
    example_plugin installed.

bootstrap_command

Optional plugin-specific bootstrap command name run after a Success result. Translates to a single dart run :artisan invocation deferred to the very end of the manifest flow.

bootstrap_command: example:install

Complete Example

The example below is the canonical _fullYaml test fixture from test/installer/manifest_parser_test.dart. Every section above appears here in context.

plugin_name: example_plugin

dependencies:
  pubspec:
    intl: ^0.20.0
    crypto: ^3.0.0
  dev_pubspec:
    mocktail: ^1.0.0
  pubspec_assets:
    - assets/example/
    - assets/lang/en.json

publish:
  install/example_config.dart.stub: lib/config/example.dart
  install/example_routes.dart.stub: lib/routes/example.dart

json_merge:
  assets/lang/en.json:
    source: install/lang/en.json
    additive: true

magic:
  provider: ExampleServiceProvider
  config_factory: exampleConfig
  routes: registerExampleRoutes

native:
  android:
    permissions:
      - android.permission.INTERNET
    meta_data:
      io.flutter.embedded_views_preview: "true"
    gradle:
      plugins:
        - id: com.example.gradle.plugin
          version: "1.0.0"
      dependencies:
        - scope: implementation
          notation: "com.example:lib:1.0.0"
  ios:
    info_plist:
      NSExampleUsageDescription: "Reason shown in iOS permission dialog"
      UIBackgroundModes: ["fetch"]
    entitlements:
      com.apple.security.keychain: true
    podfile:
      platform_version: "13.0"
      pods:
        - "ExamplePod"
  macos:
    info_plist:
      NSExampleUsageDescription: "Reason shown in macOS permission dialog"
    entitlements:
      com.apple.security.network.client: true
    podfile:
      platform_version: "11.0"
      pods:
        - "ExamplePod"
  web:
    head_scripts:
      - ''
    meta_tags:
      - {name: "description", content: "Example plugin metadata"}

env:
  EXAMPLE_KEY:
    default: example_value
    comment: "Example plugin runtime config"

prompts:
  - {key: configPath, type: string, default: "~/.example.conf", question: "Config file path?"}
  - {key: mode, type: choice, options: [dev, staging, prod], default: dev, question: "Deployment mode?"}
  - {key: enableFeature, type: bool, default: false, question: "Enable optional feature?"}

placeholders:
  configFilePath: "{{ prompts.configPath }}"
  runtimeMode: "{{ prompts.mode }}"

post_install:
  run:
    - cmd: dart
      args: [format, lib/config/example.dart]
  ask_to_run:
    - prompt: "Run pub get now?"
      cmd: flutter
      args: [pub, get]
  message: |
    example_plugin installed.

bootstrap_command: example:install