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