resolveRemoteIdeRoot function

String? resolveRemoteIdeRoot(
  1. String? arg,
  2. String? remoteCwd
)

Helpers shared by the native :ide command and a web client's :ide, kept dart:io-free so both (CLI and browser) resolve the IDE root and pick the agent's command syntax identically. Resolves the remote IDE root from an optional arg and the current remote working directory remoteCwd:

  • an absolute remote path — POSIX (/srv/app) or Windows (C:\proj, \\server\share) — is normalized and used as-is;
  • a relative path is joined onto remoteCwd;
  • no argument (or .) uses remoteCwd itself.

Whether the node's paths follow Windows rules comes from remoteCwd's form when known (C:\… vs /…, so Git Bash on Windows stays POSIX), else from arg's (the shell family cannot say: PowerShell runs on Linux and macOS too). Windows paths come back in their native form (normalizeRemotePath); on Git Bash, whose cwd is /c/…, a Windows path argument (C:\proj) is taken in its /c/proj form (msysPath). Returns null when the cwd is needed (a relative, drive-relative or omitted path) but not yet known — the caller should ask the user to run a command first or pass an absolute path.

Implementation

/// Resolves the remote IDE root from an optional [arg] and the current remote
/// working directory [remoteCwd]:
///
/// * an absolute remote path — POSIX (`/srv/app`) or Windows (`C:\proj`,
///   `\\server\share`) — is normalized and used as-is;
/// * a relative path is joined onto [remoteCwd];
/// * no argument (or `.`) uses [remoteCwd] itself.
///
/// Whether the node's paths follow Windows rules comes from [remoteCwd]'s
/// form when known (`C:\…` vs `/…`, so Git Bash on Windows stays POSIX), else
/// from [arg]'s (the shell family cannot say: PowerShell runs on Linux and
/// macOS too). Windows paths come back in their native form
/// ([normalizeRemotePath]); on Git Bash, whose cwd is `/c/…`, a Windows path
/// argument (`C:\proj`) is taken in its `/c/proj` form ([msysPath]).
/// Returns `null` when the cwd is needed (a relative, drive-relative or
/// omitted path) but not yet known — the caller should ask the user to run a
/// command first or pass an absolute path.
String? resolveRemoteIdeRoot(String? arg, String? remoteCwd) {
  final windows = isWindowsRemotePath(remoteCwd ?? arg ?? '');
  final ctx = windows ? p.windows : p.posix;
  final cwd = remoteCwd == null
      ? null
      : normalizeRemotePath(remoteCwd, windows: windows);
  if (arg == null || arg.isEmpty || arg == '.') return cwd;
  if (!windows) {
    final msys = cwd != null && _msysRoot.hasMatch(cwd) ? msysPath(arg) : null;
    final path = msys ?? arg;
    if (ctx.isAbsolute(path)) return p.posix.normalize(path);
    if (cwd == null) return null;
    return p.posix.normalize(ctx.join(cwd, path));
  }
  // A bare drive (`C:`) means its root here, not that drive's current directory.
  final path = RegExp(r'^[A-Za-z]:$').hasMatch(arg) ? '$arg\\' : arg;
  if (RegExp(r'^[\\/](?![\\/])').hasMatch(path)) {
    // Rooted on the current drive (`\proj`): that is the cwd's drive.
    if (cwd == null) return null;
    return normalizeRemotePath(
      ctx.join(ctx.rootPrefix(cwd), path.substring(1)),
      windows: true,
    );
  }
  final driveRelative = _driveRelative.firstMatch(path);
  if (driveRelative != null) {
    // `D:x` is relative to drive D's own current directory: known only when
    // that is the cwd's drive.
    if (cwd == null ||
        cwd[0].toLowerCase() != driveRelative.group(1)!.toLowerCase()) {
      return null;
    }
    return normalizeRemotePath(
      ctx.join(cwd, driveRelative.group(2)!),
      windows: true,
    );
  }
  if (ctx.isAbsolute(path)) return normalizeRemotePath(path, windows: true);
  if (cwd == null) return null;
  return normalizeRemotePath(ctx.join(cwd, path), windows: true);
}