Skip to content

Commit

Permalink
Don't impose a strict size limit to uploads
Browse files Browse the repository at this point in the history
  • Loading branch information
sigurdm committed Sep 13, 2023
1 parent cb0d6f9 commit 4ace350
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 27 deletions.
25 changes: 20 additions & 5 deletions lib/src/command/lish.dart
Original file line number Diff line number Diff line change
Expand Up @@ -277,14 +277,17 @@ the \$PUB_HOSTED_URL environment variable.''',
'${tree.fromFiles(files, baseDir: entrypoint.rootDir, showFileSizes: true)}',
);

var packageBytesFuture =
createTarGz(files, baseDir: entrypoint.rootDir).toBytes();
var packageBytes =
await createTarGz(files, baseDir: entrypoint.rootDir).toBytes();
log.message(
'\nTotal compressed archive size: ${_readableFileSize(packageBytes.length)}.\n',
);

// Validate the package.
var isValid = skipValidation
? true
: await _validate(
packageBytesFuture.then((bytes) => bytes.length),
packageBytes.length,
files,
);
if (!isValid) {
Expand All @@ -294,7 +297,7 @@ the \$PUB_HOSTED_URL environment variable.''',
log.message('The server may enforce additional checks.');
return;
} else {
await _publish(await packageBytesFuture);
await _publish(packageBytes);
}
}

Expand All @@ -307,7 +310,7 @@ the \$PUB_HOSTED_URL environment variable.''',

/// Validates the package. Completes to false if the upload should not
/// proceed.
Future<bool> _validate(Future<int> packageSize, List<String> files) async {
Future<bool> _validate(int packageSize, List<String> files) async {
final hints = <String>[];
final warnings = <String>[];
final errors = <String>[];
Expand Down Expand Up @@ -368,3 +371,15 @@ the \$PUB_HOSTED_URL environment variable.''',
return true;
}
}

String _readableFileSize(int size) {
if (size >= 1 << 30) {
return '${size ~/ (1 << 30)} GB';
} else if (size >= 1 << 20) {
return '${size ~/ (1 << 20)} MB';
} else if (size >= 1 << 10) {
return '${size ~/ (1 << 10)} KB';
} else {
return '<1 KB';
}
}
4 changes: 2 additions & 2 deletions lib/src/validator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ abstract class Validator {
/// upload to the server.
static Future<void> runAll(
Entrypoint entrypoint,
Future<int> packageSize,
int packageSize,
Uri serverUrl,
List<String> files, {
required List<String> hints,
Expand Down Expand Up @@ -163,7 +163,7 @@ abstract class Validator {

final context = ValidationContext(
entrypoint,
await packageSize,
packageSize,
serverUrl,
files,
);
Expand Down
14 changes: 8 additions & 6 deletions lib/src/validator/size.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'dart:async';
import '../io.dart';
import '../validator.dart';

/// The maximum size of the package to upload (100 MB).
/// The preferred maximum size of the package to upload (100 MB).
const _maxSize = 100 * 1024 * 1024;

/// A validator that validates that a package isn't too big.
Expand All @@ -19,17 +19,19 @@ class SizeValidator extends Validator {
// Current implementation of Package.listFiles skips hidden files
var ignoreExists = fileExists(entrypoint.root.path('.gitignore'));

var error = StringBuffer('Your package is $sizeInMb MB. Hosted '
'packages must be smaller than 100 MB.');
var hint = StringBuffer('''
Your package is $sizeInMb MB.
Consider the impact large downloads can have on the package consumer.''');

if (ignoreExists && !entrypoint.root.inGitRepo) {
error.write(' Your .gitignore has no effect since your project '
hint.write('\nYour .gitignore has no effect since your project '
'does not appear to be in version control.');
} else if (!ignoreExists && entrypoint.root.inGitRepo) {
error.write(' Consider adding a .gitignore to avoid including '
hint.write('\nConsider adding a .gitignore to avoid including '
'temporary files.');
}

errors.add(error.toString());
hints.add(hint.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ Publishing test_pkg 1.0.0 to http://localhost:$PORT:
├── lib
│ └── test_pkg.dart (<1 KB)
└── pubspec.yaml (<1 KB)

Total compressed archive size: <1 KB.
Validating package...
The server may enforce additional checks.
[STDERR]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Publishing test_pkg 1.0.0 to http://localhost:$PORT:
│ ├── file_9.dart (<1 KB)
│ └── test_pkg.dart (<1 KB)
└── pubspec.yaml (<1 KB)

Total compressed archive size: <1 KB.
Validating package...

Publishing is forever; packages cannot be unpublished.
Expand Down
26 changes: 12 additions & 14 deletions test/validator/size_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,39 @@ import '../descriptor.dart' as d;
import '../test_pub.dart';
import 'utils.dart';

Future<void> expectSizeValidationError(Matcher matcher) async {
Future<void> expectSizeValidationHint(Matcher matcher) async {
await expectValidationDeprecated(
SizeValidator.new,
size: 100 * (1 << 20) + 1,
errors: contains(matcher),
hints: contains(matcher),
);
}

void main() {
test('considers a package valid if it is <= 100 MB', () async {
test('ho hint if package is <= 100 MB', () async {
await d.validPackage().create();

await expectValidationDeprecated(SizeValidator.new, size: 100);
await expectValidationDeprecated(SizeValidator.new, size: 100 * (1 << 20));
});

group('considers a package invalid if it is more than 100 MB', () {
group('hints if package is more than 100 MB', () {
test('package is not under source control and no .gitignore exists',
() async {
await d.validPackage().create();

await expectSizeValidationError(
equals('Your package is 100.0 MB. Hosted packages must '
'be smaller than 100 MB.'),
await expectSizeValidationHint(
contains('Your package is 100.0 MB.'),
);
});

test('package is not under source control and .gitignore exists', () async {
await d.validPackage().create();
await d.dir(appPath, [d.file('.gitignore', 'ignored')]).create();

await expectSizeValidationError(
await expectSizeValidationHint(
allOf(
contains('Hosted packages must be smaller than 100 MB.'),
contains('Your package is 100.0 MB.'),
contains('Your .gitignore has no effect since your project '
'does not appear to be in version control.'),
),
Expand All @@ -55,9 +54,9 @@ void main() {
await d.validPackage().create();
await d.git(appPath).create();

await expectSizeValidationError(
await expectSizeValidationHint(
allOf(
contains('Hosted packages must be smaller than 100 MB.'),
contains('Your package is 100.0 MB.'),
contains('Consider adding a .gitignore to avoid including '
'temporary files.'),
),
Expand All @@ -68,9 +67,8 @@ void main() {
await d.validPackage().create();
await d.git(appPath, [d.file('.gitignore', 'ignored')]).create();

await expectSizeValidationError(
equals('Your package is 100.0 MB. Hosted packages must '
'be smaller than 100 MB.'),
await expectSizeValidationHint(
contains('Your package is 100.0 MB.'),
);
});
});
Expand Down

0 comments on commit 4ace350

Please sign in to comment.