readPubspec static method

Future<(BPConfig?, List<BPConfigValidationError>)> readPubspec(
  1. List<String> args, [
  2. String? pubspecPath
])

Reads the pubspec.yaml file, parses, validates, and returns the config object. No exceptions are thrown from this functions, instead, a list of user-facing errors will be returned as the second object of the record

Implementation

static Future<(BPConfig?, List<BPConfigValidationError>)> readPubspec(List<String> args, [String? pubspecPath]) async {
  final rawPubspecFile = File(pubspecPath ?? 'pubspec.yaml');
  if (!(await rawPubspecFile.exists())) {
    return (
      null,
      [
        BPConfigValidationError(
          errorCase: BPConfigValidationErrorCase.pubspecNotFound,
          message: "pubspec.yaml file could not be found!",
        ),
      ],
    );
  }

  final pubspec = yaml.loadYaml(await rawPubspecFile.readAsString());
  if (!(pubspec as yaml.YamlMap).containsKey("build_pipe")) {
    return (
      null,
      [
        BPConfigValidationError(
          errorCase: BPConfigValidationErrorCase.buildPipeConfigMissing,
          message: "please add the build_pipe configuration to your pubspec file!",
        ),
      ],
    );
  }

  var buildPipeConfig = pubspec["build_pipe"];

  if (!buildPipeConfig.containsKey("workflows")) {
    List<String> messages = [
      "No 'workflows' found in build_pipe config.",
    ];
    // In 0.3.0, the named workflows were introduced which is a breaking change to the config structure.
    // Prior to 0.3.0, the `build_pipe` object contains the config directly, practically for
    // a single workflow. If the `workflows` key is missing and the `platforms` is present, it is an
    // indication that the user is using an older version of the package.
    if (buildPipeConfig.containsKey("platforms")) {
      messages.add("It seems that you have updated the flutter_build_pipe package to version 0.3.0 or higher. This version contains breaking changes in the configuration.");
      messages.add("You need to make some changes to your pubspec.yaml file, which should take less than a minute.");
      messages.add("Please read the migration guide here: https://github.com/vieolo/flutter_build_pipe/blob/master/doc/migration/0_3_0.md");
    }

    return (
      null,
      [
        BPConfigValidationError(
          errorCase: BPConfigValidationErrorCase.noWorkflowInConfig,
          message: messages.join("\n"),
        ),
      ],
    );
  }

  String workflowName = "default";
  List<String> overriddenTargetPlatforms = [];
  List<String> downstreamargs = [];
  for (var arg in args) {
    if (arg.startsWith("--workflow=")) {
      workflowName = arg.split("=")[1];
      continue;
    }
    if (arg.startsWith("--override-target-platforms=")) {
      overriddenTargetPlatforms = arg.split("=")[1].split(",");
      continue;
    }
    downstreamargs.add(arg);
  }

  var workflows = buildPipeConfig["workflows"];
  if (!workflows.containsKey(workflowName)) {
    return (
      null,
      [
        BPConfigValidationError(
          errorCase: BPConfigValidationErrorCase.workflowNotFound,
          message: "Workflow '$workflowName' not found.",
        ),
      ],
    );
  }

  final (BPConfig?, List<BPConfigValidationError>) config = BPConfig.fromMap(
    workflows[workflowName],
    downstreamargs,
    pubspec["version"].split("+")[0],
    // just in case the + doesnt exist
    pubspec["version"].split("+").length > 1 ? pubspec["version"].split("+")[1] : "0",
  );

  if (config.$1 != null && overriddenTargetPlatforms.isNotEmpty) {
    config.$1?._applyTargetPlatformFilter(overriddenTargetPlatforms);
  }

  if (config.$1 != null && config.$1!.publishPlatforms.isEmpty && config.$1!.buildPlatforms.isEmpty) {
    return (
      null,
      [
        BPConfigValidationError(
          errorCase: BPConfigValidationErrorCase.noTargetPlatform,
          message: "No target platforms were detected. Please add your target platforms to pubspec",
        ),
      ],
    );
  }

  return config;
}