blob: 01619cb80a097157d0ad4bd2aa30c0c3b6087259 [file] [edit]
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
import 'package:args/command_runner.dart';
import 'package:file/file.dart' as f;
import 'package:http/http.dart' as http;
import 'package:pub/pub.dart';
import '../resource_provider/resource_provider_file.dart';
import '../resource_provider/resource_provider_wrap_cwd.dart';
import '../shared.dart';
import '../util/stdout_recorder.dart';
const supportedPubCommands = [
'get',
'add',
'downgrade',
'outdated',
'upgrade',
'remove',
'unpack',
];
Future<({String log})> pub({
required ResourceProvider resourceProvider,
required String currentWorkingDirectory,
required String command,
required List<String> args,
required DartPadConfig config,
}) async {
if (!supportedPubCommands.contains(command)) {
throw ArgumentError.value(
command,
'command',
'must be one of $supportedPubCommands',
);
}
final stdout = StdoutRecorder();
final exitCode = await Runner(
fileSystem: resourceProviderAsFileFileSystem(
resourceProviderWithCurrentWorkingDirectory(
resourceProvider,
currentWorkingDirectory,
),
),
stdout: stdout.sink,
stderr: stdout.sink,
stdin: const Stream.empty(),
platformVersion: '3.12.0',
environment: {
'PUB_CACHE': '/pub-cache',
'DART_ROOT': config.dartSdkPath,
'FLUTTER_ROOT': ?config.flutterSdkPath,
if (config.pubHostedUrl?.isNotEmpty == true)
'PUB_HOSTED_URL': ?config.pubHostedUrl,
},
httpClient: http.Client(),
).run(['pub', command, ...args]);
if (exitCode != 0) {
final makeException =
_pubExceptionMap[exitCode] ?? PubCommandFailedException.new;
throw makeException(stdout.log, data: {'exitCode': exitCode});
}
return (log: stdout.log);
}
typedef _MakeException = Exception Function(String message, {Object? data});
/// Pub uses exit codes from http://www.freebsd.org/cgi/man.cgi?query=sysexits
///
/// See: sdk/third_party/pkg/pub/lib/src/exit_codes.dart
final _pubExceptionMap = <int, _MakeException>{
64: PubUsageException.new,
65: PubDataException.new,
66: PubNoInputException.new,
67: PubNoUserException.new,
68: PubNoHostException.new,
69: PubUnavailableException.new,
70: PubSoftwareException.new,
71: PubOsException.new,
72: PubOsFileException.new,
73: PubCantCreateException.new,
74: PubIoException.new,
75: PubTempFailException.new,
76: PubProtocolException.new,
77: PubNoPermException.new,
78: PubConfigException.new,
};
class Runner extends CommandRunner<int> {
final f.FileSystem fileSystem;
final Map<String, String> environment;
final String platformVersion;
final Stream<List<int>> stdin;
final StreamSink<List<int>> stdout;
final StreamSink<List<int>> stderr;
final http.Client httpClient;
Runner({
required this.fileSystem,
required this.environment,
required this.platformVersion,
required this.stdin,
required this.stdout,
required this.stderr,
required this.httpClient,
}) : super('dart', 'dart pub emulator') {
addCommand(
pubCommand(
isVerbose: () => false,
fileSystem: fileSystem,
environment: environment,
platformVersion: platformVersion,
stdin: stdin,
stdout: stdout,
stderr: stderr,
httpClient: httpClient,
),
);
}
}