prepare static method

ProjectFilePreparer prepare(
  1. Directory projectDirectory, {
  2. required TenantProjectPubspec tenantProjectPubspec,
  3. required SupportedDartSdkPolicy? supportedSdkPolicy,
  4. String? scloudDirPath,
})

Analyzes the tenant project structure, creates bespoke deployment files, and compiles the list of paths whose contents are to be included.

supportedSdkPolicy is the Dart SDK version policy of Serverpod Cloud, fetched from the server, or null if it could not be fetched. See TenantProjectPubspec.projectDependencyIssues.

Specify scloudDirPath to override the default scloud directory path.

Returns a ProjectFilePreparer object to be used to filter project files.

If no workspace root is found, or the preparation fails, error messages will be logged and WorkspaceException is thrown.

Implementation

static ProjectFilePreparer prepare(
  final Directory projectDirectory, {
  required final TenantProjectPubspec tenantProjectPubspec,
  required final SupportedDartSdkPolicy? supportedSdkPolicy,
  final String? scloudDirPath,
}) {
  final String projectPackageName = _getPackageName(projectDirectory);

  if (!tenantProjectPubspec.isWorkspaceResolved()) {
    return ProjectFilePreparer(
      isWorkspace: false,
      rootDirectory: projectDirectory,
      scloudDir: Directory(scloudDirPath ?? ScloudIgnore.scloudDirName),
      includedSubPaths: const ['.'],
      includedPackagePaths: [],
      projectPackageName: projectPackageName,
    );
  }

  // Find workspace root directory by traversing up until we find a pubspec.yaml with workspace field
  final (workspaceRootDir, workspacePubspec) = findWorkspaceRoot(
    projectDirectory,
  );

  // create map with all workspace packages, map from package name to [WorkspacePackage]
  final allWorkspacePackages = <String, WorkspacePackage>{};
  for (final packagePath in workspacePubspec.workspace ?? []) {
    final pubspec = Pubspec.parse(
      File(
        p.join(workspaceRootDir.path, packagePath, 'pubspec.yaml'),
      ).readAsStringSync(),
    );
    allWorkspacePackages[pubspec.name] = WorkspacePackage(
      Directory(packagePath),
      pubspec,
    );
  }

  final projectPackage = allWorkspacePackages[projectPackageName];
  if (projectPackage == null) {
    _throwWorkspaceException(
      message:
          "The project's package wasn't found among the workspace's packages.",
    );
  }

  final includedPackages = WorkspaceProjectLogic.getWorkspaceDependencies(
    allWorkspacePackages: allWorkspacePackages,
    package: projectPackage,
    included: <String, WorkspacePackage>{projectPackageName: projectPackage},
  );

  WorkspaceProjectLogic.validateIncludedPackages(
    includedPackages.values.map((final package) => package.pubspec),
    supportedSdkPolicy: supportedSdkPolicy,
  );

  final includedPackagePaths = includedPackages.values
      .map((final package) => package.dir.path)
      .toList();

  final scloudDir = Directory(
    scloudDirPath ??
        p.join(workspaceRootDir.path, ScloudIgnore.scloudDirName),
  );
  scloudDir.createSync(recursive: true);

  try {
    _writeSCloudFiles(workspaceRootDir, scloudDir, projectPackage);

    final includedPaths = [
      ...includedPackagePaths,
      'pubspec.yaml',
      'pubspec.lock',
      ScloudIgnore.scloudDirName,
    ];

    final packageGraph = PackageGraphParser.fromProjectDirectory(
      workspaceRootDir,
    );

    return ProjectFilePreparer(
      isWorkspace: true,
      rootDirectory: workspaceRootDir,
      scloudDir: scloudDir,
      includedSubPaths: includedPaths,
      includedPackagePaths: includedPackagePaths,
      projectPackageName: projectPackageName,
      packageGraph: packageGraph,
    );
  } on PackageGraphFileNotFoundException catch (e) {
    final tailPath = p.relative(e.projectPath, from: workspaceRootDir.path);
    _throwWorkspaceException(
      message: '$tailPath not found.',
      nestedException: null,
      nestedStackTrace: null,
      hint: 'Run "dart pub get"',
    );
  }
}