1 package com.soebes.maven.extensions.incremental;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.nio.file.Path;
23 import java.util.List;
24 import java.util.concurrent.ExecutionException;
25
26 import javax.inject.Inject;
27 import javax.inject.Named;
28 import javax.inject.Singleton;
29
30 import org.apache.commons.lang.StringUtils;
31 import org.apache.maven.execution.MavenSession;
32 import org.apache.maven.lifecycle.internal.LifecycleModuleBuilder;
33 import org.apache.maven.lifecycle.internal.ProjectBuildList;
34 import org.apache.maven.lifecycle.internal.ReactorBuildStatus;
35 import org.apache.maven.lifecycle.internal.ReactorContext;
36 import org.apache.maven.lifecycle.internal.TaskSegment;
37 import org.apache.maven.lifecycle.internal.builder.Builder;
38 import org.apache.maven.project.MavenProject;
39 import org.apache.maven.scm.ScmException;
40 import org.apache.maven.scm.ScmFile;
41 import org.apache.maven.scm.ScmFileSet;
42 import org.apache.maven.scm.command.status.StatusScmResult;
43 import org.apache.maven.scm.manager.NoSuchScmProviderException;
44 import org.apache.maven.scm.manager.ScmManager;
45 import org.apache.maven.scm.repository.ScmRepository;
46 import org.apache.maven.scm.repository.ScmRepositoryException;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50
51
52
53
54
55 @Singleton
56 @Named( "incremental" )
57 public class IncrementalModuleBuilder
58 implements Builder
59 {
60 private final Logger LOGGER = LoggerFactory.getLogger( getClass() );
61
62 private final LifecycleModuleBuilder lifecycleModuleBuilder;
63
64 @Inject
65 private ScmManager scmManager;
66
67 @Inject
68 public IncrementalModuleBuilder( LifecycleModuleBuilder lifecycleModuleBuilder )
69 {
70 LOGGER.info( " ------------------------------------" );
71 LOGGER.info( " Maven Incremental Module Builder" );
72 LOGGER.info( " Version: {}", IncrementalModuleBuilderVersion.getVersion() );
73 LOGGER.debug( " SHA: {}", IncrementalModuleBuilderVersion.getRevision() );
74 LOGGER.info( " ------------------------------------" );
75 this.lifecycleModuleBuilder = lifecycleModuleBuilder;
76 }
77
78 private boolean havingScmDeveloperConnection( MavenSession session )
79 {
80 if ( session.getTopLevelProject().getScm() == null )
81 {
82 LOGGER.error( "The incremental module builder needs a correct scm configuration." );
83 return false;
84 }
85
86 if ( StringUtils.isEmpty( session.getTopLevelProject().getScm().getDeveloperConnection() ) )
87 {
88 LOGGER.error( "The incremental module builder needs the scm developerConnection to work properly." );
89 return false;
90 }
91
92 return true;
93 }
94
95 @Override
96 public void build( final MavenSession session, final ReactorContext reactorContext, ProjectBuildList projectBuilds,
97 final List<TaskSegment> taskSegments, ReactorBuildStatus reactorBuildStatus )
98 throws ExecutionException, InterruptedException
99 {
100
101
102 if ( !session.getCurrentProject().isExecutionRoot() )
103 {
104 LOGGER.info( "Not executing in root." );
105 }
106
107 Path projectRootpath = session.getTopLevelProject().getBasedir().toPath();
108
109 if ( !havingScmDeveloperConnection( session ) )
110 {
111 LOGGER.warn( "There is no scm developer connection configured." );
112 LOGGER.warn( "So we can't estimate which modules have changed." );
113 return;
114 }
115
116
117
118 ScmRepository repository = null;
119 try
120 {
121
122 repository = scmManager.makeScmRepository( session.getTopLevelProject().getScm().getDeveloperConnection() );
123 }
124 catch ( ScmRepositoryException | NoSuchScmProviderException e )
125 {
126 LOGGER.error( "Failure during makeScmRepository", e );
127 return;
128 }
129
130 StatusScmResult result = null;
131 try
132 {
133 result = scmManager.status( repository, new ScmFileSet( session.getTopLevelProject().getBasedir() ) );
134 }
135 catch ( ScmException e )
136 {
137 LOGGER.error( "Failure during status", e );
138 return;
139 }
140
141 List<ScmFile> changedFiles = result.getChangedFiles();
142 if ( changedFiles.isEmpty() )
143 {
144 LOGGER.info( " Nothing has been changed." );
145 }
146 else
147 {
148
149 for ( ScmFile scmFile : changedFiles )
150 {
151 LOGGER.info( " Changed file: " + scmFile.getPath() + " " + scmFile.getStatus() );
152 }
153
154 ModuleCalculator mc =
155 new ModuleCalculator( session.getProjectDependencyGraph().getSortedProjects(), changedFiles );
156 List<MavenProject> calculateChangedModules = mc.calculateChangedModules( projectRootpath );
157
158 for ( MavenProject mavenProject : calculateChangedModules )
159 {
160 LOGGER.info( "Changed Project: " + mavenProject.getId() );
161 }
162
163 IncrementalModuleBuilderImpl incrementalModuleBuilderImpl =
164 new IncrementalModuleBuilderImpl( calculateChangedModules, lifecycleModuleBuilder, session,
165 reactorContext, taskSegments );
166
167
168 incrementalModuleBuilderImpl.build();
169 }
170 }
171
172 }