From bf765507f15da8fbd23377d3f0d4df96b940b6d9 Mon Sep 17 00:00:00 2001 From: Kelvin Kavisi <68240897+kekavc24@users.noreply.github.com> Date: Thu, 21 Dec 2023 22:58:45 +0000 Subject: [PATCH] refactor: clean up manager & subclasses > add `ConsolePrinter` as required arg d9df525 > clean up `FinderManager` & `ReplacerManager`. Reduce bloated code which made it hard to follow code > add file number when calling reset in tracker 909ad98 > add initial final touches that makes the managers complete and ready for tests > customize enums & typedefs for manager use --- .gitignore | 1 + .../managers/finder_manager.dart | 151 ++++++++---------- .../yaml_transformers/managers/manager.dart | 22 ++- .../managers/replacer_manager.dart | 81 +++++----- lib/src/utils/enums/enums.dart | 11 +- .../extensions/arg_results_extension.dart | 3 +- lib/src/utils/typedefs/typedefs.dart | 3 +- 7 files changed, 149 insertions(+), 123 deletions(-) diff --git a/.gitignore b/.gitignore index cc74417..362324e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ pubspec.lock doc/api/ # Files generated during & for tests +.vscode/ .test_coverage.dart coverage/ .test_runner.dart diff --git a/lib/src/core/yaml_transformers/managers/finder_manager.dart b/lib/src/core/yaml_transformers/managers/finder_manager.dart index 0fbb2aa..3a9ae1b 100644 --- a/lib/src/core/yaml_transformers/managers/finder_manager.dart +++ b/lib/src/core/yaml_transformers/managers/finder_manager.dart @@ -12,68 +12,63 @@ class FinderManager extends TransformerManager implements ManageByCount { FinderManager._({ required super.files, required super.aggregator, - required KeysToFind keysToFind, - required ValuesToFind valuesToFind, - required PairsToFind pairsToFind, - required FinderType finderType, - }) : _finderType = finderType, - _keysToFind = keysToFind, - _valuesToFind = valuesToFind, - _pairsToFind = pairsToFind; + required super.printer, + KeysToFind? keysToFind, + ValuesToFind? valuesToFind, + PairsToFind? pairsToFind, + FinderType? finderType, + }) : _finderType = finderType ?? FinderType.byValue, + _keysToFind = keysToFind ?? (keys: [], orderType: OrderType.loose), + _valuesToFind = valuesToFind ?? [], + _pairsToFind = pairsToFind ?? {}; - factory FinderManager.forFinder({ + FinderManager.fullSetup({ required List files, required Aggregator aggregator, + required ConsolePrinter printer, required KeysToFind keysToFind, required ValuesToFind valuesToFind, required PairsToFind pairsToFind, - FinderType? finderType, - }) { - return FinderManager._( - files: files, - aggregator: aggregator, - finderType: finderType ?? FinderType.byValue, - keysToFind: keysToFind, - valuesToFind: valuesToFind, - pairsToFind: pairsToFind, - ); - } + required FinderType finderType, + }) : this._( + files: files, + aggregator: aggregator, + printer: printer, + keysToFind: keysToFind, + valuesToFind: valuesToFind, + pairsToFind: pairsToFind, + finderType: finderType, + ); - factory FinderManager.findValues({ + FinderManager.findValues({ required List files, required Aggregator aggregator, + required ConsolePrinter printer, required ValuesToFind valuesToFind, - }) { - return FinderManager._( - files: files, - aggregator: aggregator, - keysToFind: (keys: [], orderType: OrderType.loose), - valuesToFind: valuesToFind, - pairsToFind: {}, - finderType: FinderType.byValue, - ); - } + }) : this._( + files: files, + aggregator: aggregator, + printer: printer, + valuesToFind: valuesToFind, + ); - factory FinderManager.findeKeys({ + FinderManager.findKeys({ required List files, required Aggregator aggregator, + required ConsolePrinter printer, required KeysToFind keysToFind, - }) { - return FinderManager._( - files: files, - aggregator: aggregator, - keysToFind: keysToFind, - valuesToFind: [], - pairsToFind: {}, - finderType: FinderType.byValue, - ); - } + }) : this._( + files: files, + aggregator: aggregator, + printer: printer, + keysToFind: keysToFind, + ); - late FinderType _finderType; + final FinderType _finderType; - late KeysToFind _keysToFind; - late ValuesToFind _valuesToFind; - late PairsToFind _pairsToFind; + final KeysToFind _keysToFind; + final ValuesToFind _valuesToFind; + final PairsToFind _pairsToFind; /// Obtains the current generator to be used/ currently in use by /// this manager @@ -82,36 +77,40 @@ class FinderManager extends TransformerManager implements ManageByCount { ? transformAll(resetTracker: true) : transformByCount( aggregator.count!, - applyToEach: aggregator.applyToEach, + applyToEachArg: aggregator.applyToEachArg, + applyToEachFile: aggregator.applyToEachFile, ); } /// Prefills the tracker with keys for accurate value tracking void _prefillTracker() { for (final data in keysToPrefill()) { + if (data.keys.isEmpty) continue; + _tracker.prefill(data.keys, origin: data.origin); } } @override Future transform() async { - - // TODO: Add match formatter/aggregator - for (final match in getGenerator()) {} + // Loop all matches and add to printer + for (final match in getGenerator()) { + _printer.addValuesFound(match.currentFile, match.data); + } } @override Iterable transformByCount( int count, { - required bool applyToEach, - bool applyToEachFile = true, + required bool applyToEachArg, + required bool applyToEachFile, }) sync* { // Prefill tracker _prefillTracker(); /// If we are not applying to each file and neither are we applying to /// to each argument. Return just count - if (!applyToEachFile && !applyToEach) { + if (!applyToEachFile && !applyToEachArg) { yield* transformAll(resetTracker: true).take(count); } @@ -129,7 +128,7 @@ class FinderManager extends TransformerManager implements ManageByCount { /// // we never reset the tracker, terminate once arg conditions are met - else if (!applyToEachFile && applyToEach) { + else if (!applyToEachFile && applyToEachArg) { yield* transformAll(resetTracker: false).takeWhile( (value) => !value.reachedLimit, ); @@ -148,22 +147,18 @@ class FinderManager extends TransformerManager implements ManageByCount { var countForEachFile = {}; /// When `applyToEach` argument is true, we track current active file & - /// whether we reach the limit for count for each argument and yielded the - /// last value that triggered the match + /// whether we reached the limit for count for each argument and yielded + /// the last value that triggered the match var currentFile = 0; /// We create our custom queue with all files var customQueue = QueueList.from(yamlQueue); // Setup all our variables for tracking exiting current transformation - if (!applyToEach) { - countForEachFile = yamlQueue.asMap().keys.fold( - {}, - (previousValue, element) { - previousValue.addAll({element: 0}); - return previousValue; - }, - ); + if (!applyToEachArg) { + countForEachFile = {}..addEntries( + yamlQueue.mapIndexed((index, element) => MapEntry(index, 0)), + ); } /// Our queue will act as the reference for controlling the loop @@ -178,7 +173,7 @@ class FinderManager extends TransformerManager implements ManageByCount { /// /// When `applyToEach` argument is false, we break loop if count for /// matches generated for this file has been reached - if (!applyToEach) { + if (!applyToEachArg) { if (countForEachFile[match.currentFile] == count) break; // Increment its count if loop wasn't broken @@ -233,15 +228,16 @@ class FinderManager extends TransformerManager implements ManageByCount { required bool resetTracker, QueueList? customQueue, }) sync* { + final numOfFiles = yamlQueue.length; final localQueue = customQueue ?? QueueList.from(yamlQueue); do { // Index of current file - final currentFile = yamlQueue.length - localQueue.length; + final currentFile = numOfFiles - localQueue.length; // Reset tracker if not first run, since we havent completed it. if (localQueue.length != yamlQueue.length && resetTracker) { - super.resetTracker(); + super.resetTracker(currentFile - 1); } final yamlMap = localQueue.removeFirst(); // Get file, remove from list @@ -260,23 +256,18 @@ class FinderManager extends TransformerManager implements ManageByCount { ); } } while (localQueue.isNotEmpty); + + // Reset the tracker and put last tracker into the history + if (resetTracker) super.resetTracker(numOfFiles - 1); } @override List keysToPrefill() { - final keys = []; - - if (_keysToFind.keys.isNotEmpty) { - keys.add((keys: _keysToFind.keys, origin: Origin.key)); - } - if (_valuesToFind.isNotEmpty) { - keys.add((keys: _valuesToFind, origin: Origin.value)); - } - if (_pairsToFind.isNotEmpty) { - keys.add((keys: _pairsToFind.entries.toList(), origin: null)); - } - - return keys; + return [ + (keys: _keysToFind.keys, origin: Origin.key), + (keys: _valuesToFind, origin: Origin.value), + (keys: _pairsToFind.entries.toList(), origin: null), + ]; } /// Get finder for this manager diff --git a/lib/src/core/yaml_transformers/managers/manager.dart b/lib/src/core/yaml_transformers/managers/manager.dart index bcd95d7..36c47f6 100644 --- a/lib/src/core/yaml_transformers/managers/manager.dart +++ b/lib/src/core/yaml_transformers/managers/manager.dart @@ -1,4 +1,5 @@ import 'package:collection/collection.dart'; +import 'package:magical_version_bump/src/core/yaml_transformers/console_printer/console_printer.dart'; import 'package:magical_version_bump/src/core/yaml_transformers/managers/tranform_tracker/transform_tracker.dart'; import 'package:magical_version_bump/src/core/yaml_transformers/yaml_transformer.dart'; import 'package:magical_version_bump/src/utils/enums/enums.dart'; @@ -14,7 +15,9 @@ abstract class TransformerManager { TransformerManager({ required List files, required Aggregator aggregator, + ConsolePrinter? printer, }) : _aggregator = aggregator, + _printer = printer ?? ConsolePrinter(format: aggregator.viewFormat), _yamlQueue = QueueList.from(files.map((e) => e.fileAsMap)), _tracker = TransformTracker(limit: aggregator.count); @@ -24,6 +27,10 @@ abstract class TransformerManager { /// A custom Aggregator for this transformer final Aggregator _aggregator; + /// A console printer for each manager that will is called by each + /// command's handler to print to console all aggregated info + final ConsolePrinter _printer; + /// Tracker for keeping track of transformations made. final TransformTracker _tracker; @@ -36,6 +43,8 @@ abstract class TransformerManager { /// Tracker in use by this manager TransformTracker get tracker => _tracker; + ConsolePrinter get printer => _printer; + /// Increments the count of a tracked value being transformed in the /// tracker using a [ String ] void incrementWithStrings(List values, {required Origin origin}) { @@ -56,7 +65,7 @@ abstract class TransformerManager { } /// Resets tracker and saves current state to history - void resetTracker() => _tracker.reset(); + void resetTracker(int fileNumber) => _tracker.reset(fileNumber: fileNumber); /// Initializes transformer manager Future transform(); @@ -83,9 +92,16 @@ abstract interface class ManageByCount { /// /// [ count ] - denotes number of values to extract /// - /// [ applyToEach ] - denotes whether each unique matcher should be + /// [ applyToEachArg ] - denotes whether each unique matcher should be /// transformed by this count - void transformByCount(int count, {required bool applyToEach}); + /// + /// [ applyToEachFile ] - denotes whether each file should be transformed + /// by count + void transformByCount( + int count, { + required bool applyToEachArg, + required bool applyToEachFile, + }); /// Transforms all void transformAll({required bool resetTracker}); diff --git a/lib/src/core/yaml_transformers/managers/replacer_manager.dart b/lib/src/core/yaml_transformers/managers/replacer_manager.dart index e86c532..a7adb7b 100644 --- a/lib/src/core/yaml_transformers/managers/replacer_manager.dart +++ b/lib/src/core/yaml_transformers/managers/replacer_manager.dart @@ -4,58 +4,55 @@ class ReplacerManager extends TransformerManager { ReplacerManager._({ required super.files, required super.aggregator, + required super.printer, required this.commandType, required this.replacer, - required this.generator, - }); + required this.manager, + }) : assert( + !commandType.isFinder, + 'Only replace and rename commands are allowed', + ); factory ReplacerManager.create({ required WalkSubCommandType commandType, required List files, required Aggregator aggregator, + required ConsolePrinter printer, required List targets, - Iterable? generator, - Replacer? replacer, }) { - assert( - !commandType.isFinder, - 'Only replace and rename commands are supported for now', - ); - - final replacerForManager = replacer ?? - _getReplacer( - commandType, - targets: targets, - ); + final replacer = _getReplacer(commandType, targets: targets); return ReplacerManager._( files: files, aggregator: aggregator, + printer: printer, commandType: commandType, - replacer: replacerForManager, - generator: generator ?? - _getGenerator( - commandType, - files: files, - aggregator: aggregator, - replacer: replacerForManager, - ), + replacer: replacer, + manager: _getManager( + commandType, + files: files, + aggregator: aggregator, + printer: printer, + replacer: replacer, + ), ); } final WalkSubCommandType commandType; - final Iterable generator; + final FinderManager manager; final Replacer replacer; + TransformTracker get finderTracker => manager.tracker; + @override Future transform() async { // Modifiable queue we can read and swap modifiable values back and forth final localQueue = QueueList.from(yamlQueue); - for (final output in generator) { - var file = localQueue[output.currentFile]; // Get yaml file + for (final match in manager.getGenerator()) { + var file = localQueue[match.currentFile]; // Get yaml file // Prevents unnecessary replacement for deeply nested keys var canReplace = true; @@ -65,12 +62,12 @@ class ReplacerManager extends TransformerManager { /// keys already renamed! Caveat of indexing to terminal value if (commandType == WalkSubCommandType.rename) { final keyPath = (replacer as MagicalRenamer).replaceDryRun( - output.data, + match.data, ); /// Store file number and key path. Guarantees some level of uniqueness /// and also ties it to a file - final keyInTracker = '${output.currentFile},$keyPath'; + final keyInTracker = '${match.currentFile},$keyPath'; // Make sure the key path has just 1 of it if (getCountOfValue(keyInTracker, origin: Origin.key) == 1) { @@ -82,19 +79,26 @@ class ReplacerManager extends TransformerManager { // Replace if current value is not being tracked. if (canReplace) { - file = replacer.replace(file, matchedNodeData: output.data); + final output = replacer.replace(file, matchedNodeData: match.data); // Swap old file in queue with new one localQueue.replaceRange( - output.currentFile, - output.currentFile, - [file], + match.currentFile, + match.currentFile, + [output.updatedMap], + ); + + // Add to printer + _printer.addValuesReplaced( + match.currentFile, + origin: commandType == WalkSubCommandType.rename + ? Origin.key + : Origin.value, + replacements: output.mapping, + oldPath: match.data.getPath(), ); } } - - // TODO: Swap the old yaml map in file saved with new yaml map - // TODO: Add match formatter/aggregator } } @@ -108,23 +112,26 @@ Replacer _getReplacer( }; } -Iterable _getGenerator( +FinderManager _getManager( WalkSubCommandType commandType, { required List files, required Aggregator aggregator, + required ConsolePrinter printer, required Replacer replacer, }) { final manager = commandType == WalkSubCommandType.rename - ? FinderManager.findeKeys( + ? FinderManager.findKeys( files: files, aggregator: aggregator, + printer: printer, keysToFind: (replacer as MagicalRenamer).getTargets(), ) : FinderManager.findValues( files: files, aggregator: aggregator, + printer: printer, valuesToFind: (replacer as MagicalReplacer).getTargets(), ); - return manager.getGenerator(); + return manager; } diff --git a/lib/src/utils/enums/enums.dart b/lib/src/utils/enums/enums.dart index 6311b6a..6bac562 100644 --- a/lib/src/utils/enums/enums.dart +++ b/lib/src/utils/enums/enums.dart @@ -45,7 +45,16 @@ enum UpdateMode { } /// Type of subcommand that may have been triggered -enum WalkSubCommandType { find, search, rename, replace } +enum WalkSubCommandType { + find(isFinder: true), + search(isFinder: true), + rename(isFinder: false), + replace(isFinder: false); + + const WalkSubCommandType({required this.isFinder}); + + final bool isFinder; +} /// View format for printing values found by `Finder` or `MagicalReplacer` enum ConsoleViewFormat { diff --git a/lib/src/utils/extensions/arg_results_extension.dart b/lib/src/utils/extensions/arg_results_extension.dart index f3ba72a..2517b4f 100644 --- a/lib/src/utils/extensions/arg_results_extension.dart +++ b/lib/src/utils/extensions/arg_results_extension.dart @@ -115,7 +115,8 @@ extension WalkerResults on ArgResults { return ( type: _aggregatorType, - applyToEach: true, + applyToEachArg: true, + applyToEachFile: true, count: _aggregatorType == AggregateType.first ? 1 : _limit, viewFormat: viewFormat, ); diff --git a/lib/src/utils/typedefs/typedefs.dart b/lib/src/utils/typedefs/typedefs.dart index 140401b..01c4e24 100644 --- a/lib/src/utils/typedefs/typedefs.dart +++ b/lib/src/utils/typedefs/typedefs.dart @@ -79,7 +79,8 @@ bool collectionsUnorderedMatch(dynamic e1, dynamic e2) => /// each output typedef Aggregator = ({ AggregateType type, - bool applyToEach, + bool applyToEachArg, + bool applyToEachFile, int? count, ConsoleViewFormat viewFormat, });