Skip to content

Commit a00302d

Browse files
committed
refactor: AppInfo dependencies map is now a list
Also turned public fields private with accessors.
1 parent 1d81c6d commit a00302d

File tree

4 files changed

+99
-52
lines changed

4 files changed

+99
-52
lines changed

src/main/java/org/codejive/jpm/Jpm.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,8 @@ public SyncResult install(String[] artifactNames, Map<String, String> extraRepos
186186
List<Path> files = Resolver.create(artifacts, repos).resolvePaths();
187187
SyncResult stats = FileUtils.syncArtifacts(files, directory, noLinks, true);
188188
if (artifactNames.length > 0) {
189-
for (String dep : artifactNames) {
190-
int p = dep.lastIndexOf(':');
191-
String name = dep.substring(0, p);
192-
String version = dep.substring(p + 1);
193-
appInfo.dependencies.put(name, version);
194-
}
195-
appInfo.repositories.putAll(repos);
189+
appInfo.dependencies().addAll(Arrays.asList(artifactNames));
190+
appInfo.repositories().putAll(repos);
196191
AppInfo.write(appInfo);
197192
}
198193
return stats;
@@ -254,7 +249,7 @@ private static String[] getArtifacts(String[] artifactNames, AppInfo appInfo) {
254249
}
255250

256251
private Map<String, String> getRepositories(Map<String, String> extraRepos, AppInfo appInfo) {
257-
Map<String, String> repos = new HashMap<>(appInfo.repositories);
252+
Map<String, String> repos = new HashMap<>(appInfo.repositories());
258253
repos.putAll(extraRepos);
259254
return repos;
260255
}

src/main/java/org/codejive/jpm/config/AppInfo.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import java.nio.file.Files;
77
import java.nio.file.Path;
88
import java.nio.file.Paths;
9+
import java.util.ArrayList;
910
import java.util.LinkedHashMap;
11+
import java.util.List;
1012
import java.util.Map;
1113
import org.yaml.snakeyaml.DumperOptions;
1214
import org.yaml.snakeyaml.Yaml;
@@ -18,22 +20,32 @@
1820
public class AppInfo {
1921
private Map<String, Object> yaml = new LinkedHashMap<>();
2022

21-
public Map<String, String> dependencies = new LinkedHashMap<>();
22-
public Map<String, String> repositories = new LinkedHashMap<>();
23-
public Map<String, String> actions = new LinkedHashMap<>();
23+
private final List<String> dependencies = new ArrayList<>();
24+
private final Map<String, String> repositories = new LinkedHashMap<>();
25+
private final Map<String, String> actions = new LinkedHashMap<>();
2426

2527
/** The official name of the app.yml file. */
2628
public static final String APP_INFO_FILE = "app.yml";
2729

30+
public List<String> dependencies() {
31+
return dependencies;
32+
}
33+
34+
public Map<String, String> repositories() {
35+
return repositories;
36+
}
37+
38+
public Map<String, String> actions() {
39+
return actions;
40+
}
41+
2842
/**
2943
* Returns the dependencies as an array of strings in the format "groupId:artifactId:version".
3044
*
3145
* @return An array of strings
3246
*/
3347
public String[] getDependencyGAVs() {
34-
return dependencies.entrySet().stream()
35-
.map(e -> e.getKey() + ":" + e.getValue())
36-
.toArray(String[]::new);
48+
return dependencies.toArray(String[]::new);
3749
}
3850

3951
/**
@@ -105,11 +117,15 @@ public static AppInfo read(Reader in) {
105117
// respective fields in the AppInfo object, leaving unknown information untouched
106118
// WARNING awful code ahead
107119
// Parse dependencies section
108-
if (appInfo.yaml.containsKey("dependencies")
109-
&& appInfo.yaml.get("dependencies") instanceof Map) {
110-
Map<String, Object> deps = (Map<String, Object>) appInfo.yaml.get("dependencies");
111-
for (Map.Entry<String, Object> entry : deps.entrySet()) {
112-
appInfo.dependencies.put(entry.getKey(), entry.getValue().toString());
120+
if (appInfo.yaml.containsKey("dependencies")) {
121+
if (appInfo.yaml.get("dependencies") instanceof Map) {
122+
Map<String, Object> deps = (Map<String, Object>) appInfo.yaml.get("dependencies");
123+
for (Map.Entry<String, Object> entry : deps.entrySet()) {
124+
appInfo.dependencies.add(entry.getKey() + ":" + entry.getValue());
125+
}
126+
} else if (appInfo.yaml.get("dependencies") instanceof List) {
127+
List<String> deps = (List<String>) appInfo.yaml.get("dependencies");
128+
appInfo.dependencies.addAll(deps);
113129
}
114130
}
115131
// Parse repositories section
@@ -169,7 +185,7 @@ public static void write(AppInfo appInfo, Writer out) {
169185
dopts.setPrettyFlow(true);
170186
Yaml yaml = new Yaml(dopts);
171187
// WARNING awful code ahead
172-
appInfo.yaml.put("dependencies", (Map<String, Object>) (Map) appInfo.dependencies);
188+
appInfo.yaml.put("dependencies", appInfo.dependencies);
173189
if (!appInfo.repositories.isEmpty()) {
174190
appInfo.yaml.put("repositories", (Map<String, Object>) (Map) appInfo.repositories);
175191
} else {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.codejive.jpm.config;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.io.IOException;
6+
import java.nio.file.Files;
7+
import java.nio.file.Path;
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.io.TempDir;
10+
11+
/** Tests for AppInfo class, focusing on action parsing and management. */
12+
class AppInfoLegacyTest {
13+
14+
@TempDir Path tempDir;
15+
16+
@Test
17+
void testUpdateLegacyDeps() throws IOException {
18+
// Create a test app.yml file with legacy dependencies map
19+
Path appYmlPath = tempDir.resolve("app.yml");
20+
String yamlContent = "dependencies:\n" + " com.example:test-lib: \"1.0.0\"\n";
21+
Files.writeString(appYmlPath, yamlContent);
22+
23+
AppInfo appInfo = AppInfo.read(appYmlPath);
24+
25+
// Test dependencies are still parsed correctly
26+
assertThat(appInfo.dependencies()).hasSize(1);
27+
assertThat(appInfo.dependencies()).contains("com.example:test-lib:1.0.0");
28+
29+
AppInfo.write(appInfo, appYmlPath);
30+
31+
// Verify the file now uses new dependencies list format
32+
String updatedContent = Files.readString(appYmlPath);
33+
assertThat(updatedContent).doesNotContain("com.example:test-lib: \"1.0.0\"");
34+
assertThat(updatedContent).contains("- com.example:test-lib:1.0.0");
35+
}
36+
}

src/test/java/org/codejive/jpm/config/AppInfoTest.java

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void testReadAppInfoWithActions() throws IOException {
2020
Path appYmlPath = tempDir.resolve("app.yml");
2121
String yamlContent =
2222
"dependencies:\n"
23-
+ " com.example:test-lib: \"1.0.0\"\n"
23+
+ " - com.example:test-lib:1.0.0\n"
2424
+ "\n"
2525
+ "actions:\n"
2626
+ " build: \"javac -cp {{deps}} *.java\"\n"
@@ -51,8 +51,8 @@ void testReadAppInfoWithActions() throws IOException {
5151
assertThat(appInfo.getAction("nonexistent")).isNull();
5252

5353
// Test dependencies are still parsed correctly
54-
assertThat(appInfo.dependencies).hasSize(1);
55-
assertThat(appInfo.dependencies).containsEntry("com.example:test-lib", "1.0.0");
54+
assertThat(appInfo.dependencies()).hasSize(1);
55+
assertThat(appInfo.dependencies()).contains("com.example:test-lib:1.0.0");
5656
} finally {
5757
System.setProperty("user.dir", originalDir);
5858
}
@@ -62,7 +62,7 @@ void testReadAppInfoWithActions() throws IOException {
6262
void testReadAppInfoWithoutActions() throws IOException {
6363
// Create a test app.yml file without actions
6464
Path appYmlPath = tempDir.resolve("app.yml");
65-
String yamlContent = "dependencies:\n" + " com.example:test-lib: \"1.0.0\"\n";
65+
String yamlContent = "dependencies:\n" + " - com.example:test-lib:1.0.0\n";
6666
Files.writeString(appYmlPath, yamlContent);
6767

6868
String originalDir = System.getProperty("user.dir");
@@ -76,7 +76,7 @@ void testReadAppInfoWithoutActions() throws IOException {
7676
assertThat(appInfo.getAction("build")).isNull();
7777

7878
// Test dependencies are still parsed correctly
79-
assertThat(appInfo.dependencies).hasSize(1);
79+
assertThat(appInfo.dependencies()).hasSize(1);
8080
} finally {
8181
System.setProperty("user.dir", originalDir);
8282
}
@@ -93,7 +93,7 @@ void testReadEmptyAppInfo() throws IOException {
9393

9494
// Test no actions and no dependencies
9595
assertThat(appInfo.getActionNames()).isEmpty();
96-
assertThat(appInfo.dependencies).isEmpty();
96+
assertThat(appInfo.dependencies()).isEmpty();
9797
assertThat(appInfo.getAction("build")).isNull();
9898
} finally {
9999
System.setProperty("user.dir", originalDir);
@@ -103,9 +103,9 @@ void testReadEmptyAppInfo() throws IOException {
103103
@Test
104104
void testWriteAppInfoWithActions() throws IOException {
105105
AppInfo appInfo = new AppInfo();
106-
appInfo.dependencies.put("com.example:test-lib", "1.0.0");
107-
appInfo.actions.put("build", "javac -cp {{deps}} *.java");
108-
appInfo.actions.put("test", "java -cp {{deps}} TestRunner");
106+
appInfo.dependencies().add("com.example:test-lib:1.0.0");
107+
appInfo.actions().put("build", "javac -cp {{deps}} *.java");
108+
appInfo.actions().put("test", "java -cp {{deps}} TestRunner");
109109

110110
String originalDir = System.getProperty("user.dir");
111111
System.setProperty("user.dir", tempDir.toString());
@@ -122,7 +122,7 @@ void testWriteAppInfoWithActions() throws IOException {
122122
assertThat(readBack.getAction("build")).isEqualTo("javac -cp {{deps}} *.java");
123123
assertThat(readBack.getAction("test")).isEqualTo("java -cp {{deps}} TestRunner");
124124
assertThat(readBack.getActionNames()).hasSize(2);
125-
assertThat(readBack.dependencies).hasSize(1);
125+
assertThat(readBack.dependencies()).hasSize(1);
126126
} finally {
127127
System.setProperty("user.dir", originalDir);
128128
}
@@ -133,7 +133,7 @@ void testAppInfoWithComplexActions() throws IOException {
133133
Path appYmlPath = tempDir.resolve("app.yml");
134134
String yamlContent =
135135
"dependencies:\n"
136-
+ " com.example:test-lib: \"1.0.0\"\n"
136+
+ " - com.example:test-lib:1.0.0\n"
137137
+ "\n"
138138
+ "actions:\n"
139139
+ " complex: \"java -cp {{deps}} -Dprop=value MainClass arg1 arg2\"\n"
@@ -166,7 +166,7 @@ void testReadAppInfoWithRepositories() throws IOException {
166166
Path appYmlPath = tempDir.resolve("app.yml");
167167
String yamlContent =
168168
"dependencies:\n"
169-
+ " com.example:test-lib: \"1.0.0\"\n"
169+
+ " - com.example:test-lib:1.0.0\n"
170170
+ "\n"
171171
+ "repositories:\n"
172172
+ " central: \"https://repo1.maven.org/maven2\"\n"
@@ -181,15 +181,15 @@ void testReadAppInfoWithRepositories() throws IOException {
181181
AppInfo appInfo = AppInfo.read();
182182

183183
// Test repository retrieval
184-
assertThat(appInfo.repositories).hasSize(3);
185-
assertThat(appInfo.repositories)
184+
assertThat(appInfo.repositories()).hasSize(3);
185+
assertThat(appInfo.repositories())
186186
.containsEntry("central", "https://repo1.maven.org/maven2")
187187
.containsEntry("jcenter", "https://jcenter.bintray.com")
188188
.containsEntry("custom", "https://my.custom.repo/maven2");
189189

190190
// Test dependencies are still parsed correctly
191-
assertThat(appInfo.dependencies).hasSize(1);
192-
assertThat(appInfo.dependencies).containsEntry("com.example:test-lib", "1.0.0");
191+
assertThat(appInfo.dependencies()).hasSize(1);
192+
assertThat(appInfo.dependencies()).contains("com.example:test-lib:1.0.0");
193193
} finally {
194194
System.setProperty("user.dir", originalDir);
195195
}
@@ -199,7 +199,7 @@ void testReadAppInfoWithRepositories() throws IOException {
199199
void testReadAppInfoWithoutRepositories() throws IOException {
200200
// Create a test app.yml file without repositories
201201
Path appYmlPath = tempDir.resolve("app.yml");
202-
String yamlContent = "dependencies:\n" + " com.example:test-lib: \"1.0.0\"\n";
202+
String yamlContent = "dependencies:\n" + " - com.example:test-lib:1.0.0\n";
203203
Files.writeString(appYmlPath, yamlContent);
204204

205205
String originalDir = System.getProperty("user.dir");
@@ -209,10 +209,10 @@ void testReadAppInfoWithoutRepositories() throws IOException {
209209
AppInfo appInfo = AppInfo.read();
210210

211211
// Test no repositories
212-
assertThat(appInfo.repositories).isEmpty();
212+
assertThat(appInfo.repositories()).isEmpty();
213213

214214
// Test dependencies are still parsed correctly
215-
assertThat(appInfo.dependencies).hasSize(1);
215+
assertThat(appInfo.dependencies()).hasSize(1);
216216
} finally {
217217
System.setProperty("user.dir", originalDir);
218218
}
@@ -221,9 +221,9 @@ void testReadAppInfoWithoutRepositories() throws IOException {
221221
@Test
222222
void testWriteAppInfoWithRepositories() throws IOException {
223223
AppInfo appInfo = new AppInfo();
224-
appInfo.dependencies.put("com.example:test-lib", "1.0.0");
225-
appInfo.repositories.put("central", "https://repo1.maven.org/maven2");
226-
appInfo.repositories.put("custom", "https://my.custom.repo/maven2");
224+
appInfo.dependencies().add("com.example:test-lib:1.0.0");
225+
appInfo.repositories().put("central", "https://repo1.maven.org/maven2");
226+
appInfo.repositories().put("custom", "https://my.custom.repo/maven2");
227227

228228
String originalDir = System.getProperty("user.dir");
229229
System.setProperty("user.dir", tempDir.toString());
@@ -237,11 +237,11 @@ void testWriteAppInfoWithRepositories() throws IOException {
237237

238238
// Read it back and verify
239239
AppInfo readBack = AppInfo.read();
240-
assertThat(readBack.repositories).hasSize(2);
241-
assertThat(readBack.repositories)
240+
assertThat(readBack.repositories()).hasSize(2);
241+
assertThat(readBack.repositories())
242242
.containsEntry("central", "https://repo1.maven.org/maven2")
243243
.containsEntry("custom", "https://my.custom.repo/maven2");
244-
assertThat(readBack.dependencies).hasSize(1);
244+
assertThat(readBack.dependencies()).hasSize(1);
245245
} finally {
246246
System.setProperty("user.dir", originalDir);
247247
}
@@ -250,7 +250,7 @@ void testWriteAppInfoWithRepositories() throws IOException {
250250
@Test
251251
void testWriteAppInfoWithoutRepositories() throws IOException {
252252
AppInfo appInfo = new AppInfo();
253-
appInfo.dependencies.put("com.example:test-lib", "1.0.0");
253+
appInfo.dependencies().add("com.example:test-lib:1.0.0");
254254
// No repositories added
255255

256256
String originalDir = System.getProperty("user.dir");
@@ -261,8 +261,8 @@ void testWriteAppInfoWithoutRepositories() throws IOException {
261261

262262
// Read it back and verify repositories section is not present
263263
AppInfo readBack = AppInfo.read();
264-
assertThat(readBack.repositories).isEmpty();
265-
assertThat(readBack.dependencies).hasSize(1);
264+
assertThat(readBack.repositories()).isEmpty();
265+
assertThat(readBack.dependencies()).hasSize(1);
266266

267267
// Also verify the YAML content doesn't contain repositories section
268268
String content = Files.readString(tempDir.resolve("app.yml"));
@@ -277,7 +277,7 @@ void testAppInfoWithComplexRepositoriesAndActions() throws IOException {
277277
Path appYmlPath = tempDir.resolve("app.yml");
278278
String yamlContent =
279279
"dependencies:\n"
280-
+ " com.example:test-lib: \"1.0.0\"\n"
280+
+ " - com.example:test-lib:1.0.0\n"
281281
+ "\n"
282282
+ "repositories:\n"
283283
+ " central: \"https://repo1.maven.org/maven2\"\n"
@@ -294,11 +294,11 @@ void testAppInfoWithComplexRepositoriesAndActions() throws IOException {
294294
AppInfo appInfo = AppInfo.read();
295295

296296
// Test all sections are parsed correctly
297-
assertThat(appInfo.dependencies).hasSize(1);
298-
assertThat(appInfo.repositories).hasSize(2);
297+
assertThat(appInfo.dependencies()).hasSize(1);
298+
assertThat(appInfo.repositories()).hasSize(2);
299299
assertThat(appInfo.getActionNames()).hasSize(1);
300300

301-
assertThat(appInfo.repositories)
301+
assertThat(appInfo.repositories())
302302
.containsEntry("central", "https://repo1.maven.org/maven2")
303303
.containsEntry(
304304
"sonatype-snapshots",

0 commit comments

Comments
 (0)