uploadPackage method
Future<Response>
uploadPackage(
- Request req
)
Implementation
Future<shelf.Response> uploadPackage(shelf.Request req) async {
try {
var token = await _getBearToken(req);
var contentType = req.headers[HttpHeaders.contentTypeHeader];
if (contentType == null) throw 'invalid content type';
var mediaType = MediaType.parse(contentType);
var boundary = mediaType.parameters['boundary'];
if (boundary == null) throw 'invalid boundary';
var transformer = MimeMultipartTransformer(boundary);
MimeMultipart? fileData;
// The map below makes the runtime type checker happy.
// https://github.com/dart-lang/pub-dev/blob/19033f8154ca1f597ef5495acbc84a2bb368f16d/app/lib/fake/server/fake_storage_server.dart#L74
final stream = req.read().map((a) => a).transform(transformer);
await for (var part in stream) {
if (fileData != null) continue;
fileData = part;
}
logger!.info('[uploadPackage] fileData: ${fileData?.headers}');
var bb = await fileData!
.fold(BytesBuilder(), (BytesBuilder bbuf, d) => bbuf..add(d));
var tarbarBytes = bb.takeBytes();
var tarBytes = GZipDecoder().decodeBytes(tarbarBytes);
var archive = TarDecoder().decodeBytes(tarBytes);
ArchiveFile? pubspecArchiveFile;
ArchiveFile? readmeFile;
ArchiveFile? changelogFile;
bool hasLib = false,
hasAndroid = false,
hasIOS = false,
hasLinux = false,
hasMacOS = false,
hasWindows = false,
hasWeb = false;
for (var file in archive.files) {
if (file.name == 'pubspec.yaml') {
pubspecArchiveFile = file;
continue;
}
if (file.name.toLowerCase() == 'readme.md') {
readmeFile = file;
continue;
}
if (file.name.toLowerCase() == 'changelog.md') {
changelogFile = file;
continue;
}
if (file.name.toLowerCase() == 'lib' && file.isDirectory) {
hasLib = true;
}
if (file.name.toLowerCase() == 'android' && file.isDirectory) {
hasAndroid = true;
}
if (file.name.toLowerCase() == 'ios' && file.isDirectory) {
hasIOS = true;
}
if (file.name.toLowerCase() == 'linux' && file.isDirectory) {
hasLinux = true;
}
if (file.name.toLowerCase() == 'macos' && file.isDirectory) {
hasMacOS = true;
}
if (file.name.toLowerCase() == 'windows' && file.isDirectory) {
hasWindows = true;
}
if (file.name.toLowerCase() == 'web' && file.isDirectory) {
hasWeb = true;
}
}
if (pubspecArchiveFile == null) {
throw 'Did not found any pubspec.yaml file in upload. Aborting...';
}
var pubspecYaml =
utf8.decode(pubspecArchiveFile.content, allowMalformed: true);
var pubspec = loadYaml(pubspecYaml, recover: true);
await uploadValidator?.call(pubspec, token);
_pubspecItemCheck(pubspec, 'name');
_pubspecItemCheck(pubspec, 'version');
_pubspecItemCheck(pubspec, 'environment');
var isDart3Compatible = false;
if (pubspec['environment'] is YamlMap &&
(pubspec['environment'] as YamlMap).containsKey('sdk')) {
var sdk = (pubspec['environment'] as YamlMap)['sdk'].toString();
final constraint = semver.VersionConstraint.parse(sdk);
isDart3Compatible = constraint.allows(semver.Version(3, 0, 0)) ||
constraint.allows(semver.Version(3, 5, 0));
}
var name = pubspec['name'] as String;
var version = pubspec['version'] as String;
var package = await metaRepo.query(name);
if (package != null) {
if (!package.private) {
throw '$name is not a private package, please upload it to https://pub.dev';
}
if (package.uploaders?.contains(token) == false) {
throw '$token is not an uploader of $name';
}
var duplicated =
package.versions.firstWhereOrNull((it) => version == it.version);
if (duplicated != null) {
throw 'version $name@$version already exists';
}
}
final sha256 = await packageStorage.upload(name, version, tarbarBytes);
String? readme, changelog;
if (readmeFile != null) {
readme = utf8.decode(readmeFile.content);
}
if (changelogFile != null) {
changelog = utf8.decode(changelogFile.content);
}
var unpuberVersion = PackageVersion(
archiveUrl: '/packages/$name/versions/$version.tar.gz',
archiveSha256: sha256,
version: version,
pubspec: (pubspec as YamlMap).toMap(),
pubspecYaml: pubspecYaml,
uploader: auth,
readme: readme,
changelog: changelog,
isDart3Compatible: isDart3Compatible,
plats: _getPkgPlats(
hasLib, hasAndroid, hasIOS, hasLinux, hasMacOS, hasWindows, hasWeb),
published: DateTime.now(),
);
await metaRepo.addRecord(name, unpuberVersion);
return shelf.Response.found(
_resolveUri(req, '/api/packages/versions/newUploadFinish'));
} on Exception catch (e) {
return shelf.Response.found(_resolveUri(
req, '/api/packages/versions/newUploadFinish?error=${e.toString()}'));
} catch (e, st) {
logger!.severe('[uploadPackage] failed: ', e, st);
return _bad('internal server error: ${e.toString()}');
}
}