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