Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add regex for line comparison #243

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -538,14 +538,14 @@ In license-maven-plugin, each header style is defined by patterns to detect it a
<additionalHeaders>
<javadoc_style>
<firstLine>/**</firstLine>
<beforeEachLine> * </beforeEachLine>
<endLine> */</endLine>
<beforeEachLine xml:space="preserve"> * </beforeEachLine>
<endLine xml:space="preserve"> */</endLine>
<afterEachLine></afterEachLine>
<!--skipLine></skipLine-->
<firstLineDetectionPattern>(\s|\t)*/\*.*$</firstLineDetectionPattern>
<lastLineDetectionPattern>.*\*/(\s|\t)*$</lastLineDetectionPattern>
<allowBlankLines>false</allowBlankLines>
<isMultiline>true</isMultiline>
<multiline>true</multiline>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove any change regarding multiline: I've correctly fixed in #247

<padLines>false</padLines>
</javadoc_style>
</additionalHeaders>
Expand All @@ -558,14 +558,14 @@ And for XML:
<additionalHeaders>
<xml_style>
<firstLine><![CDATA[<!--\n]]></firstLine>
<beforeEachLine> </beforeEachLine>
<beforeEachLine xml:space="preserve"> </beforeEachLine>
<endLine><![CDATA[-->]]></endLine>
<afterEachLine></afterEachLine>
<skipLine><![CDATA[^<\?xml.*>$]]></skipLine>
<firstLineDetectionPattern><![CDATA[(\s|\t)*<!--.*$]]></firstLineDetectionPattern>
<lastLineDetectionPattern><![CDATA[.*-->(\s|\t)*$]]></lastLineDetectionPattern>
<allowBlankLines>false</allowBlankLines>
<isMultiline>true</isMultiline>
<multiline>true</multiline>
<padLines>false</padLines>
</xml_style>
</additionalHeaders>
Expand All @@ -582,20 +582,20 @@ This page will show you how you can define extended header definitions to fit yo
<additionalHeaders>
<csregion_style>
<firstLine>#region LicenseEOL/**</firstLine>
<beforeEachLine> * </beforeEachLine>
<endLine> */EOL#endregion</endLine>
<beforeEachLine xml:space="preserve"> * </beforeEachLine>
<endLine xml:space="preserve"> */EOL#endregion</endLine>
<firstLineDetectionPattern>#region.*^EOL/\*\*.*$</firstLineDetectionPattern>
<lastLineDetectionPattern>\*/EOL#endregion"</lastLineDetectionPattern>
<allowBlankLines>true</allowBlankLines>
<isMultiline>true</isMultiline>
<multiline>true</multiline>
</csregion_style>
</additionalHeaders>
```

* The `EOL` string will be replaced with the proper end of line depending the file format your are processing.
* We also have defined the _skipLine_ attribute to skip the region tags (which starts with a '#')
* `allowBlankLines` allows you to define if this header style supports blank lines in it or not. In example, in XML headers, you could have blank lines after the <!-- and before --> because XML delimiters delimit a multiline block. When you work with script style comments like in Ruby, Porperties files, the # character delimit a comment for only one line. So when you create the header, for it to be uniform, you place # on each line. So allowBlankLines will be false.
* `isMultiline` specifies if your header has tokens to delimit a multiline comment of if the tokens are a one-line comment. I.E.: XML style comments are multiline whereas script style comment where each line starts with # are not multiline
* `multiline` specifies if your header has tokens to delimit a multiline comment of if the tokens are a one-line comment. I.E.: XML style comments are multiline whereas script style comment where each line starts with # are not multiline

You now have to add this new header definition file to the plugin configuration. It is done as the following in your pom:

Expand Down Expand Up @@ -637,6 +637,8 @@ And it should generate headers like:

__Inline styles__

(since version 4.2)

This is also possible to configure new header style inline within the POM without using external files. This is a useful feature for module inheritance.

The following example will redefine the header file for text files:
Expand All @@ -653,7 +655,7 @@ The following example will redefine the header file for text files:
<defaultInlineHeaderStyle>
<name>SMILEY_STYLE</name>
<firstLine>:(</firstLine>
<beforeEachLine> ( </beforeEachLine>
<beforeEachLine xml:space="preserve"> ( </beforeEachLine>
<endLine>:(</endLine>
<firstLineDetectionPattern>\:\(</firstLineDetectionPattern>
<lastLineDetectionPattern>\:\(</lastLineDetectionPattern>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,19 @@ public class HeaderStyle {
@Parameter(required = true)
public String firstLineDetectionPattern;

/**
* The regex used to detect the other lines of a header section or line
*/
@Parameter(required = false)
public String otherLineDetectionPattern;

/**
* The regex used to detect the end of a header section or line
*/
@Parameter(required = true)
public String lastLineDetectionPattern;

public HeaderDefinition toHeaderDefinition() {
return new HeaderDefinition(name, firstLine, beforeEachLine, endLine, afterEachLine, skipLinePattern, firstLineDetectionPattern, lastLineDetectionPattern, allowBlankLines, multiline, padLines);
return new HeaderDefinition(name != null ? name.toLowerCase() : null, firstLine, beforeEachLine, endLine, afterEachLine, skipLinePattern, firstLineDetectionPattern, otherLineDetectionPattern, lastLineDetectionPattern, allowBlankLines, multiline, padLines);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import java.util.regex.Pattern;

import com.mycila.maven.plugin.license.util.StringUtils;

/**
* The <code>HeaderDefinition</code> class defines what is needed to output a header text into the of the given file
* type and what is needed to match the first line as well as the last line of a previous header of the given file
Expand All @@ -34,6 +36,7 @@ public final class HeaderDefinition {

private Pattern skipLinePattern;
private Pattern firstLineDetectionPattern;
private Pattern otherLineDetectionPattern;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer that the name is called middleLineDetectionPattern

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except it is for all lines except the first line - the last line must also pass this pattern (or the beforeEachLine test).
Finding the best name is often the most difficult task ;-)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the last line must also pass this pattern

Why ? There is a pattern for the last line.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the code still checks beforeEachLine. I didn't want to change the logic and the RegEx happens when the startsWith(beforeEachLine) check happens.

private Pattern lastLineDetectionPattern;
private Boolean isMultiline;

Expand Down Expand Up @@ -61,13 +64,40 @@ public HeaderDefinition(String type,
String skipLinePattern,
String firstLineDetectionPattern, String lastLineDetectionPattern,
boolean allowBlankLines, boolean isMultiline, boolean padLines) {
this(type, firstLine, beforeEachLine, endLine, afterEachLine, skipLinePattern, firstLineDetectionPattern, null, lastLineDetectionPattern, allowBlankLines, isMultiline, padLines);
}

/**
* Constructs a new <code>HeaderDefinition</code> object with every header definition properties.
*
* @param type The type name for this header definition.
* @param firstLine The string to output before the content of the first line of this header.
* @param beforeEachLine The string to output before the content of each line of this header (except
* firstLine and endLine).
* @param endLine The string to output before the content of the last line of this header.
* @param afterEachLine The string to output after the content of each line of this header (except
* firstLine and endLine).
* @param skipLinePattern The pattern of lines to skip before being allowed to output this header or null
* if it can be outputted from the line of the file.
* @param firstLineDetectionPattern The pattern to detect the first line of a previous header.
* @param otherLineDetectionPattern The pattern to detect any following line of a previous header.
* @param lastLineDetectionPattern The pattern to detect the last line of a previous header.
* @throws IllegalArgumentException If the type name is null.
*/
public HeaderDefinition(String type,
String firstLine, String beforeEachLine,
String endLine, String afterEachLine,
String skipLinePattern,
String firstLineDetectionPattern, String otherLineDetectionPattern, String lastLineDetectionPattern,
boolean allowBlankLines, boolean isMultiline, boolean padLines) {
this(type);
this.firstLine = firstLine;
this.beforeEachLine = beforeEachLine;
this.endLine = endLine;
this.afterEachLine = afterEachLine;
this.skipLinePattern = compile(skipLinePattern);
this.firstLineDetectionPattern = compile(firstLineDetectionPattern);
this.otherLineDetectionPattern = compile(otherLineDetectionPattern);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you would need to update setPropertyFromString(...) too for xml header definition.

this.lastLineDetectionPattern = compile(lastLineDetectionPattern);
this.allowBlankLines = allowBlankLines;
this.isMultiline = isMultiline;
Expand Down Expand Up @@ -141,12 +171,30 @@ public boolean isSkipLine(String line) {
* Tells if the given content line is the first line of a possible header of this definition kind.
*
* @param line The line to test.
* @return true if the first line of a header have been recognized or false.
* @return true if the first line of a header has been recognized or false.
*/
public boolean isFirstHeaderLine(String line) {
return firstLineDetectionPattern != null && line != null && firstLineDetectionPattern.matcher(line).matches();
}


/**
* Tells if the given content line is another than the first line of a possible header of this definition kind.
*
* @param line The line to test.
* @return true if another than the first line of a header has been recognized or false.
*/
public boolean isOtherHeaderLine(String line) {
if (line == null) {
return false;
} else if (otherLineDetectionPattern != null) {
return otherLineDetectionPattern.matcher(line).matches();
} else if ("".equals(StringUtils.rtrim(beforeEachLine)) && !isMultiLine()) {
return line.startsWith(beforeEachLine);
} else {
return line.startsWith(StringUtils.rtrim(beforeEachLine));
}
}

/**
* Tells if the given content line is the last line of a possible header of this definition kind.
*
Expand Down Expand Up @@ -209,6 +257,7 @@ public void validate() {
check("endLine", this.endLine);
check("afterEachLine", this.afterEachLine);
check("firstLineDetectionPattern", this.firstLineDetectionPattern);
// other line detection pattern can be null
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this comment: it's like beforeEachLine ;-)

check("lastLineDetectionPattern", this.lastLineDetectionPattern);
check("isMultiline", this.isMultiline);
check("allowBlankLines", this.allowBlankLines);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ private boolean hasHeader() {
foundEnd = true;

} else {
while ((line = fileContent.nextLine()) != null && line.startsWith(before)) {
while ((line = fileContent.nextLine()) != null && headerDefinition.isOtherHeaderLine(line)) {
inPlaceHeader.append(line.toLowerCase());
if (headerDefinition.isMultiLine() && headerDefinition.isLastHeaderLine(line)) {
foundEnd = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,33 @@ public void test_parsing_xml6() throws Exception {
assertEquals(parser.getBeginPosition(), 45);
assertEquals(parser.getEndPosition(), 864);
}

@Test
public void test_parsing_java1() throws Exception {
HeaderParser parser = getCustomJavadocHeaderParser("src/test/resources/doc/java1.txt");
assertTrue(parser.gotAnyHeader());
assertEquals("package", parser.getFileContent().getContent().substring(parser.getEndPosition()).trim().substring(0, 7));
}

@Test
public void test_parsing_java2() throws Exception {
HeaderParser parser = getCustomJavadocHeaderParser("src/test/resources/doc/java2.txt");
assertTrue(parser.gotAnyHeader());
assertEquals("package", parser.getFileContent().getContent().substring(parser.getEndPosition()).trim().substring(0, 7));
}

@Test
public void test_parsing_java3() throws Exception {
HeaderParser parser = getCustomJavadocHeaderParser("src/test/resources/doc/java3.txt");
assertTrue(parser.gotAnyHeader());
assertEquals("package", parser.getFileContent().getContent().substring(parser.getEndPosition()).trim().substring(0, 7));
}

private HeaderParser getCustomJavadocHeaderParser(final String fileName) {
final HeaderDefinition headerDefinition = new HeaderDefinition(
"javadoc2_style", "/**", " ** ", " **/", "", null, "^\\s*/\\*.*$", "^\\s*\\*.*$", "^.*\\*/\\s*$", false, true, false);
return new HeaderParser(new FileContent(new File(fileName), System.getProperty("file.encoding")), headerDefinition, new String[]{"copyright"});
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would need also to have a more complete test (like CompleteMojoTest does) to also test the other plugin actions, like really testing the issue you want to fix.



}
4 changes: 4 additions & 0 deletions license-maven-plugin/src/test/resources/doc/java1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/***********************
** Copyright ACME
**********************/
package com.mycila.maven.plugin.license.header;
4 changes: 4 additions & 0 deletions license-maven-plugin/src/test/resources/doc/java2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/***********************
* Copyright ACME
**********************/
package com.mycila.maven.plugin.license.header;
4 changes: 4 additions & 0 deletions license-maven-plugin/src/test/resources/doc/java3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/***********************
* Copyright ACME *
***********************/
package com.mycila.maven.plugin.license.header;