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