Skip to content

Commit

Permalink
[tool] Use new pub cache location for publish (flutter#3962)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
stuartmorgan authored May 11, 2023
1 parent 12d6717 commit 5b7d732
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 35 deletions.
58 changes: 33 additions & 25 deletions script/tool/lib/src/publish_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ class PublishCommand extends PackageLoopingCommand {
// `flutter_plugin_tools-v0.0.24`.
static const String _tagFormat = '%PACKAGE%-v%VERSION%';

/// Returns the correct path where the pub credential is stored.
@visibleForTesting
late final String credentialsPath =
_getCredentialsPath(platform: platform, path: path);

@override
final String name = 'publish';

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

void _ensureValidPubCredential() {
final String credentialsPath = _credentialsPath;
final File credentialFile = packagesDir.fileSystem.file(credentialsPath);
if (credentialFile.existsSync() &&
credentialFile.readAsStringSync().isNotEmpty) {
return;
}
final String? credential = io.Platform.environment[_pubCredentialName];
final String? credential = platform.environment[_pubCredentialName];
if (credential == null) {
printError('''
No pub credential available. Please check if `$credentialsPath` is valid.
Expand All @@ -415,42 +419,46 @@ If running this command on CI, you can set the pub credential content in the $_p
..writeStringSync(credential)
..closeSync();
}

/// Returns the correct path where the pub credential is stored.
@visibleForTesting
static String getCredentialPath() {
return _credentialsPath;
}
}

/// The path in which pub expects to find its credentials file.
final String _credentialsPath = () {
// This follows the same logic as pub:
// https://github.com/dart-lang/pub/blob/d99b0d58f4059d7bb4ac4616fd3d54ec00a2b5d4/lib/src/system_cache.dart#L34-L43
String? cacheDir;
final String? pubCache = io.Platform.environment['PUB_CACHE'];
if (pubCache != null) {
cacheDir = pubCache;
} else if (io.Platform.isWindows) {
final String? appData = io.Platform.environment['APPDATA'];
String _getCredentialsPath(
{required Platform platform, required p.Context path}) {
// See https://github.com/dart-lang/pub/blob/master/doc/cache_layout.md#layout
String? configDir;
if (platform.isLinux) {
String? configHome = platform.environment['XDG_CONFIG_HOME'];
if (configHome == null) {
final String? home = platform.environment['HOME'];
if (home == null) {
printError('"HOME" environment variable is not set.');
} else {
configHome = path.join(home, '.config');
}
}
if (configHome != null) {
configDir = path.join(configHome, 'dart');
}
} else if (platform.isWindows) {
final String? appData = platform.environment['APPDATA'];
if (appData == null) {
printError('"APPDATA" environment variable is not set.');
} else {
cacheDir = p.join(appData, 'Pub', 'Cache');
configDir = path.join(appData, 'dart');
}
} else {
final String? home = io.Platform.environment['HOME'];
} else if (platform.isMacOS) {
final String? home = platform.environment['HOME'];
if (home == null) {
printError('"HOME" environment variable is not set.');
} else {
cacheDir = p.join(home, '.pub-cache');
configDir = path.join(home, 'Library', 'Application Support', 'dart');
}
}

if (cacheDir == null) {
printError('Unable to determine pub cache location');
if (configDir == null) {
printError('Unable to determine pub con location');
throw ToolExit(1);
}

return p.join(cacheDir, 'credentials.json');
}();
return path.join(configDir, 'pub-credentials.json');
}
62 changes: 52 additions & 10 deletions script/tool/test/publish_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,26 @@ import 'util.dart';
void main() {
final String flutterCommand = getFlutterCommand(const LocalPlatform());

late MockPlatform platform;
late Directory packagesDir;
late MockGitDir gitDir;
late TestProcessRunner processRunner;
late PublishCommand command;
late CommandRunner<void> commandRunner;
late MockStdin mockStdin;
late FileSystem fileSystem;
// Map of package name to mock response.
late Map<String, Map<String, dynamic>> mockHttpResponses;

void createMockCredentialFile() {
final String credentialPath = PublishCommand.getCredentialPath();
fileSystem.file(credentialPath)
fileSystem.file(command.credentialsPath)
..createSync(recursive: true)
..writeAsStringSync('some credential');
}

setUp(() async {
platform = MockPlatform(isLinux: true);
platform.environment['HOME'] = '/home';
fileSystem = MemoryFileSystem();
packagesDir = createPackagesDirectory(fileSystem: fileSystem);
processRunner = TestProcessRunner();
Expand Down Expand Up @@ -71,14 +74,15 @@ void main() {
});

mockStdin = MockStdin();
commandRunner = CommandRunner<void>('tester', '')
..addCommand(PublishCommand(
packagesDir,
processRunner: processRunner,
stdinput: mockStdin,
gitDir: gitDir,
httpClient: mockClient,
));
command = PublishCommand(
packagesDir,
platform: platform,
processRunner: processRunner,
stdinput: mockStdin,
gitDir: gitDir,
httpClient: mockClient,
);
commandRunner = CommandRunner<void>('tester', '')..addCommand(command);
});

group('Initial validation', () {
Expand Down Expand Up @@ -880,6 +884,44 @@ void main() {
isNot(contains('git-push')));
});
});

group('credential location', () {
test('Linux with XDG', () async {
platform = MockPlatform(isLinux: true);
platform.environment['XDG_CONFIG_HOME'] = '/xdghome/config';
command = PublishCommand(packagesDir, platform: platform);

expect(
command.credentialsPath, '/xdghome/config/dart/pub-credentials.json');
});

test('Linux without XDG', () async {
platform = MockPlatform(isLinux: true);
platform.environment['HOME'] = '/home';
command = PublishCommand(packagesDir, platform: platform);

expect(
command.credentialsPath, '/home/.config/dart/pub-credentials.json');
});

test('macOS', () async {
platform = MockPlatform(isMacOS: true);
platform.environment['HOME'] = '/Users/someuser';
command = PublishCommand(packagesDir, platform: platform);

expect(command.credentialsPath,
'/Users/someuser/Library/Application Support/dart/pub-credentials.json');
});

test('Windows', () async {
platform = MockPlatform(isWindows: true);
platform.environment['APPDATA'] = r'C:\Users\SomeUser\AppData';
command = PublishCommand(packagesDir, platform: platform);

expect(command.credentialsPath,
r'C:\Users\SomeUser\AppData\dart\pub-credentials.json');
});
});
}

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

0 comments on commit 5b7d732

Please sign in to comment.