Indentations break the feed.
[SquirrelJME.git] / buildSrc / src / main / java / cc / squirreljme / plugin / multivm / NanoCoatBuiltInCleanTaskAction.java
blob59d998d7c48214b25b025d7b0e92b12d2dafbc33
1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // Multi-Phasic Applications: SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc.squirreljme.plugin.multivm;
12 import cc.squirreljme.plugin.multivm.csv.SharedCsvEntry;
13 import cc.squirreljme.plugin.multivm.ident.SourceTargetClassifier;
14 import com.opencsv.bean.CsvToBean;
15 import com.opencsv.bean.CsvToBeanBuilder;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.InputStreamReader;
19 import java.io.Reader;
20 import java.nio.file.Files;
21 import java.nio.file.OpenOption;
22 import java.nio.file.Path;
23 import java.nio.file.StandardOpenOption;
24 import java.util.Collections;
25 import java.util.LinkedHashSet;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.TreeMap;
29 import java.util.TreeSet;
30 import java.util.stream.Collectors;
31 import java.util.stream.Stream;
32 import org.gradle.api.Action;
33 import org.gradle.api.Task;
34 import org.gradle.api.provider.Provider;
36 /**
37 * Performs the actual cleaning of the NanoCoat Built-In ROM generated sources.
39 * This task is a bit more complicated because it will only clean up for a
40 * given ROM's output, while using workarounds for the shared directory.
42 * @since 2023/09/03
44 public class NanoCoatBuiltInCleanTaskAction
45 implements Action<Task>
47 /** The classifier for the cleaning. */
48 protected final SourceTargetClassifier classifier;
50 /** The ROM base path. */
51 private final Provider<Path> _romBasePath;
53 /** The shared path. */
54 private final Provider<Path> _sharedPath;
56 /** The specific path. */
57 private final Provider<Path> _specificPath;
59 /**
60 * Initializes the cleaning action.
62 * @param __classifier The classifier of what this is cleaning for.
63 * @param __romBasePath The base ROM path.
64 * @param __specificPath The specific module path.
65 * @param __sharedPath The shared path.
66 * @throws NullPointerException On null arguments.
67 * @since 2023/09/03
69 public NanoCoatBuiltInCleanTaskAction(SourceTargetClassifier __classifier,
70 Provider<Path> __romBasePath, Provider<Path> __specificPath,
71 Provider<Path> __sharedPath)
72 throws NullPointerException
74 if (__classifier == null || __romBasePath == null ||
75 __specificPath == null || __sharedPath == null)
76 throw new NullPointerException("NARG");
78 this.classifier = __classifier;
79 this._romBasePath = __romBasePath;
80 this._specificPath = __specificPath;
81 this._sharedPath = __sharedPath;
84 /**
85 * {@inheritDoc}
86 * @since 2023/09/03
88 @Override
89 public void execute(Task __task)
91 try
93 // Determine our specific ROM being used
94 Path ourSpecificPath = this._specificPath.get();
95 String ourSpecific = ourSpecificPath.getFileName().toString();
97 // Get all the specifics that have been found
98 Map<String, Path> specifics = this.__specifics();
100 // Nothing to actually delete?
101 if (specifics.isEmpty())
102 return;
104 // There are two sets of shared, the ones that are in our share
105 // set and the ones that are in the other share set... we can only
106 // remove ones that they do not use at all
107 Set<SharedCsvEntry> ourShared = new LinkedHashSet<>();
108 Set<SharedCsvEntry> otherShared = new LinkedHashSet<>();
110 // Load in all the shared entries
111 for (Map.Entry<String, Path> entry : specifics.entrySet())
113 String specific = entry.getKey();
114 Path specificPath = entry.getValue();
116 // Which one are we loading into?
117 Set<SharedCsvEntry> into;
118 if (specific.equals(ourSpecific))
119 into = ourShared;
120 else
121 into = otherShared;
123 // Perform the load
124 this.__load(into, specificPath);
127 // By removing everything from ours that is used by others, we
128 // have a set of shared entries which are not used elsewhere
129 ourShared.removeAll(otherShared);
131 // Go through everything and remove accordingly
132 Path root = this._romBasePath.get();
133 for (SharedCsvEntry entry : ourShared)
135 // Delete source and header file
136 Files.deleteIfExists(root.resolve(
137 VMHelpers.stringToPath(entry.getHeader())));
138 Files.deleteIfExists(root.resolve(
139 VMHelpers.stringToPath(entry.getSource())));
142 // Delete our own specific set
143 __task.getProject().delete(ourSpecificPath);
145 catch (IOException __e)
147 throw new RuntimeException(__e);
152 * Determines all the specific ROMs.
154 * @return The specific ROMs.
155 * @throws IOException On read errors.
156 * @since 2023/09/03
158 private Map<String, Path> __specifics()
159 throws IOException
161 // If the build is clean, this will always return nothing
162 Path root = this._romBasePath.get();
163 Path specificRoot = root.resolve("specific");
164 if (!Files.exists(root) || !Files.exists(specificRoot))
165 return Collections.emptyMap();
167 // Determine all specifics available
168 Map<String, Path> result = new TreeMap<>();
169 try (Stream<Path> stream = Files.list(specificRoot))
171 for (Path path : stream.collect(Collectors.toList()))
172 if (Files.exists(path.resolve("shared.csv")))
173 result.put(path.getFileName().toString(), path);
176 return Collections.unmodifiableMap(result);
180 * Loads the shared entry lists.
182 * @param __into Which is this being loaded into?
183 * @param __base The base.
184 * @return {@code __into}.
185 * @throws IOException On read errors.
186 * @throws NullPointerException On null arguments.
187 * @since 2023/09/03
189 private static Set<SharedCsvEntry> __load(Set<SharedCsvEntry> __into,
190 Path __base)
191 throws IOException, NullPointerException
193 if (__into == null || __base == null)
194 throw new NullPointerException("NARG");
196 // Make sure the target exists first
197 Path sharedPath = __base.resolve("shared.csv");
198 if (!Files.exists(sharedPath))
199 return __into;
201 // Read in everything
202 try (InputStream in = Files.newInputStream(sharedPath,
203 StandardOpenOption.READ);
204 Reader reader = new InputStreamReader(in, "utf-8"))
206 // Setup parser
207 CsvToBean<SharedCsvEntry> parser =
208 new CsvToBeanBuilder<SharedCsvEntry>(reader)
209 .withType(SharedCsvEntry.class)
210 .withIgnoreEmptyLine(true)
211 .withIgnoreLeadingWhiteSpace(true)
212 .build();
214 // Read in all entries
215 for (SharedCsvEntry entry : parser)
216 __into.add(entry);
219 return __into;