Skip to content

Commit 88a03f8

Browse files
gnodetmichael-o
authored andcommitted
[MNG-7486] Create a multiline message helper for boxed log messages
This closes #746
1 parent 23cc863 commit 88a03f8

3 files changed

Lines changed: 179 additions & 15 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package org.apache.maven.internal;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
import java.util.ArrayList;
23+
import java.util.List;
24+
25+
/**
26+
* Helper class to format multiline messages to the console
27+
*/
28+
public class MultilineMessageHelper
29+
{
30+
31+
private static final int DEFAULT_MAX_SIZE = 65;
32+
private static final char BOX_CHAR = '*';
33+
34+
public static String separatorLine()
35+
{
36+
StringBuilder sb = new StringBuilder( DEFAULT_MAX_SIZE );
37+
repeat( sb, '*', DEFAULT_MAX_SIZE );
38+
return sb.toString();
39+
}
40+
41+
public static List<String> format( String... lines )
42+
{
43+
int size = DEFAULT_MAX_SIZE;
44+
int remainder = size - 4; // 4 chars = 2 box_char + 2 spaces
45+
List<String> result = new ArrayList<>();
46+
StringBuilder sb = new StringBuilder( size );
47+
// first line
48+
sb.setLength( 0 );
49+
repeat( sb, BOX_CHAR, size );
50+
result.add( sb.toString() );
51+
// lines
52+
for ( String line : lines )
53+
{
54+
sb.setLength( 0 );
55+
String[] words = line.split( "\\s+" );
56+
for ( String word : words )
57+
{
58+
if ( sb.length() >= remainder - word.length() - ( sb.length() > 0 ? 1 : 0 ) )
59+
{
60+
repeat( sb, ' ', remainder - sb.length() );
61+
result.add( BOX_CHAR + " " + sb + " " + BOX_CHAR );
62+
sb.setLength( 0 );
63+
}
64+
if ( sb.length() > 0 )
65+
{
66+
sb.append( ' ' );
67+
}
68+
sb.append( word );
69+
}
70+
71+
while ( sb.length() < remainder )
72+
{
73+
sb.append( ' ' );
74+
}
75+
result.add( BOX_CHAR + " " + sb + " " + BOX_CHAR );
76+
}
77+
// last line
78+
sb.setLength( 0 );
79+
repeat( sb, BOX_CHAR, size );
80+
result.add( sb.toString() );
81+
return result;
82+
}
83+
84+
private static void repeat( StringBuilder sb, char c, int nb )
85+
{
86+
for ( int i = 0; i < nb; i++ )
87+
{
88+
sb.append( c );
89+
}
90+
}
91+
}

maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.maven.execution.ExecutionEvent;
2525
import org.apache.maven.execution.MavenExecutionRequest;
2626
import org.apache.maven.execution.MavenSession;
27+
import org.apache.maven.internal.MultilineMessageHelper;
2728
import org.apache.maven.lifecycle.LifecycleExecutionException;
2829
import org.apache.maven.lifecycle.LifecycleNotFoundException;
2930
import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
@@ -103,34 +104,35 @@ public MavenExecutionPlan resolveBuildPlan( MavenSession session, MavenProject p
103104
final Set<Plugin> unsafePlugins = executionPlan.getNonThreadSafePlugins();
104105
if ( !unsafePlugins.isEmpty() )
105106
{
106-
logger.warn( "*****************************************************************" );
107-
logger.warn( "* Your build is requesting parallel execution, but project *" );
108-
logger.warn( "* contains the following plugin(s) that have goals not marked *" );
109-
logger.warn( "* as @threadSafe to support parallel building. *" );
110-
logger.warn( "* While this /may/ work fine, please look for plugin updates *" );
111-
logger.warn( "* and/or request plugins be made thread-safe. *" );
112-
logger.warn( "* If reporting an issue, report it against the plugin in *" );
113-
logger.warn( "* question, not against maven-core *" );
114-
logger.warn( "*****************************************************************" );
107+
for ( String s : MultilineMessageHelper.format(
108+
"Your build is requesting parallel execution, but this project contains the following "
109+
+ "plugin(s) that have goals not marked as thread-safe to support parallel execution.",
110+
"While this /may/ work fine, please look for plugin updates and/or "
111+
+ "request plugins be made thread-safe.",
112+
"If reporting an issue, report it against the plugin in question, not against Apache Maven." ) )
113+
{
114+
logger.warn( s );
115+
}
115116
if ( logger.isDebugEnabled() )
116117
{
117118
final Set<MojoDescriptor> unsafeGoals = executionPlan.getNonThreadSafeMojos();
118-
logger.warn( "The following goals are not marked @threadSafe in " + project.getName() + ":" );
119+
logger.warn( "The following goals are not marked as thread-safe in " + project.getName() + ":" );
119120
for ( MojoDescriptor unsafeGoal : unsafeGoals )
120121
{
121-
logger.warn( unsafeGoal.getId() );
122+
logger.warn( " " + unsafeGoal.getId() );
122123
}
123124
}
124125
else
125126
{
126-
logger.warn( "The following plugins are not marked @threadSafe in " + project.getName() + ":" );
127+
logger.warn( "The following plugins are not marked as thread-safe in " + project.getName() + ":" );
127128
for ( Plugin unsafePlugin : unsafePlugins )
128129
{
129-
logger.warn( unsafePlugin.getId() );
130+
logger.warn( " " + unsafePlugin.getId() );
130131
}
131-
logger.warn( "Enable debug to see more precisely which goals are not marked @threadSafe." );
132+
logger.warn( "" );
133+
logger.warn( "Enable debug to see precisely which goals are not marked as thread-safe." );
132134
}
133-
logger.warn( "*****************************************************************" );
135+
logger.warn( MultilineMessageHelper.separatorLine() );
134136
}
135137
}
136138

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package org.apache.maven.internal;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
import java.util.ArrayList;
23+
import java.util.List;
24+
25+
import org.junit.Test;
26+
27+
import static org.junit.Assert.assertEquals;
28+
29+
public class MultilineMessageHelperTest
30+
{
31+
32+
@Test
33+
public void testBuilderCommon()
34+
{
35+
List<String> msgs = new ArrayList<>();
36+
msgs.add( "*****************************************************************" );
37+
msgs.add( "* Your build is requesting parallel execution, but project *" );
38+
msgs.add( "* contains the following plugin(s) that have goals not marked *" );
39+
msgs.add( "* as @threadSafe to support parallel building. *" );
40+
msgs.add( "* While this /may/ work fine, please look for plugin updates *" );
41+
msgs.add( "* and/or request plugins be made thread-safe. *" );
42+
msgs.add( "* If reporting an issue, report it against the plugin in *" );
43+
msgs.add( "* question, not against maven-core *" );
44+
msgs.add( "*****************************************************************" );
45+
46+
assertEquals( msgs, MultilineMessageHelper.format(
47+
"Your build is requesting parallel execution, but project contains the following "
48+
+ "plugin(s) that have goals not marked as @threadSafe to support parallel building.",
49+
"While this /may/ work fine, please look for plugin updates and/or "
50+
+ "request plugins be made thread-safe.",
51+
"If reporting an issue, report it against the plugin in question, not against maven-core"
52+
) );
53+
}
54+
55+
@Test
56+
public void testMojoExecutor()
57+
{
58+
List<String> msgs = new ArrayList<>();
59+
msgs.add( "*****************************************************************" );
60+
msgs.add( "* An aggregator Mojo is already executing in parallel build, *" );
61+
msgs.add( "* but aggregator Mojos require exclusive access to reactor to *" );
62+
msgs.add( "* prevent race conditions. This mojo execution will be blocked *" );
63+
msgs.add( "* until the aggregator work is done. *" );
64+
msgs.add( "*****************************************************************" );
65+
66+
assertEquals( msgs, MultilineMessageHelper.format(
67+
"An aggregator Mojo is already executing in parallel build, but aggregator "
68+
+ "Mojos require exclusive access to reactor to prevent race conditions. This "
69+
+ "mojo execution will be blocked until the aggregator work is done." ) );
70+
}
71+
}

0 commit comments

Comments
 (0)