Skip to content

Commit 5b7d732

Browse files
[tool] Use new pub cache location for publish (flutter#3962)
As of Dart 3.0 (Flutter 3.10), the location that the tool was using for the pub cache wasn't being read, breaking autopublish in CI. This updates to the new location, and adds tests for it. Should fix the fact that the `release` step hangs on every package change now.
1 parent 12d6717 commit 5b7d732

File tree

2 files changed

+85
-35
lines changed

2 files changed

+85
-35
lines changed

script/tool/lib/src/publish_command.dart

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ class PublishCommand extends PackageLoopingCommand {
9999
// `flutter_plugin_tools-v0.0.24`.
100100
static const String _tagFormat = '%PACKAGE%-v%VERSION%';
101101

102+
/// Returns the correct path where the pub credential is stored.
103+
@visibleForTesting
104+
late final String credentialsPath =
105+
_getCredentialsPath(platform: platform, path: path);
106+
102107
@override
103108
final String name = 'publish';
104109

@@ -397,13 +402,12 @@ Safe to ignore if the package is deleted in this commit.
397402
}
398403

399404
void _ensureValidPubCredential() {
400-
final String credentialsPath = _credentialsPath;
401405
final File credentialFile = packagesDir.fileSystem.file(credentialsPath);
402406
if (credentialFile.existsSync() &&
403407
credentialFile.readAsStringSync().isNotEmpty) {
404408
return;
405409
}
406-
final String? credential = io.Platform.environment[_pubCredentialName];
410+
final String? credential = platform.environment[_pubCredentialName];
407411
if (credential == null) {
408412
printError('''
409413
No pub credential available. Please check if `$credentialsPath` is valid.
@@ -415,42 +419,46 @@ If running this command on CI, you can set the pub credential content in the $_p
415419
..writeStringSync(credential)
416420
..closeSync();
417421
}
418-
419-
/// Returns the correct path where the pub credential is stored.
420-
@visibleForTesting
421-
static String getCredentialPath() {
422-
return _credentialsPath;
423-
}
424422
}
425423

426424
/// The path in which pub expects to find its credentials file.
427-
final String _credentialsPath = () {
428-
// This follows the same logic as pub:
429-
// https://github.com/dart-lang/pub/blob/d99b0d58f4059d7bb4ac4616fd3d54ec00a2b5d4/lib/src/system_cache.dart#L34-L43
430-
String? cacheDir;
431-
final String? pubCache = io.Platform.environment['PUB_CACHE'];
432-
if (pubCache != null) {
433-
cacheDir = pubCache;
434-
} else if (io.Platform.isWindows) {
435-
final String? appData = io.Platform.environment['APPDATA'];
425+
String _getCredentialsPath(
426+
{required Platform platform, required p.Context path}) {
427+
// See https://github.com/dart-lang/pub/blob/master/doc/cache_layout.md#layout
428+
String? configDir;
429+
if (platform.isLinux) {
430+
String? configHome = platform.environment['XDG_CONFIG_HOME'];
431+
if (configHome == null) {
432+
final String? home = platform.environment['HOME'];
433+
if (home == null) {
434+
printError('"HOME" environment variable is not set.');
435+
} else {
436+
configHome = path.join(home, '.config');
437+
}
438+
}
439+
if (configHome != null) {
440+
configDir = path.join(configHome, 'dart');
441+
}
442+
} else if (platform.isWindows) {
443+
final String? appData = platform.environment['APPDATA'];
436444
if (appData == null) {
437445
printError('"APPDATA" environment variable is not set.');
438446
} else {
439-
cacheDir = p.join(appData, 'Pub', 'Cache');
447+
configDir = path.join(appData, 'dart');
440448
}
441-
} else {
442-
final String? home = io.Platform.environment['HOME'];
449+
} else if (platform.isMacOS) {
450+
final String? home = platform.environment['HOME'];
443451
if (home == null) {
444452
printError('"HOME" environment variable is not set.');
445453
} else {
446-
cacheDir = p.join(home, '.pub-cache');
454+
configDir = path.join(home, 'Library', 'Application Support', 'dart');
447455
}
448456
}
449457

450-
if (cacheDir == null) {
451-
printError('Unable to determine pub cache location');
458+
if (configDir == null) {
459+
printError('Unable to determine pub con location');
452460
throw ToolExit(1);
453461
}
454462

455-
return p.join(cacheDir, 'credentials.json');
456-
}();
463+
return path.join(configDir, 'pub-credentials.json');
464+
}

script/tool/test/publish_command_test.dart

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,26 @@ import 'util.dart';
2424
void main() {
2525
final String flutterCommand = getFlutterCommand(const LocalPlatform());
2626

27+
late MockPlatform platform;
2728
late Directory packagesDir;
2829
late MockGitDir gitDir;
2930
late TestProcessRunner processRunner;
31+
late PublishCommand command;
3032
late CommandRunner<void> commandRunner;
3133
late MockStdin mockStdin;
3234
late FileSystem fileSystem;
3335
// Map of package name to mock response.
3436
late Map<String, Map<String, dynamic>> mockHttpResponses;
3537

3638
void createMockCredentialFile() {
37-
final String credentialPath = PublishCommand.getCredentialPath();
38-
fileSystem.file(credentialPath)
39+
fileSystem.file(command.credentialsPath)
3940
..createSync(recursive: true)
4041
..writeAsStringSync('some credential');
4142
}
4243

4344
setUp(() async {
45+
platform = MockPlatform(isLinux: true);
46+
platform.environment['HOME'] = '/home';
4447
fileSystem = MemoryFileSystem();
4548
packagesDir = createPackagesDirectory(fileSystem: fileSystem);
4649
processRunner = TestProcessRunner();
@@ -71,14 +74,15 @@ void main() {
7174
});
7275

7376
mockStdin = MockStdin();
74-
commandRunner = CommandRunner<void>('tester', '')
75-
..addCommand(PublishCommand(
76-
packagesDir,
77-
processRunner: processRunner,
78-
stdinput: mockStdin,
79-
gitDir: gitDir,
80-
httpClient: mockClient,
81-
));
77+
command = PublishCommand(
78+
packagesDir,
79+
platform: platform,
80+
processRunner: processRunner,
81+
stdinput: mockStdin,
82+
gitDir: gitDir,
83+
httpClient: mockClient,
84+
);
85+
commandRunner = CommandRunner<void>('tester', '')..addCommand(command);
8286
});
8387

8488
group('Initial validation', () {
@@ -880,6 +884,44 @@ void main() {
880884
isNot(contains('git-push')));
881885
});
882886
});
887+
888+
group('credential location', () {
889+
test('Linux with XDG', () async {
890+
platform = MockPlatform(isLinux: true);
891+
platform.environment['XDG_CONFIG_HOME'] = '/xdghome/config';
892+
command = PublishCommand(packagesDir, platform: platform);
893+
894+
expect(
895+
command.credentialsPath, '/xdghome/config/dart/pub-credentials.json');
896+
});
897+
898+
test('Linux without XDG', () async {
899+
platform = MockPlatform(isLinux: true);
900+
platform.environment['HOME'] = '/home';
901+
command = PublishCommand(packagesDir, platform: platform);
902+
903+
expect(
904+
command.credentialsPath, '/home/.config/dart/pub-credentials.json');
905+
});
906+
907+
test('macOS', () async {
908+
platform = MockPlatform(isMacOS: true);
909+
platform.environment['HOME'] = '/Users/someuser';
910+
command = PublishCommand(packagesDir, platform: platform);
911+
912+
expect(command.credentialsPath,
913+
'/Users/someuser/Library/Application Support/dart/pub-credentials.json');
914+
});
915+
916+
test('Windows', () async {
917+
platform = MockPlatform(isWindows: true);
918+
platform.environment['APPDATA'] = r'C:\Users\SomeUser\AppData';
919+
command = PublishCommand(packagesDir, platform: platform);
920+
921+
expect(command.credentialsPath,
922+
r'C:\Users\SomeUser\AppData\dart\pub-credentials.json');
923+
});
924+
});
883925
}
884926

885927
/// An extension of [RecordingProcessRunner] that stores 'flutter pub publish'

0 commit comments

Comments
 (0)