createForIssue method

Future<Workspace> createForIssue(
  1. String issueIdentifier
)

Creates or reuses the workspace for issueIdentifier.

Implementation

Future<Workspace> createForIssue(String issueIdentifier) async {
  final key = sanitizeKey(issueIdentifier);
  if (key.isEmpty) {
    throw const WorkspaceException(
      WorkspaceFailureCode.emptyKey,
      'Workspace key resolved to an empty string after sanitization.',
    );
  }

  final root = p.normalize(workspaceConfig.root);
  final path = resolvePath(issueIdentifier);
  final branchName = 'spectra/$key';

  Directory(root).createSync(recursive: true);

  final dir = Directory(path);
  final existedBefore = dir.existsSync();
  var createdNow = false;

  if (!existedBefore) {
    if (useGitWorktrees) {
      final result = await _git(<String>[
        'worktree',
        'add',
        '-B',
        branchName,
        path,
        baseRef,
      ], workingDirectory: repositoryRoot);
      if (result.exitCode != 0) {
        throw WorkspaceException(
          WorkspaceFailureCode.worktreeAddFailed,
          'git worktree add failed (exit ${result.exitCode}): ${result.stderr}',
        );
      }
    } else {
      try {
        dir.createSync(recursive: true);
      } catch (e) {
        throw WorkspaceException(
          WorkspaceFailureCode.createFailed,
          'Failed to create workspace directory $path: $e',
          cause: e,
        );
      }
    }
    createdNow = true;
  }

  final workspace = Workspace(
    workspaceKey: key,
    path: path,
    branchName: branchName,
    createdNow: createdNow,
  );

  if (createdNow) {
    final outcome = await hookRunner.run(
      kind: WorkspaceHookKind.afterCreate,
      workspacePath: path,
      hooks: hooksConfig,
    );
    if (outcome.isFatal) {
      await _bestEffortRemoveWorktree(path);
      throw WorkspaceException(
        outcome.timedOut
            ? WorkspaceFailureCode.hookTimedOut
            : WorkspaceFailureCode.hookFailed,
        'after_create hook failed: ${outcome.output}',
      );
    }
  }

  return workspace;
}