generate method

Future<({List<String> removed, List<String> written})> generate({
  1. List<String> packages = const [],
})

Saves the edits in the project cache as patch files, and returns the patch paths written and removed, relative to the patch directory.

Only *.patch files under hosted/ and git/ in the patch directory are written or removed. With packages, only those packages' patches are touched.

Implementation

Future<({List<String> written, List<String> removed})> generate({
  List<String> packages = const [],
}) async {
  if (!hasBaseline) {
    throw DpkException(
      'The project cache has no baseline yet. Run "dpk get" in project '
      'mode first.',
    );
  }
  await updateBaseline();

  final diffs = <String, String>{};
  diffs.addAll(await _hostedDiffs());
  for (final checkout in _gitCheckouts()) {
    final diff = await _diff(checkout, const ['.']);
    if (diff.isNotEmpty) {
      diffs['git/${p.basename(checkout)}.patch'] = diff;
    }
  }

  bool selected(String relativePath) {
    if (packages.isEmpty) {
      return true;
    }
    final folder = p.basenameWithoutExtension(relativePath);
    final name = _splitFolder(folder).name;
    return packages.contains(name) || packages.contains(folder);
  }

  final written = <String>[];
  for (final MapEntry(key: relativePath, value: diff) in diffs.entries) {
    if (!selected(relativePath)) {
      continue;
    }
    final file = File(p.join(patchPath, relativePath));
    if (file.existsSync() && file.readAsStringSync() == diff) {
      continue;
    }
    file
      ..createSync(recursive: true)
      ..writeAsStringSync(diff);
    written.add(relativePath);
  }

  final removed = <String>[];
  for (final patch in patches()) {
    if (selected(patch.relativePath) &&
        !diffs.containsKey(patch.relativePath)) {
      patch.file.deleteSync();
      removed.add(patch.relativePath);
    }
  }
  return (written: written, removed: removed);
}