Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,14 @@ commands:
- run:
name: Install and set up melos
command: |
flutter pub global activate melos 1.3.0
melos bootstrap
flutter pub global activate melos
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any value in pinning this anymore?

install_aft:
steps:
- run:
name: Install and set up aft
command: |
flutter pub global activate -spath packages/aft
aft bootstrap
activate_pana:
steps:
- run:
Expand All @@ -56,6 +62,7 @@ jobs:
steps:
- install_flutter
- checkout
- install_aft
- install_melos
- run: melos run format

Expand All @@ -64,6 +71,7 @@ jobs:
steps:
- install_flutter
- checkout
- install_aft
- install_melos
- run:
name: Analyze Dart/Flutter Code
Expand All @@ -78,6 +86,7 @@ jobs:
steps:
- install_flutter
- checkout
- install_aft
- install_melos
- activate_pana
- run:
Expand All @@ -92,6 +101,7 @@ jobs:
steps:
- install_flutter
- checkout
- install_aft
- install_melos
- run:
name: Install junitreport for JUnit XML reports
Expand Down Expand Up @@ -125,6 +135,7 @@ jobs:
steps:
- install_flutter
- checkout
- install_aft
- install_melos
- run:
name: Pre-start iOS simulator
Expand Down Expand Up @@ -161,6 +172,7 @@ jobs:
steps:
- install_flutter
- checkout
- install_aft
- install_melos
- run:
name: Build example APKs
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Podfile.lock
.last_build_id
.fvm/
.packages
pubspec_overrides.yaml

# IDEs
.idea/
Expand Down
4 changes: 4 additions & 0 deletions deps.yaml → aft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ dependencies:
json_annotation: ^4.4.0
json_serializable: ^6.1.0
uuid: 3.0.6

# Packages to ignore in all repo operations
ignore:
- synthetic_package
9 changes: 8 additions & 1 deletion packages/aft/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ A CLI tool for managing the Amplify Flutter repository.

## Commands

- `deps check`: Checks dependencies of all packages against `deps.yaml`
- `bootstrap`/`bs`: Sets up repo for development work
- `clean`: Cleans temporary files and build artifacts for all packages
- `deps check`: Checks dependencies of all packages against `aft.yaml`
- `generate-sdk`: Generates the AWS SDK for a given package
- `link`: Links all packages together using `pubspec_overrides.yaml`
- `list`: Lists all packages in the repo
- `pub`: Run pub commands for all packages in the repo
- `get`: Runs `dart pub get`/`flutter pub get` for all packages
- `upgrade`: Runs `dart pub upgrade`/`flutter pub upgrade` for all packages
- `publish`: Runs `dart pub publish`/`flutter pub publish` for all packages which need publishing
33 changes: 31 additions & 2 deletions packages/aft/bin/aft.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:io';

import 'package:aft/aft.dart';
import 'package:args/command_runner.dart';

Expand All @@ -23,8 +25,35 @@ Future<void> main(List<String> args) async {
help: 'Prints verbose logs',
defaultsTo: false,
)
..argParser.addOption(
'directory',
help: 'Directory to run commands from. Defaults to current directory.',
hide: true,
)
..addCommand(GenerateSdkCommand())
..addCommand(ListPackagesCommand())
..addCommand(DepsCommand());
await runner.run(args);
..addCommand(DepsCommand())
..addCommand(LinkCommand())
..addCommand(CleanCommand())
..addCommand(PubCommand())
..addCommand(BootstrapCommand());
try {
await runner.run(args);
} on UsageException catch (e) {
stderr
..writeln(e.message)
..writeln(e.usage);
exitCode = 1;
} on Object catch (e, st) {
stderr
..writeln(e.toString())
..writeln(st);
exitCode = 1;
} finally {
// Free up resources before exiting..
for (final command in runner.commands.values.whereType<AmplifyCommand>()) {
command.close();
}
exit(exitCode);
}
}
6 changes: 6 additions & 0 deletions packages/aft/lib/aft.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
library aft;

export 'src/commands/amplify_command.dart';
export 'src/commands/bootstrap_command.dart';
export 'src/commands/clean_command.dart';
export 'src/commands/deps_command.dart';
export 'src/commands/generate_sdk_command.dart';
export 'src/commands/link_command.dart';
export 'src/commands/list_packages_command.dart';
export 'src/commands/pub_command.dart';
export 'src/commands/publish_command.dart';
export 'src/models.dart';
export 'src/pub/pub_runner.dart';
100 changes: 81 additions & 19 deletions packages/aft/lib/src/commands/amplify_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,43 @@ import 'dart:io';
import 'package:aft/aft.dart';
import 'package:args/command_runner.dart';
import 'package:async/async.dart';
import 'package:aws_common/aws_common.dart';
import 'package:checked_yaml/checked_yaml.dart';
import 'package:cli_util/cli_logging.dart';
import 'package:collection/collection.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
import 'package:pub/pub.dart';
import 'package:stream_transform/stream_transform.dart';

const _ignorePackages = [
'synthetic_package',
];

abstract class AmplifyCommand extends Command<void> {
/// Base class for all commands in this package providing common functionality.
abstract class AmplifyCommand extends Command<void> implements Closeable {
/// Whether verbose logging is enabled.
late final verbose = globalResults!['verbose'] as bool;
late final bool verbose = globalResults!['verbose'] as bool;

/// The configured logger for the command.
late final Logger logger = verbose ? Logger.verbose() : Logger.standard();

/// The current working directory.
late final Directory workingDirectory = () {
final directory = globalResults?['directory'] as String?;
if (directory == null) {
return Directory.current;
}
return Directory(directory);
}();

_PubHttpClient? _httpClient;

/// HTTP client for remote operations.
http.Client get httpClient => _httpClient ??= _PubHttpClient();

final _rootDirMemo = AsyncMemoizer<Directory>();

/// The root directory of the Amplify Flutter repo.
Future<Directory> get rootDir => _rootDirMemo.runOnce(() async {
var dir = Directory.current;
var dir = workingDirectory;
while (dir.parent != dir) {
final files = dir.list(followLinks: false).whereType<File>();
await for (final file in files) {
Expand All @@ -53,14 +69,15 @@ abstract class AmplifyCommand extends Command<void> {
);
});

final _allPackagesMemo = AsyncMemoizer<List<PackageInfo>>();
final _allPackagesMemo = AsyncMemoizer<Map<String, PackageInfo>>();

/// All packages in the Amplify Flutter repo.
Future<List<PackageInfo>> get allPackages =>
Future<Map<String, PackageInfo>> get allPackages =>
_allPackagesMemo.runOnce(() async {
final allDirs = (await rootDir)
.list(recursive: true, followLinks: false)
.whereType<Directory>();
final aftConfig = await this.aftConfig;

final allPackages = <PackageInfo>[];
await for (final dir in allDirs) {
Expand All @@ -69,7 +86,7 @@ abstract class AmplifyCommand extends Command<void> {
continue;
}
final pubspec = pubspecInfo.pubspec;
if (_ignorePackages.contains(pubspec.name)) {
if (aftConfig.ignore.contains(pubspec.name)) {
continue;
}
allPackages.add(
Expand All @@ -82,18 +99,63 @@ abstract class AmplifyCommand extends Command<void> {
),
);
}
return allPackages..sort();
return UnmodifiableMapView({
for (final package in allPackages..sort()) package.name: package,
});
});

final _globalDependencyConfigMemo = AsyncMemoizer<GlobalDependencyConfig>();
final _aftConfigMemo = AsyncMemoizer<AftConfig>();

/// The global dependency configuration for the repo.
Future<GlobalDependencyConfig> get globalDependencyConfig =>
_globalDependencyConfigMemo.runOnce(() async {
/// The global `aft` configuration for the repo.
Future<AftConfig> get aftConfig => _aftConfigMemo.runOnce(() async {
final rootDir = await this.rootDir;
final depsFile = File(p.join(rootDir.path, 'deps.yaml'));
assert(depsFile.existsSync(), 'Could not find deps.yaml');
final depsYaml = depsFile.readAsStringSync();
return checkedYamlDecode(depsYaml, GlobalDependencyConfig.fromJson);
final configFile = File(p.join(rootDir.path, 'aft.yaml'));
assert(configFile.existsSync(), 'Could not find aft.yaml');
final configYaml = configFile.readAsStringSync();
return checkedYamlDecode(configYaml, AftConfig.fromJson);
});

/// A command runner for `pub`.
PubCommandRunner createPubRunner() => PubCommandRunner(
pubCommand(isVerbose: () => verbose),
);

/// Displays a prompt to the user and waits for a response on stdin.
String prompt(String prompt) {
String? response;
while (response == null) {
stdout.write(prompt);
response = stdin.readLineSync();
}
return response;
}

@override
@mustCallSuper
void close() {
_httpClient?._close();
}
}

/// An HTTP client which can be used by processes which call `client.close()`
/// outside our control, like `pub`.
class _PubHttpClient extends http.BaseClient {
_PubHttpClient([http.Client? inner]) : _inner = inner ?? http.Client();

final http.Client _inner;

@override
Future<http.StreamedResponse> send(http.BaseRequest request) {
return _inner.send(request);
}

@override
void close() {
// Do nothing
}

// Actually close
void _close() {
_inner.close();
}
}
Loading