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