-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add: file utils, common utils for use in migration logic by users Working example for using utils to write a migration Update docs to mention utils
- Loading branch information
1 parent
308a724
commit 4462eea
Showing
13 changed files
with
471 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
baton-maven-plugin/src/main/java/org/technologybrewery/baton/util/CommonUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package org.technologybrewery.baton.util; | ||
import com.vdurmont.semver4j.Semver; | ||
|
||
public class CommonUtils { | ||
/** | ||
* Checks if version1 is less than version2 using the Semver4j library. | ||
* | ||
* @param version1 | ||
* @param version2 | ||
* @return isLessThanVersion - if true, version1 is less than version2. | ||
*/ | ||
public static boolean isLessThanVersion(String version1, String version2) { | ||
Semver sem = new Semver(version1); | ||
return sem.isLowerThan(version2); | ||
} | ||
} |
204 changes: 204 additions & 0 deletions
204
baton-maven-plugin/src/main/java/org/technologybrewery/baton/util/FileUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
package org.technologybrewery.baton.util; | ||
|
||
import org.apache.commons.io.IOUtils; | ||
import org.codehaus.plexus.util.StringUtils; | ||
|
||
import java.io.File; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
import java.nio.charset.Charset; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
public final class FileUtils { | ||
|
||
/** | ||
* | ||
* @param file the File | ||
* @param toReplace a string representing the text to replace | ||
* @param replacement the replacement text to substitute the toReplace string | ||
* @return a boolean set to true if at least one replacement was performed in the file | ||
*/ | ||
public static boolean replaceLiteralInFile(File file, String toReplace, String replacement) throws IOException { | ||
boolean replacedInFile = false; | ||
|
||
if (file != null && file.exists()) { | ||
String content = new String(Files.readAllBytes((file.toPath()))); | ||
content = content.replace(toReplace, replacement); | ||
Files.write(file.toPath(), content.getBytes()); | ||
replacedInFile = true; | ||
} | ||
return replacedInFile; | ||
} | ||
|
||
/** | ||
* | ||
* @param file the File | ||
* @param regex a regex representing the text to replace, as a String | ||
* @param replacement the replacement text to substitute the regex | ||
* @return a boolean set to true if at least one replacement was performed in the file | ||
*/ | ||
public static boolean replaceInFile(File file, String regex, String replacement) throws IOException { | ||
boolean replacedInFile = false; | ||
if (file != null && file.exists()) { | ||
Charset charset = StandardCharsets.UTF_8; | ||
String fileContent = new String(Files.readAllBytes(file.toPath()), charset); | ||
|
||
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); | ||
Matcher matcher = pattern.matcher(fileContent); | ||
String newFileContent = matcher.replaceAll(replacement); | ||
IOUtils.write(newFileContent, new FileOutputStream(file), charset); | ||
replacedInFile = true; | ||
} | ||
return replacedInFile; | ||
} | ||
|
||
/** | ||
* Evaluates a file against a regex pattern and replaces a substring of each regex match | ||
* with a specified replacement | ||
* @param file the File | ||
* @param regex a regex representing the text to replace a substring of | ||
* @param substring the substring of the regex match that will be replaced | ||
* @param replacement the replacement of the match substring | ||
* @return a boolean set to true if at least one modification was performed in the file | ||
*/ | ||
public static boolean modifyRegexMatchInFile(File file, String regex, String substring, String replacement) { | ||
if (file == null || !file.exists()) { | ||
return false; | ||
} | ||
|
||
boolean modified = false; | ||
|
||
try { | ||
Path path = file.toPath(); | ||
Charset charset = StandardCharsets.UTF_8; | ||
List<String> resultLines = new ArrayList<>(); | ||
|
||
Pattern pattern = Pattern.compile(regex); | ||
for (String line : Files.readAllLines(path, charset)) { | ||
if (pattern.matcher(line).find()) { | ||
line = line.replace(substring, replacement); | ||
modified = true; | ||
} | ||
resultLines.add(line); | ||
} | ||
if (modified) { | ||
Files.write(path, resultLines, charset); | ||
} | ||
} catch (IOException e) { | ||
return false; | ||
} | ||
return modified; | ||
} | ||
|
||
/** | ||
* Reads in the {@link File} object and returns a {@link List} of the contents. | ||
* @param file {@link File} to read | ||
* @return {@link List} of the contents | ||
* @throws IOException | ||
*/ | ||
public static List<String> readAllFileLines(File file) throws IOException { | ||
return Files.readAllLines(file.toPath(), StandardCharsets.UTF_8); | ||
} | ||
|
||
/** | ||
* Writes a {@link List} of the contents to the {@link File} object. | ||
* @param file {@link File} to write | ||
* @param contents {@link List} of the contents | ||
* @throws IOException | ||
*/ | ||
public static void writeFile(File file, List<String> contents) throws IOException { | ||
Files.write(file.toPath(), contents, StandardCharsets.UTF_8); | ||
} | ||
|
||
/** | ||
* @see FileUtils#getRegExCaptureGroups(String, String) | ||
* @param regex a regex containing capture groups, as a String | ||
* @param file the file to search for matching capture groups | ||
* @return An ArrayList of Strings representing each capture group in the regex that was matched | ||
*/ | ||
public static ArrayList<String> getRegExCaptureGroups(String regex, File file) throws IOException { | ||
String fileContent = ""; | ||
if (file != null && file.exists()) { | ||
Charset charset = StandardCharsets.UTF_8; | ||
fileContent = new String(Files.readAllBytes(file.toPath()), charset); | ||
} | ||
return StringUtils.isNotEmpty(fileContent) ? getRegExCaptureGroups(regex, fileContent) : new ArrayList<>(); | ||
} | ||
|
||
/** | ||
* | ||
* @param regex a regex containing capture groups, as a String | ||
* @param input the string to search for matching capture groups | ||
* @return An ArrayList of Strings representing each capture group in the regex that was matched | ||
*/ | ||
public static ArrayList<String> getRegExCaptureGroups(String regex, String input) { | ||
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); | ||
Matcher matcher = pattern.matcher(input); | ||
|
||
ArrayList<String> captured = new ArrayList<>(); | ||
if (matcher.find()) { | ||
// Skip the 0 index -- the first match is always all capture groups put together | ||
for (int i = 1; i <= matcher.groupCount(); ++i) { | ||
captured.add(matcher.group(i)); | ||
} | ||
} | ||
|
||
return captured; | ||
} | ||
|
||
/** | ||
* Evaluates a regex pattern against a file to determine if at least one regex match exists | ||
* | ||
* @param regex a regex pattern, as a String | ||
* @param file the file to search for matching substrings | ||
* @return true if there is at least one regex match, otherwise false | ||
*/ | ||
public static boolean hasRegExMatch(String regex, File file) throws IOException { | ||
String fileContent; | ||
if (file != null && file.exists()) { | ||
Charset charset = StandardCharsets.UTF_8; | ||
fileContent = Files.readString(file.toPath(), charset); | ||
return Pattern.compile(regex, Pattern.MULTILINE).matcher(fileContent).find(); | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* Infers the indentation style from the given line. | ||
* | ||
* @param line the line to infer the indentation style from | ||
* @param level the level of indentation of the line | ||
* @return a single indent in the inferred style | ||
*/ | ||
public static String getIndent(String line, int level) { | ||
if( level < 1 ) { | ||
return ""; | ||
} | ||
int i = 0; | ||
while (i < line.length() && Character.isWhitespace(line.charAt(i))) { | ||
i++; | ||
} | ||
return line.substring(0, i/level); | ||
} | ||
|
||
/** | ||
* Indent the values the desired number of tabs with a variable tab size. | ||
* @param values List of {@link String} values to indent | ||
* @param numSpaces number of spaces to indent | ||
*/ | ||
public static void indentValues(List<String> values, int numSpaces) { | ||
String SPACE = " "; | ||
for (int i = 0; i < values.size(); i++) { | ||
if (!values.get(i).isBlank()) { | ||
values.set(i, SPACE.repeat(numSpaces) + values.get(i)); | ||
} | ||
} | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
baton-maven-plugin/src/test/java/org/technologybrewery/baton/UtilsTestSteps.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package org.technologybrewery.baton; | ||
|
||
import io.cucumber.java.en.Given; | ||
import io.cucumber.java.en.Then; | ||
import io.cucumber.java.en.When; | ||
import org.technologybrewery.baton.util.FileUtils; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
|
||
public class UtilsTestSteps { | ||
|
||
private static final File DEFAULT_TEST_DIRECTORY = new File("target/utils-test/"); | ||
private static final String DEFAULT_TEST_FILE_NAME = "text_file.txt"; | ||
File testFile; | ||
Boolean match; | ||
String inputAsString; | ||
List<String> captureGroups; | ||
|
||
@Given("I have a string containing {string}") | ||
public void i_have_a_string_containing(String str) throws Throwable { | ||
inputAsString = str; | ||
} | ||
|
||
@When("I use the regex {string} to retrieve capture groups") | ||
public void i_use_the_regex_to_retrieve_capture_groups(String regex) throws IOException { | ||
if (testFile != null) { | ||
captureGroups = FileUtils.getRegExCaptureGroups(regex, testFile); | ||
} else { | ||
captureGroups = FileUtils.getRegExCaptureGroups(regex, inputAsString); | ||
} | ||
} | ||
|
||
@Then("the size of the retrieved capture groups should be \"{int}\"") | ||
public void the_size_of_the_retrieved_capture_groups_should_be(int groups) { | ||
assertEquals(groups, captureGroups.size(),"Unexpected size for capture groups"); | ||
} | ||
|
||
@Then("the capture groups should include") | ||
public void the_capture_groups_should_include(List<String> expectedGroups) { | ||
assertEquals(expectedGroups, captureGroups); | ||
} | ||
|
||
@Given("I have a file containing the string {string}") | ||
public void i_have_a_file_containing_the_string(String string) throws IOException { | ||
testFile = new File(DEFAULT_TEST_DIRECTORY, DEFAULT_TEST_FILE_NAME); | ||
if (DEFAULT_TEST_DIRECTORY.mkdirs()) { | ||
FileUtils.writeFile(testFile, Collections.singletonList(string)); | ||
} | ||
} | ||
|
||
@When("I use the regex {string} to substitute {string}") | ||
public void i_use_the_regex_to_substitute(String regex, String substitute) throws IOException { | ||
FileUtils.replaceInFile(testFile, regex, substitute); | ||
} | ||
|
||
@When("I use the literal {string} to substitute {string}") | ||
public void iUseTheLiteralToSubstitute(String literal, String substitute) throws IOException { | ||
FileUtils.replaceLiteralInFile(testFile, literal, substitute); | ||
} | ||
|
||
@Then("the file should now contain the string {string}") | ||
public void the_file_should_now_contain_the_string(String string) throws IOException { | ||
assertTrue(FileUtils.hasRegExMatch(string, testFile), String.format("File does not contain expected string %s",string)); | ||
} | ||
|
||
@When("I use the regex {string} to substitute {string} with {string}") | ||
public void i_use_the_regex_to_substitute_with(String regex, String target, String substitute) { | ||
FileUtils.modifyRegexMatchInFile(testFile, regex, target, substitute); | ||
} | ||
|
||
@When("I use the regex {string} to search for matches in a file") | ||
public void i_use_the_regex_to_search_for_matches_in_a_file(String regex) throws IOException { | ||
match = FileUtils.hasRegExMatch(regex, testFile); | ||
|
||
} | ||
|
||
@Then("the match result should be \"{booleanValue}\"") | ||
public void the_match_result_should_be(Boolean expected) { | ||
assertEquals(expected, match, "RegEx file matcher did not return expected result"); | ||
|
||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
baton-maven-plugin/src/test/java/org/technologybrewery/baton/util/TestUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
package org.technologybrewery.baton.util; | ||
|
||
import io.cucumber.java.ParameterType; | ||
|
||
public class TestUtils { | ||
@ParameterType( value = "true|True|TRUE|false|False|FALSE") | ||
public Boolean booleanValue(String value){ | ||
return Boolean.valueOf(value); | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
baton-maven-plugin/src/test/resources/specifications/util/common-utils.feature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Feature: Baton utilities can be used to assist with commonly used logic in a migration | ||
Scenario: I can easily compare the semantic versioning of two strings |
45 changes: 45 additions & 0 deletions
45
baton-maven-plugin/src/test/resources/specifications/util/file-utils.feature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
@baton | ||
Feature: Baton utilities can be used to assist with migration logic pertaining to files | ||
|
||
Scenario: I want to easily replace a string in a file using a literal expression | ||
Given I have a file containing the string "123abc456" | ||
When I use the literal "abc" to substitute "def" | ||
Then the file should now contain the string "123def456" | ||
|
||
Scenario: I want to easily replace a string in a file using a regex expression | ||
Given I have a file containing the string "123abc456" | ||
When I use the regex "(?<=123).*(?=456)" to substitute "def" | ||
Then the file should now contain the string "123def456" | ||
|
||
Scenario: I want to easily replace a substring of a string in a file using a regex expression | ||
Given I have a file containing the string "123abc456" | ||
When I use the regex "123.*456" to substitute "abc" with "def" | ||
Then the file should now contain the string "123def456" | ||
|
||
Scenario: I want to easily test if a string is present in a file using a regex expression | ||
Given I have a file containing the string "123abc456" | ||
When I use the regex "123.*456" to search for matches in a file | ||
Then the match result should be "true" | ||
|
||
Scenario: I want to easily be able to pull out specific substrings from a string using regex capture groups | ||
Given I have a string containing "123abc456" | ||
When I use the regex "123(.*)456" to retrieve capture groups | ||
Then the size of the retrieved capture groups should be "1" | ||
And the capture groups should include | ||
| abc | | ||
|
||
Scenario: I want to easily be able to pull out specific strings from a file using regex capture groups | ||
Given I have a file containing the string "123abc456" | ||
When I use the regex "(123).*(456)" to retrieve capture groups | ||
Then the size of the retrieved capture groups should be "2" | ||
And the capture groups should include | ||
| 123 | | ||
| 456 | | ||
|
||
Scenario: I want to easily retrieve the type of indexing being used in a string | ||
|
||
Scenario: I want to easily indent a group of strings with spaces | ||
|
||
Scenario: I want to easily retrieve the contents of a file | ||
|
||
Scenario: I want to easily write to a file |
Oops, something went wrong.