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