|
1 | 1 | package fr.chuckame.marlinfw.configurator;
|
2 | 2 |
|
3 |
| -import fr.chuckame.marlinfw.configurator.change.LineChange; |
4 |
| -import fr.chuckame.marlinfw.configurator.change.LineChangeFormatter; |
5 |
| -import fr.chuckame.marlinfw.configurator.change.LineChangeManager; |
6 |
| -import fr.chuckame.marlinfw.configurator.constant.Constant; |
7 |
| -import fr.chuckame.marlinfw.configurator.constant.ProfilePropertiesChangeAdapter; |
8 |
| -import fr.chuckame.marlinfw.configurator.profile.ProfilePropertiesParser; |
9 |
| -import fr.chuckame.marlinfw.configurator.util.FileHelper; |
10 |
| -import lombok.RequiredArgsConstructor; |
11 |
| -import org.springframework.boot.ApplicationArguments; |
12 |
| -import org.springframework.boot.ApplicationRunner; |
13 | 3 | import org.springframework.boot.SpringApplication;
|
14 | 4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
|
15 |
| -import reactor.core.publisher.Flux; |
16 |
| -import reactor.core.publisher.Mono; |
17 |
| -import reactor.util.function.Tuple2; |
18 |
| - |
19 |
| -import java.nio.file.Path; |
20 |
| -import java.util.Collection; |
21 |
| -import java.util.List; |
22 |
| -import java.util.Map; |
23 |
| -import java.util.Scanner; |
24 |
| -import java.util.function.Function; |
25 |
| -import java.util.function.Predicate; |
26 |
| -import java.util.stream.Collectors; |
27 | 5 |
|
28 | 6 | @SpringBootApplication
|
29 |
| -@RequiredArgsConstructor |
30 |
| -public class MarlinConfigurator implements ApplicationRunner { |
| 7 | +public class MarlinConfigurator { |
31 | 8 | public static void main(final String[] args) {
|
32 |
| - SpringApplication.run(MarlinConfigurator.class, args); |
33 |
| - } |
34 |
| - |
35 |
| - private final ProfilePropertiesChangeAdapter changeAdapter; |
36 |
| - private final LineChangeManager lineChangeManager; |
37 |
| - private final LineChangeFormatter lineChangeFormatter; |
38 |
| - private final ProfilePropertiesParser profilePropertiesParser; |
39 |
| - private final FileHelper fileHelper; |
40 |
| - |
41 |
| - // get profileProperties |
42 |
| - // get lines of file |
43 |
| - // prepare profileProperties in memory |
44 |
| - // prompt the user all changes (E/E&C/D) and ERRORs |
45 |
| - // prompt WARN when missing constants that are defined into profile |
46 |
| - // is no error, apply changes into files if user agree (or if --yes arg) |
47 |
| - |
48 |
| - @Override |
49 |
| - public void run(final ApplicationArguments args) throws Exception { |
50 |
| - try { |
51 |
| - final Path profilePath = getRequiredArgPath("profile", args); |
52 |
| - final List<Path> filesPath = getRequiredArgPaths("file", args); |
53 |
| - final boolean forceApply = args.containsOption("apply"); |
54 |
| - |
55 |
| - profilePropertiesParser.parseFromFile(profilePath) |
56 |
| - .map(changeAdapter::getWantedConstants) |
57 |
| - .flatMap(wantedConstants -> |
58 |
| - prepareChanges(filesPath, wantedConstants) |
59 |
| - .flatMap(changes -> printChanges(changes) |
60 |
| - .then(printUnusedConstants(changes, wantedConstants)) |
61 |
| - .then(checkIfUserAgree(forceApply)) |
62 |
| - .then(applyAndSaveChanges(changes))) |
63 |
| - ) |
64 |
| - .blockOptional() |
65 |
| - ; |
66 |
| - } catch (final InvalidArgException e) { |
67 |
| - System.err.println(e.getMessage()); |
68 |
| - System.exit(1); |
69 |
| - } |
70 |
| - } |
71 |
| - |
72 |
| - private Mono<Void> printChanges(final Map<Path, List<LineChange>> changes) { |
73 |
| - return Flux.fromIterable(changes.entrySet()) |
74 |
| - .concatMap(fileChanges -> Flux.concat( |
75 |
| - Flux.just(String.format("%s change(s) for file %s:", fileChanges.getValue().size(), fileChanges.getKey())), |
76 |
| - Flux.fromIterable(fileChanges.getValue()).filter(LineChange::isConstant).map(lineChangeFormatter::format), |
77 |
| - Flux.just("") |
78 |
| - )) |
79 |
| - .doOnNext(System.out::println) |
80 |
| - .then() |
81 |
| - ; |
82 |
| - } |
83 |
| - |
84 |
| - private Mono<Void> printUnusedConstants(final Map<Path, List<LineChange>> changes, final Map<String, Constant> wantedConstants) { |
85 |
| - return lineChangeManager.getUnusedWantedConstants(changes.values().stream().flatMap(List::stream).collect(Collectors.toList()), wantedConstants) |
86 |
| - .collectList() |
87 |
| - .filter(Predicate.not(List::isEmpty)) |
88 |
| - .doOnNext(unusedConstants -> System.out.printf("Still some unused constants: %s%n", unusedConstants)) |
89 |
| - .then() |
90 |
| - ; |
91 |
| - } |
92 |
| - |
93 |
| - private Mono<Void> checkIfUserAgree(final boolean forceApply) { |
94 |
| - if (forceApply) { |
95 |
| - return Mono.empty(); |
96 |
| - } |
97 |
| - return Mono.fromRunnable(() -> System.out.println("Apply changes ? type 'y' to apply changes, or everything else to cancel")) |
98 |
| - .then(Mono.fromSupplier(() -> new Scanner(System.in).next())) |
99 |
| - .filter("y"::equals) |
100 |
| - .switchIfEmpty(Mono.error(() -> new InvalidArgException("User refused to apply"))) |
101 |
| - .then(); |
102 |
| - } |
103 |
| - |
104 |
| - public Mono<Map<Path, List<LineChange>>> prepareChanges(final List<Path> filesPath, final Map<String, Constant> wantedConstants) { |
105 |
| - return Flux.fromIterable(filesPath) |
106 |
| - .flatMap(filePath -> fileHelper.lines(filePath) |
107 |
| - .index() |
108 |
| - .concatMap(line -> lineChangeManager.prepareChange(line.getT2(), line.getT1().intValue(), wantedConstants)) |
109 |
| - .collectList() |
110 |
| - .zipWith(Mono.just(filePath))) |
111 |
| - .collectMap(Tuple2::getT2, Tuple2::getT1); |
112 |
| - } |
113 |
| - |
114 |
| - public Mono<Void> applyAndSaveChanges(final Map<Path, List<LineChange>> changes) { |
115 |
| - return Flux.fromIterable(changes.entrySet()) |
116 |
| - .groupBy(Map.Entry::getKey, Map.Entry::getValue) |
117 |
| - .flatMap(fileChanges -> fileHelper.write(fileChanges.key(), true, fileChanges.flatMap(this::applyChanges))) |
118 |
| - .then(); |
119 |
| - } |
120 |
| - |
121 |
| - public Flux<String> applyChanges(final Collection<LineChange> changes) { |
122 |
| - return Flux.fromIterable(changes).flatMap(lineChangeManager::applyChange); |
123 |
| - } |
124 |
| - |
125 |
| - private List<Path> getRequiredArgPaths(final String name, final ApplicationArguments args) { |
126 |
| - return Mono.justOrEmpty(args.getOptionValues(name)) |
127 |
| - .flatMapIterable(Function.identity()) |
128 |
| - .flatMap(v -> Mono.fromSupplier(() -> Path.of(v)) |
129 |
| - .doOnError(e -> new InvalidArgException("Invalid value for argument --%s: %s", name, e.getMessage()))) |
130 |
| - .collectList() |
131 |
| - .filter(Predicate.not(List::isEmpty)) |
132 |
| - .switchIfEmpty(Mono.error(() -> new InvalidArgException("Missing --%s argument", name))) |
133 |
| - .block(); |
134 |
| - } |
135 |
| - |
136 |
| - private Path getRequiredArgPath(final String name, final ApplicationArguments args) { |
137 |
| - return Flux.fromIterable(getRequiredArgPaths(name, args)) |
138 |
| - .single() |
139 |
| - .onErrorMap(IndexOutOfBoundsException.class, e -> new InvalidArgException("Only one --%s is allowed", name)) |
140 |
| - .block(); |
| 9 | + SpringApplication.run(MarlinConfigurator.class, "apply-profiled", "--save", "--profile", "src/test/resources/profile.yaml", "--file", "src/test/resources/file.h"); |
| 10 | + //SpringApplication.run(MarlinConfigurator.class, "generate-profile", "--input", "src/test/resources/file.h", "--output", "src/test/resources/profile.yaml"); |
141 | 11 | }
|
142 | 12 | }
|
143 | 13 |
|
144 |
| -class InvalidArgException extends RuntimeException { |
145 |
| - public InvalidArgException(final String format, final Object... args) { |
146 |
| - super(String.format(format, args)); |
147 |
| - } |
148 |
| -} |
0 commit comments