roleClassNameProblems function

List<String> roleClassNameProblems(
  1. Iterable<Role<Object>> roles, {
  2. String root = '.',
  3. FileSystem fileSystem = const LocalFileSystem(),
})

The strings in the code of the package in the directory root, the current directory by default, and of the module packages it depends on, that spell out the name of a class that one of roles requires: one line for each, with the path of its file and the line of the name.

Generated code takes the name of such a class, such as the AppShell of the layout role, from the role, as '${LayoutRole.appShell.name}(' does, so that it follows the role. The classes are the RequiredClasses of the interfaces of roles, and a string spells one out when its text between its interpolations has the name followed by (. Comments and code outside strings, such as a Destination(...) of the DSL of the router, do not count, nor do the files in lib/bundles/, which bricks generate.

It tells the module packages as ModulePackage does: they are smf_contracts, smf_pipeline and every package that depends on smf_contracts, which it finds through the package config that dart pub get writes. Without the package config, or without the pubspec of a package it has to tell, the problems ask to run dart pub get.

test('takes the names of the classes of roles from the roles', () {
  expect(roleClassNameProblems(ModuleRegistry(modules).roles), isEmpty);
});

Implementation

List<String> roleClassNameProblems(
  Iterable<Role> roles, {
  String root = '.',
  FileSystem fileSystem = const LocalFileSystem(),
}) {
  final directory = fileSystem.directory(root);
  final pubspecFile = directory.childFile('pubspec.yaml');
  final pubspec = pubspecFile.existsSync()
      ? loadYaml(pubspecFile.readAsStringSync())
      : null;
  if (pubspec case final YamlMap map && {'name': final String name}) {
    final packages = ResolvedPackages.of(directory);
    if (packages == null) return [ResolvedPackages.missingConfig(root)];
    final checked = [(name, directory), ..._modulePackagesOf(map, packages)];
    final classes = _requiredClassesOf(roles);
    final problems = [
      for (final (package, packageRoot) in checked)
        for (final (path, file) in dartFilesIn(packageRoot, 'lib'))
          if (!path.startsWith('lib/bundles/'))
            ..._problemsOf('$package/$path', file.readAsStringSync(), classes),
    ];
    return [...packages.problems, ...problems];
  }
  return ['The directory $root has no pubspec.yaml.'];
}