Skip to content

Commit a4f5789

Browse files
authored
Don't choke when publishing a package with an empty submodule (#1710)
Closes #1679
1 parent 5567505 commit a4f5789

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

lib/src/package.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,12 @@ class Package {
258258
// Git prints files relative to [beneath], but we want them relative to
259259
// the pub's working directory. It also prints forward slashes on Windows
260260
// which we normalize away for easier testing.
261-
files = files.map((file) {
261+
//
262+
// Git lists empty directories as "./", which we skip so we don't keep
263+
// trying to recurse into the same directory. Normally git doesn't allow
264+
// totally empty directories, but a submodule that's not checked out
265+
// behaves like one.
266+
files = files.where((file) => file != './').map((file) {
262267
if (Platform.operatingSystem != 'windows') return "$beneath/$file";
263268
return "$beneath\\${file.replaceAll("/", "\\")}";
264269
}).expand((file) {

test/lish/archives_and_uploads_a_package_test.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
import 'dart:convert';
66

7+
import 'package:path/path.dart' as p;
78
import 'package:shelf/shelf.dart' as shelf;
89
import 'package:shelf_test_handler/shelf_test_handler.dart';
910
import 'package:test/test.dart';
1011

1112
import 'package:pub/src/exit_codes.dart' as exit_codes;
13+
import 'package:pub/src/io.dart';
1214

1315
import '../descriptor.dart' as d;
1416
import '../test_pub.dart';
@@ -37,6 +39,40 @@ main() {
3739
await pub.shouldExit(exit_codes.SUCCESS);
3840
});
3941

42+
// This is a regression test for #1679. We create a submodule that's not
43+
// checked out to ensure that file listing doesn't choke on the empty
44+
// directory.
45+
test('with an empty Git submodule', () async {
46+
await d.git('empty').create();
47+
48+
var repo = d.git(appPath);
49+
await repo.create();
50+
51+
await repo.runGit(['submodule', 'add', '../empty', 'empty']);
52+
await repo.commit();
53+
54+
deleteEntry(p.join(d.sandbox, appPath, 'empty'));
55+
await d.dir(p.join(appPath, 'empty')).create();
56+
57+
var server = await ShelfTestServer.create();
58+
await d.credentialsFile(server, 'access token').create();
59+
var pub = await startPublish(server);
60+
61+
await confirmPublish(pub);
62+
handleUploadForm(server);
63+
handleUpload(server);
64+
65+
server.handler.expect('GET', '/create', (request) {
66+
return new shelf.Response.ok(JSON.encode({
67+
'success': {'message': 'Package test_pkg 1.0.0 uploaded!'}
68+
}));
69+
});
70+
71+
expect(pub.stdout, emits(startsWith('Uploading...')));
72+
expect(pub.stdout, emits('Package test_pkg 1.0.0 uploaded!'));
73+
await pub.shouldExit(exit_codes.SUCCESS);
74+
});
75+
4076
// TODO(nweiz): Once a multipart/form-data parser in Dart exists, we should
4177
// test that "pub lish" chooses the correct files to publish.
4278
}

0 commit comments

Comments
 (0)