1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin;
20
21 import javax.inject.Inject;
22
23 import java.io.File;
24 import java.net.URI;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Objects;
32 import java.util.Properties;
33
34 import org.apache.maven.AbstractCoreMavenComponentTestCase;
35 import org.apache.maven.artifact.Artifact;
36 import org.apache.maven.artifact.ArtifactUtils;
37 import org.apache.maven.artifact.repository.ArtifactRepository;
38 import org.apache.maven.bridge.MavenRepositorySystem;
39 import org.apache.maven.configuration.internal.EnhancedComponentConfigurator;
40 import org.apache.maven.execution.DefaultMavenExecutionRequest;
41 import org.apache.maven.execution.DefaultMavenExecutionResult;
42 import org.apache.maven.execution.MavenExecutionRequest;
43 import org.apache.maven.execution.MavenSession;
44 import org.apache.maven.model.Build;
45 import org.apache.maven.model.Dependency;
46 import org.apache.maven.model.Model;
47 import org.apache.maven.model.building.DefaultModelBuildingRequest;
48 import org.apache.maven.model.interpolation.reflection.IntrospectionException;
49 import org.apache.maven.model.root.RootLocator;
50 import org.apache.maven.plugin.descriptor.MojoDescriptor;
51 import org.apache.maven.plugin.descriptor.PluginDescriptor;
52 import org.apache.maven.project.CycleDetectedException;
53 import org.apache.maven.project.DuplicateProjectException;
54 import org.apache.maven.project.MavenProject;
55 import org.codehaus.plexus.MutablePlexusContainer;
56 import org.codehaus.plexus.PlexusContainer;
57 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
58 import org.codehaus.plexus.configuration.DefaultPlexusConfiguration;
59 import org.codehaus.plexus.util.Os;
60 import org.junit.jupiter.api.Test;
61
62 import static org.codehaus.plexus.testing.PlexusExtension.getTestFile;
63 import static org.junit.jupiter.api.Assertions.assertEquals;
64 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
65 import static org.junit.jupiter.api.Assertions.assertNotNull;
66 import static org.junit.jupiter.api.Assertions.assertNull;
67 import static org.junit.jupiter.api.Assertions.assertSame;
68 import static org.junit.jupiter.api.Assertions.assertThrows;
69 import static org.junit.jupiter.api.Assertions.assertTrue;
70
71
72
73 class PluginParameterExpressionEvaluatorTest extends AbstractCoreMavenComponentTestCase {
74 private static final String FS = File.separator;
75
76 @Inject
77 private MavenRepositorySystem factory;
78
79 private Path rootDirectory;
80
81 @Test
82 void testPluginDescriptorExpressionReference() throws Exception {
83 MojoExecution exec = newMojoExecution();
84
85 MavenSession session = newMavenSession();
86
87 Object result = new PluginParameterExpressionEvaluator(session, exec).evaluate("${plugin}");
88
89 System.out.println("Result: " + result);
90
91 assertSame(
92 exec.getMojoDescriptor().getPluginDescriptor(),
93 result,
94 "${plugin} expression does not return plugin descriptor.");
95 }
96
97 @Test
98 void testPluginArtifactsExpressionReference() throws Exception {
99 MojoExecution exec = newMojoExecution();
100
101 Artifact depArtifact = createArtifact("group", "artifact", "1");
102
103 List<Artifact> deps = new ArrayList<>();
104 deps.add(depArtifact);
105
106 exec.getMojoDescriptor().getPluginDescriptor().setArtifacts(deps);
107
108 MavenSession session = newMavenSession();
109
110 @SuppressWarnings("unchecked")
111 List<Artifact> depResults =
112 (List<Artifact>) new PluginParameterExpressionEvaluator(session, exec).evaluate("${plugin.artifacts}");
113
114 System.out.println("Result: " + depResults);
115
116 assertNotNull(depResults);
117 assertEquals(1, depResults.size());
118 assertSame(depArtifact, depResults.get(0), "dependency artifact is wrong.");
119 }
120
121 @Test
122 void testPluginArtifactMapExpressionReference() throws Exception {
123 MojoExecution exec = newMojoExecution();
124
125 Artifact depArtifact = createArtifact("group", "artifact", "1");
126
127 List<Artifact> deps = new ArrayList<>();
128 deps.add(depArtifact);
129
130 exec.getMojoDescriptor().getPluginDescriptor().setArtifacts(deps);
131
132 MavenSession session = newMavenSession();
133
134 @SuppressWarnings("unchecked")
135 Map<String, Artifact> depResults = (Map<String, Artifact>)
136 new PluginParameterExpressionEvaluator(session, exec).evaluate("${plugin.artifactMap}");
137
138 System.out.println("Result: " + depResults);
139
140 assertNotNull(depResults);
141 assertEquals(1, depResults.size());
142 assertSame(
143 depArtifact,
144 depResults.get(ArtifactUtils.versionlessKey(depArtifact)),
145 "dependency artifact is wrong.");
146 }
147
148 @Test
149 void testPluginArtifactIdExpressionReference() throws Exception {
150 MojoExecution exec = newMojoExecution();
151
152 MavenSession session = newMavenSession();
153
154 Object result = new PluginParameterExpressionEvaluator(session, exec).evaluate("${plugin.artifactId}");
155
156 System.out.println("Result: " + result);
157
158 assertSame(
159 exec.getMojoDescriptor().getPluginDescriptor().getArtifactId(),
160 result,
161 "${plugin.artifactId} expression does not return plugin descriptor's artifactId.");
162 }
163
164 @Test
165 void testValueExtractionWithAPomValueContainingAPath() throws Exception {
166 String expected = getTestFile("target/test-classes/target/classes").getCanonicalPath();
167
168 Build build = new Build();
169 build.setDirectory(expected.substring(0, expected.length() - "/classes".length()));
170
171 Model model = new Model();
172 model.setBuild(build);
173
174 MavenProject project = new MavenProject(model);
175 project.setFile(new File("pom.xml").getCanonicalFile());
176
177 ExpressionEvaluator expressionEvaluator = createExpressionEvaluator(project, null, new Properties());
178
179 Object value = expressionEvaluator.evaluate("${project.build.directory}/classes");
180 String actual = new File(value.toString()).getCanonicalPath();
181
182 assertEquals(expected, actual);
183 }
184
185 @Test
186 void testEscapedVariablePassthrough() throws Exception {
187 String var = "${var}";
188
189 Model model = new Model();
190 model.setVersion("1");
191
192 MavenProject project = new MavenProject(model);
193
194 ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
195
196 Object value = ee.evaluate("$" + var);
197
198 assertEquals(var, value);
199 }
200
201 @Test
202 void testEscapedVariablePassthroughInLargerExpression() throws Exception {
203 String var = "${var}";
204 String key = var + " with version: ${project.version}";
205
206 Model model = new Model();
207 model.setVersion("1");
208
209 MavenProject project = new MavenProject(model);
210
211 ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
212
213 Object value = ee.evaluate("$" + key);
214
215 assertEquals("${var} with version: 1", value);
216 }
217
218 @Test
219 void testMultipleSubExpressionsInLargerExpression() throws Exception {
220 String key = "${project.artifactId} with version: ${project.version}";
221
222 Model model = new Model();
223 model.setArtifactId("test");
224 model.setVersion("1");
225
226 MavenProject project = new MavenProject(model);
227
228 ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
229
230 Object value = ee.evaluate(key);
231
232 assertEquals("test with version: 1", value);
233 }
234
235 @Test
236 void testMissingPOMPropertyRefInLargerExpression() throws Exception {
237 String expr = "/path/to/someproject-${baseVersion}";
238
239 MavenProject project = new MavenProject(new Model());
240
241 ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
242
243 Object value = ee.evaluate(expr);
244
245 assertEquals(expr, value);
246 }
247
248 @Test
249 void testPOMPropertyExtractionWithMissingProject_WithDotNotation() throws Exception {
250 String key = "m2.name";
251 String checkValue = "value";
252
253 Properties properties = new Properties();
254 properties.setProperty(key, checkValue);
255
256 Model model = new Model();
257 model.setProperties(properties);
258
259 MavenProject project = new MavenProject(model);
260
261 ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
262
263 Object value = ee.evaluate("${" + key + "}");
264
265 assertEquals(checkValue, value);
266 }
267
268 @Test
269 void testBasedirExtractionWithMissingProject() throws Exception {
270 ExpressionEvaluator ee = createExpressionEvaluator(null, null, new Properties());
271
272 Object value = ee.evaluate("${basedir}");
273
274 assertEquals(System.getProperty("user.dir"), value);
275 }
276
277 @Test
278 void testValueExtractionFromSystemPropertiesWithMissingProject() throws Exception {
279 String sysprop = "PPEET_sysprop1";
280
281 Properties executionProperties = new Properties();
282
283 if (executionProperties.getProperty(sysprop) == null) {
284 executionProperties.setProperty(sysprop, "value");
285 }
286
287 ExpressionEvaluator ee = createExpressionEvaluator(null, null, executionProperties);
288
289 Object value = ee.evaluate("${" + sysprop + "}");
290
291 assertEquals("value", value);
292 }
293
294 @Test
295 void testValueExtractionFromSystemPropertiesWithMissingProject_WithDotNotation() throws Exception {
296 String sysprop = "PPEET.sysprop2";
297
298 Properties executionProperties = new Properties();
299
300 if (executionProperties.getProperty(sysprop) == null) {
301 executionProperties.setProperty(sysprop, "value");
302 }
303
304 ExpressionEvaluator ee = createExpressionEvaluator(null, null, executionProperties);
305
306 Object value = ee.evaluate("${" + sysprop + "}");
307
308 assertEquals("value", value);
309 }
310
311 @SuppressWarnings("deprecation")
312 private static MavenSession createSession(PlexusContainer container, ArtifactRepository repo, Properties properties)
313 throws CycleDetectedException, DuplicateProjectException {
314 MavenExecutionRequest request = new DefaultMavenExecutionRequest()
315 .setSystemProperties(properties)
316 .setGoals(Collections.<String>emptyList())
317 .setBaseDirectory(new File(""))
318 .setLocalRepository(repo);
319
320 return new MavenSession(
321 container, request, new DefaultMavenExecutionResult(), Collections.<MavenProject>emptyList());
322 }
323
324 @Test
325 void testLocalRepositoryExtraction() throws Exception {
326 ExpressionEvaluator expressionEvaluator =
327 createExpressionEvaluator(createDefaultProject(), null, new Properties());
328 Object value = expressionEvaluator.evaluate("${localRepository}");
329
330 assertEquals("local", ((ArtifactRepository) value).getId());
331 }
332
333 @Test
334 void testTwoExpressions() throws Exception {
335 Build build = new Build();
336 build.setDirectory("expected-directory");
337 build.setFinalName("expected-finalName");
338
339 Model model = new Model();
340 model.setBuild(build);
341
342 ExpressionEvaluator expressionEvaluator =
343 createExpressionEvaluator(new MavenProject(model), null, new Properties());
344
345 Object value = expressionEvaluator.evaluate("${project.build.directory}" + FS + "${project.build.finalName}");
346
347 assertEquals("expected-directory" + File.separatorChar + "expected-finalName", value);
348 }
349
350 @Test
351 void testShouldExtractPluginArtifacts() throws Exception {
352 PluginDescriptor pd = new PluginDescriptor();
353
354 Artifact artifact = createArtifact("testGroup", "testArtifact", "1.0");
355
356 pd.setArtifacts(Collections.singletonList(artifact));
357
358 ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), pd, new Properties());
359
360 Object value = ee.evaluate("${plugin.artifacts}");
361
362 assertTrue(value instanceof List);
363
364 @SuppressWarnings("unchecked")
365 List<Artifact> artifacts = (List<Artifact>) value;
366
367 assertEquals(1, artifacts.size());
368
369 Artifact result = artifacts.get(0);
370
371 assertEquals("testGroup", result.getGroupId());
372 }
373
374 @Test
375 void testRootDirectoryNotPrefixed() throws Exception {
376 ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), null, new Properties());
377 assertNull(ee.evaluate("${rootDirectory}"));
378 }
379
380 @Test
381 void testRootDirectoryWithNull() throws Exception {
382 ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), null, new Properties());
383 Exception e = assertThrows(Exception.class, () -> ee.evaluate("${session.rootDirectory}"));
384 e = assertInstanceOf(IntrospectionException.class, e.getCause());
385 e = assertInstanceOf(IllegalStateException.class, e.getCause());
386 assertEquals(RootLocator.UNABLE_TO_FIND_ROOT_PROJECT_MESSAGE, e.getMessage());
387 }
388
389 @Test
390 void testRootDirectory() throws Exception {
391 this.rootDirectory = Paths.get("myRootDirectory");
392 ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), null, new Properties());
393 assertInstanceOf(Path.class, ee.evaluate("${session.rootDirectory}"));
394 }
395
396 @Test
397 public void testUri() throws Exception {
398 Path path = Paths.get("").toAbsolutePath();
399
400 MavenSession mavenSession = createMavenSession(null);
401 mavenSession.getRequest().setTopDirectory(path);
402 mavenSession.getRequest().setRootDirectory(path);
403
404 Object result = new PluginParameterExpressionEvaluator(mavenSession, new MojoExecution(null))
405 .evaluate("${session.rootDirectory.uri}");
406 assertEquals(path.toUri(), result);
407 }
408
409 @Test
410 public void testPath() throws Exception {
411 Path path = Paths.get("").toAbsolutePath();
412
413 MavenSession mavenSession = createMavenSession(null);
414 mavenSession.getRequest().setTopDirectory(path);
415 mavenSession.getRequest().setRootDirectory(path);
416
417 Object result = new PluginParameterExpressionEvaluator(mavenSession, new MojoExecution(null))
418 .evaluate("${session.rootDirectory/target}");
419 assertEquals(path.resolve("target"), result);
420 }
421
422 @Test
423 public void testPluginInjection() throws Exception {
424 Path path = Paths.get("rép➜α").toAbsolutePath();
425
426 MavenSession mavenSession = createMavenSession(null);
427 mavenSession.getRequest().setTopDirectory(path);
428 mavenSession.getRequest().setRootDirectory(path);
429 DefaultModelBuildingRequest mbr = new DefaultModelBuildingRequest();
430
431 PluginParameterExpressionEvaluator evaluator =
432 new PluginParameterExpressionEvaluator(mavenSession, new MojoExecution(null));
433
434 DefaultPlexusConfiguration configuration = new DefaultPlexusConfiguration("config");
435 configuration.addChild("uri", "${session.rootDirectory.uri}");
436 configuration.addChild("path", "${session.rootDirectory}");
437 configuration.addChild("uriString", "${session.rootDirectory.uri.string}");
438 configuration.addChild("uriAsciiString", "${session.rootDirectory.uri.ASCIIString}");
439 configuration.addChild("pathString", "${session.rootDirectory.string}");
440
441 Mojo mojo = new Mojo();
442 new EnhancedComponentConfigurator().configureComponent(mojo, configuration, evaluator, null);
443
444 assertEquals(
445 Objects.equals(path.toUri().toString(), path.toUri().toASCIIString()), !Os.isFamily(Os.FAMILY_WINDOWS));
446 assertEquals(mojo.uri, path.toUri());
447 assertEquals(mojo.path, path);
448 assertEquals(mojo.uriString, path.toUri().toString());
449 assertEquals(mojo.uriAsciiString, path.toUri().toASCIIString());
450 assertEquals(mojo.pathString, path.toString());
451 }
452
453 private MavenProject createDefaultProject() {
454 return new MavenProject(new Model());
455 }
456
457 private ExpressionEvaluator createExpressionEvaluator(
458 MavenProject project, PluginDescriptor pluginDescriptor, Properties executionProperties) throws Exception {
459 ArtifactRepository repo = getLocalRepository();
460
461 MutablePlexusContainer container = (MutablePlexusContainer) getContainer();
462 MavenSession session = createSession(container, repo, executionProperties);
463 session.setCurrentProject(project);
464 session.getRequest().setRootDirectory(rootDirectory);
465
466 MojoDescriptor mojo = new MojoDescriptor();
467 mojo.setPluginDescriptor(pluginDescriptor);
468 mojo.setGoal("goal");
469
470 MojoExecution mojoExecution = new MojoExecution(mojo);
471
472 return new PluginParameterExpressionEvaluator(session, mojoExecution);
473 }
474
475 protected Artifact createArtifact(String groupId, String artifactId, String version) throws Exception {
476 Dependency dependency = new Dependency();
477 dependency.setGroupId(groupId);
478 dependency.setArtifactId(artifactId);
479 dependency.setVersion(version);
480 dependency.setType("jar");
481 dependency.setScope("compile");
482
483 return factory.createDependencyArtifact(dependency);
484 }
485
486 private MojoExecution newMojoExecution() {
487 PluginDescriptor pd = new PluginDescriptor();
488 pd.setArtifactId("my-plugin");
489 pd.setGroupId("org.myco.plugins");
490 pd.setVersion("1");
491
492 MojoDescriptor md = new MojoDescriptor();
493 md.setPluginDescriptor(pd);
494
495 pd.addComponentDescriptor(md);
496
497 return new MojoExecution(md);
498 }
499
500 private MavenSession newMavenSession() throws Exception {
501 return createMavenSession(null);
502 }
503
504 @Override
505 protected String getProjectsDirectory() {
506
507 return null;
508 }
509
510 public static class Mojo {
511 URI uri;
512 Path path;
513 String uriString;
514 String uriAsciiString;
515 String pathString;
516 }
517 }