diff --git a/README.md b/README.md index 84a2103..f32e3e9 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,11 @@ Usage:
[options] [command] [command options] -r, --ruleset The ruleset to use when you merge poms. If you don't specify a ruleset, a default ruleset will be used. Default is ProjectAndParentVersionRule with our strategy. + -e, --expandtab + Replace all indentation tabs with the specified amount of spaces. + Note: this is just a subset of the git's -Xignore-all-space + functionality. Misalignment after the tab replacement will still result in the + merge conflicts. replace Updates the parent version and/or the project version in the given pom.xml Usage: replace [options] diff --git a/src/main/java/de/oppermann/pomutils/Main.java b/src/main/java/de/oppermann/pomutils/Main.java index fc0a99b..4c75495 100644 --- a/src/main/java/de/oppermann/pomutils/Main.java +++ b/src/main/java/de/oppermann/pomutils/Main.java @@ -93,6 +93,23 @@ protected static int mainInternal(String... args) { } private static int executePomMergeDriver(CommandPomMergeDriver mergeCommand) { + if (mergeCommand.getExpandTabSpaceCount() != null) { + int spaceCount = mergeCommand.getExpandTabSpaceCount().intValue(); + if (mergeCommand.getOurPom() != null) { + TabExpander ourTabExpander = new TabExpander(mergeCommand.getOurPom(), spaceCount); + ourTabExpander.expand(); + } + + if (mergeCommand.getTheirPom() != null) { + TabExpander theirTabExpander = new TabExpander(mergeCommand.getTheirPom(), spaceCount); + theirTabExpander.expand(); + } + + if (mergeCommand.getBasePom() != null) { + TabExpander baseTabExpander = new TabExpander(mergeCommand.getBasePom(), spaceCount); + baseTabExpander.expand(); + } + } PomMergeDriver pomMergeDriver = new PomMergeDriver(mergeCommand.getRuleSet(), mergeCommand.getBasePom(), mergeCommand.getOurPom(), mergeCommand.getTheirPom()); return pomMergeDriver.merge(); diff --git a/src/main/java/de/oppermann/pomutils/TabExpander.java b/src/main/java/de/oppermann/pomutils/TabExpander.java new file mode 100644 index 0000000..9332a0e --- /dev/null +++ b/src/main/java/de/oppermann/pomutils/TabExpander.java @@ -0,0 +1,148 @@ +package de.oppermann.pomutils; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.BufferedOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; + +import org.codehaus.plexus.util.IOUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Converts indentation-tabs to configurable amount of spaces. + * No support for Unicode-Spaces (other then standard 0x20 character).
+ *
+ * Example: + *
+ * \t\tString text = "\t"; + *
+ * + * replacing tabs with 4 spaces get converted into + * + *
+ * ........String text = "\t"; + *
+ * (`.ยด represents a space character).
+ * + * @author Boris Brodski + * + */ +public class TabExpander { + private final Logger logger = LoggerFactory.getLogger(TabExpander.class); + + private String filename; + private int spaceCount; + + public TabExpander(String filename, int spaceCount) { + this.filename = filename; + this.spaceCount = spaceCount; + } + + public void expand() { + logger.debug("Expanding indenting tabs into {} spaces [file={}]", spaceCount, filename); + + byte[] fileInMemory = readFileIntoMemory(); + + boolean ok = false; + OutputStream outputStream = null; + try { + outputStream = new BufferedOutputStream(new FileOutputStream(filename)); + copyExpandingTabs(fileInMemory, outputStream); + + ok = true; + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + if (ok) { + throw new RuntimeException(e); + } else { + logger.error("Error closing output file " + filename, e); + } + } + } + } + } + + private void copyExpandingTabs(byte[] fileInMemory, OutputStream outputStream) throws IOException { + byte[] indentSpaces = new byte[spaceCount]; + Arrays.fill(indentSpaces, (byte)' '); + boolean inIndent = true; + for (int i = 0; i < fileInMemory.length; i++) { + switch (fileInMemory[i]) { + case '\n': + case '\r': + inIndent = true; + break; + + case ' ': + break; + + case '\t': + if (inIndent) { + outputStream.write(indentSpaces); + continue; + } + break; + + default: + inIndent = false; + } + + outputStream.write(fileInMemory[i]); + } + } + + private byte[] readFileIntoMemory() { + InputStream inputStream = null; + byte[] fileInMemory; + boolean ok = false; + try { + inputStream = new FileInputStream(filename); + fileInMemory = IOUtil.toByteArray(inputStream); + ok = true; + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + if (ok) { + throw new RuntimeException(e); + } else { + logger.error("Error closing input file " + filename, e); + } + } + } + } + return fileInMemory; + } + +} diff --git a/src/main/java/de/oppermann/pomutils/commands/CommandPomMergeDriver.java b/src/main/java/de/oppermann/pomutils/commands/CommandPomMergeDriver.java index b5ae27d..de340be 100644 --- a/src/main/java/de/oppermann/pomutils/commands/CommandPomMergeDriver.java +++ b/src/main/java/de/oppermann/pomutils/commands/CommandPomMergeDriver.java @@ -51,6 +51,9 @@ public class CommandPomMergeDriver { @Parameter(names = { "-r", "--ruleset" }, description = "The ruleset to use when you merge poms. If you don't specify a ruleset, a default ruleset will be used. Default is ProjectAndParentVersionRule with our strategy.") private File ruleSetfile; + @Parameter(names = { "-e", "--expandtab" }, description = "Replace all indentation tabs with the specified amount of spaces. Note: this is just a subset of the git's -Xignore-all-space functionality. Misalignment after the tab replacement will still result in the merge conflicts.", arity = 1) + private Integer expandTabSpaceCount; + public String getBasePom() { return basePom; } @@ -78,4 +81,7 @@ public Ruleset getRuleSet() { return new Ruleset(getRuleSetFile()); } + public Integer getExpandTabSpaceCount() { + return expandTabSpaceCount; + } } diff --git a/src/test/java/de/oppermann/pomutils/TabExpanderTest.java b/src/test/java/de/oppermann/pomutils/TabExpanderTest.java new file mode 100644 index 0000000..f257920 --- /dev/null +++ b/src/test/java/de/oppermann/pomutils/TabExpanderTest.java @@ -0,0 +1,106 @@ +package de.oppermann.pomutils; + + +import java.io.File; + +import org.apache.commons.io.FileUtils; +import org.junit.BeforeClass; +import org.junit.Test; + +import junit.framework.TestCase; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Tests tab expand feature: + * + *
+ * --expandtab={amount-of-space}
+ * 
+ * + * @author Boris Brodski + * + */ +public class TabExpanderTest extends TestCase { + private static File dir; + + public void setUp() { + dir = new File(TestUtils.resourceBaseTestFolder + "/" + "tabExpander"); + dir.mkdirs(); + } + + public void testExpandTab1() throws Exception { + String result = expand("", 4); + assertEquals("", result); + } + + public void testExpandTab2() throws Exception { + String result = expand("\t", 4); + assertEquals(" ", result); + } + + public void testExpandTab3() throws Exception { + String result = expand("line1\n\t\tText:\ttest\n\t\t\n", 4); + assertEquals("line1\n Text:\ttest\n \n", result); + } + + public void testExpandTab4() throws Exception { + String result = expand("line1\n\t\tText:\ttest\n\t\t\n", 1); + assertEquals("line1\n Text:\ttest\n \n", result); + } + + public void testIntegrationWithoutExpandTab() throws Exception { + String myTestSubFolder = "tabExpander/withoutExpandTab"; + + TestUtils.prepareTestFolder(myTestSubFolder); + + String[] args = { + "merge" + , "--our=" + TestUtils.resourceBaseTestFolder + "/" + myTestSubFolder + "/our.pom.xml" + , "--base=" + TestUtils.resourceBaseTestFolder + "/" + myTestSubFolder + "/base.pom.xml" + , "--their=" + TestUtils.resourceBaseTestFolder + "/" + myTestSubFolder + "/their.pom.xml" }; + + assertEquals(1, Main.mainInternal(args)); + } + + public void testIntegrationWithExpandTab() throws Exception { + String myTestSubFolder = "tabExpander/withExpandTab"; + + TestUtils.prepareTestFolder(myTestSubFolder); + + String[] args = { + "merge" + , "--our=" + TestUtils.resourceBaseTestFolder + "/" + myTestSubFolder + "/our.pom.xml" + , "--base=" + TestUtils.resourceBaseTestFolder + "/" + myTestSubFolder + "/base.pom.xml" + , "--their=" + TestUtils.resourceBaseTestFolder + "/" + myTestSubFolder + "/their.pom.xml" + , "--expandtab=4" }; + + assertEquals(0, Main.mainInternal(args)); + } + + private String expand(String from, int spaces) throws Exception { + File file = new File(dir, "test.txt"); + FileUtils.write(file, from); + new TabExpander(file.getAbsolutePath(), spaces).expand(); + + return FileUtils.readFileToString(file); + } + +} diff --git a/src/test/resources/tabExpander/withExpandTab/base.pom.xml b/src/test/resources/tabExpander/withExpandTab/base.pom.xml new file mode 100644 index 0000000..68d4988 --- /dev/null +++ b/src/test/resources/tabExpander/withExpandTab/base.pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + de.oppermann.pomutils + pomutils + base + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + maven-plugin + + + diff --git a/src/test/resources/tabExpander/withExpandTab/our.pom.xml b/src/test/resources/tabExpander/withExpandTab/our.pom.xml new file mode 100644 index 0000000..8635e17 --- /dev/null +++ b/src/test/resources/tabExpander/withExpandTab/our.pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + de.oppermann.pomutils + pomutils + our + + + org.codehaus.mojo + versions-maven-plugin + 2.5 + maven-plugin + + + diff --git a/src/test/resources/tabExpander/withExpandTab/their.pom.xml b/src/test/resources/tabExpander/withExpandTab/their.pom.xml new file mode 100644 index 0000000..1a83986 --- /dev/null +++ b/src/test/resources/tabExpander/withExpandTab/their.pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + de.oppermann.pomutils + pomutils + their + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + maven-plugin + + + diff --git a/src/test/resources/tabExpander/withoutExpandTab/base.pom.xml b/src/test/resources/tabExpander/withoutExpandTab/base.pom.xml new file mode 100644 index 0000000..68d4988 --- /dev/null +++ b/src/test/resources/tabExpander/withoutExpandTab/base.pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + de.oppermann.pomutils + pomutils + base + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + maven-plugin + + + diff --git a/src/test/resources/tabExpander/withoutExpandTab/our.pom.xml b/src/test/resources/tabExpander/withoutExpandTab/our.pom.xml new file mode 100644 index 0000000..8635e17 --- /dev/null +++ b/src/test/resources/tabExpander/withoutExpandTab/our.pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + de.oppermann.pomutils + pomutils + our + + + org.codehaus.mojo + versions-maven-plugin + 2.5 + maven-plugin + + + diff --git a/src/test/resources/tabExpander/withoutExpandTab/their.pom.xml b/src/test/resources/tabExpander/withoutExpandTab/their.pom.xml new file mode 100644 index 0000000..1a83986 --- /dev/null +++ b/src/test/resources/tabExpander/withoutExpandTab/their.pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + de.oppermann.pomutils + pomutils + their + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + maven-plugin + + +