一键执行更新密文密码到指定目录下的所有文件
1. 占位符的格式为 %(key)
2. 密码集中管理于某个指定的文件
3. 运行 gradle 执行更新; 运行 gradle clean test 执行单元测试.
build.gradle
apply plugin: 'groovy'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.7'
compile 'org.apache.ant:ant:1.9.4'
testCompile 'junit:junit:4.11'
testCompile 'commons-io:commons-io:2.2'
}
sourceSets {
main {
groovy {
srcDirs = ['.']
include 'Two.groovy'
}
}
test {
groovy {
srcDirs = ['test/groovy']
}
}
}
task runScript(type: JavaExec) {
description 'Run Groovy script'
// Set main property to name of Groovy script class.
main = 'Two'
// Set classpath for running the Groovy script.
classpath = sourceSets.main.runtimeClasspath
}
defaultTasks 'runScript'
Two.groovy
#!/usr/bin/env groovy
public class Two{
static def sampleFile='''
#-----Follows are the content of a sample configuration file-----
#path to the credentials file. (Don't input any space in between)
suez.credentials.path=./ssts-credentials.properties
#path(s) to the target top foder(s). Please separate with ";" when there is more than one target top folder. (Don't input any space in between)
suez.target.path=./config;./build
#the extentions of configuration files. (Don't input any space in between)
file.extention.filter=.xml;.properties;.cfg
#----------------------------------------------------------------
'''
static def final LINE_SEPARATOR = System.getProperty('line.separator')
//static def configFile = this.getName() + '.properties'
//static def logFile = this.getName() + '.log'
//static def log = new File(logFile)
static def configFile
static def logFile
static def log
static def credentialsMap = [:]
static def credentialFile
static def targetPath = []
static def extensions = []
// To read from credential file and put key/value pairs into a map
static getCredentialMap(){
def f = new File(credentialFile)
f.eachLine{
if(!it.trim().startsWith('#')){
def tokens = it.split('=')
credentialsMap.put('%('+tokens[0].trim()+')', tokens[1].trim())
}
}
}
// To scan recursively from a specific top folder where there are configuration files need to update their credentials
static scanFolderRecurse(String path){
new File(path).eachFileRecurse {
if(it.isFile()){
processFile(it)
}
}
}
// To process a specific file
static processFile(file){
def extension = '.' + file.getName().split(/\./)[-1]
if(extension in extensions){
def newFile = new StringBuilder()
def updated = false
def lineNo = 0
file.eachLine{
lineNo += 1
def result = processLine(it)
def replaced = result[0]
def text = result[1]
text += LINE_SEPARATOR
if(replaced){
updated = true
log.append(file.getCanonicalPath() + LINE_SEPARATOR)
log.append(String.format('Line %3d: %s', lineNo, it.trim()) + LINE_SEPARATOR)
log.append(String.format('========> %s', text.trim()) + LINE_SEPARATOR)
}
newFile.append(text)
}
if(updated){
file.write('')
file.write(newFile.toString())
}
}
}
// To process a specific line
static def processLine(line){
def text = line
def pattern = ~/\%\(.+?\)/
def replaced = false
def matcher = pattern.matcher(line)
def count = matcher.getCount()
for(i in 0..<count){
def key = matcher[i]
def value = credentialsMap.get(key)
if( value != null){
text = line.replace(key, value)
replaced = true
}
}
return [replaced, text]
}
static init(File scriptConfigPathFile){
configFile = scriptConfigPathFile ? scriptConfigPathFile : new File(this.getName() + '.properties')
logFile = this.getName() + '.log'
log = new File(logFile)
log.write('')
try{
configFile.eachLine{
if(it.startsWith('suez.credentials.path'))
credentialFile=it.split('=')[1].trim()
if(it.startsWith('suez.target.path'))
targetPath=it.split('=')[1].trim().split(';')
if(it.startsWith('file.extension.filter'))
extensions=it.split('=')[1].trim().split(';')
}
getCredentialMap()
}catch(IOException e){
println 'Please prepare ' + configFile + ' for this script ' + this.getName() + '.groovy'
println sampleFile
println e
}catch(Exception e){
println e
}
}
static main(args){
init(null)
for(String path in targetPath){
scanFolderRecurse(path)
}
}
}
TwoTest.groovy
import org.junit.*
import static org.junit.Assert.*
import org.apache.commons.io.FileUtils
import groovy.util.AntBuilder
class TwoTest {
@Before
public void setUp(){
Two.init(new File('test/groovy/Two.properties'))
}
@Test
public void initTest(){
assertNotNull Two.configFile
assertEquals 'Two.properties', Two.configFile.getName()
assertEquals 'Two.log', Two.logFile
assertNotNull Two.log
assertEquals 'Two.log', Two.log.getName()
}
@Test
public void processLineReturnTrue(){
def input = '<input type="text" name="suez.username" value="%(suez.username)"/>'
def value = Two.processLine(input)
assertTrue value[0]
assertEquals '<input type="text" name="suez.username" value="cdef"/>', value[1]
}
@Test
public void processLineReturnFalse(){
def input = '<input type="text" name="suez.username" value="cdef"/>'
def value = Two.processLine(input)
assertFalse value[0]
assertEquals '<input type="text" name="suez.username" value="cdef"/>', value[1]
}
@Test
public void processFileWithUpdating(){
new File('test/groovy/suez.properties').delete()
def ant = new AntBuilder()
ant.copy( file : 'test/groovy/suez.properties.bak' , tofile : 'test/groovy/suez.properties')
def file = new File('test/groovy/suez.properties')
Two.processFile(file)
assertEquals("The files differ!",
FileUtils.readFileToString(new File('test/groovy/suez.properties')),
FileUtils.readFileToString(new File('test/groovy/result-suez.properties')));
}
@Test
public void processFileWithoutUpdating(){
def file = new File('test/groovy/result-suez.properties')
def lastModified = file.lastModified()
Two.processFile(file)
def lastModifiedAfterProcessing = new File('test/groovy/result-suez.properties').lastModified()
assertEquals("The file was changed!",
lastModified,
lastModifiedAfterProcessing);
}
@Test
public void getCredentialMapTest(){
def props = new Properties()
new File("./test/groovy/suez-credentials.properties").withInputStream {
stream -> props.load(stream)
}
def expectedMap = [:]
props.each{k,v->
expectedMap.put('%('+k+')',v)
}
assertEquals expectedMap, Two.credentialsMap
}
@Test
public void scanFolderRecurseTest(){
def ant = new AntBuilder()
new File('./test/groovy/uat').eachFileRecurse{
def pathfile = it.getCanonicalPath()
if(!pathfile.endsWith('original') && !pathfile.endsWith('target') && it.isFile()) it.delete()
}
new File('./test/groovy/uat').eachFileRecurse{
def pathfile = it.getCanonicalPath()
if(pathfile.endsWith('original')) ant.copy( file : pathfile , tofile : pathfile.replace('.original', ''))
}
Two.scanFolderRecurse('./test/groovy/uat')
new File('./test/groovy/uat').eachFileRecurse{
def pathfile = it.getCanonicalPath()
if(pathfile.endsWith('target')){
final File expected = it;
final File output = new File(it.getCanonicalPath().replace('.target', ''));
assertEquals(FileUtils.readLines(expected), FileUtils.readLines(output));
}
}
final File expectedLog = new File('Two.log')
final File actualLog = new File('./test/groovy/Two.log')
ant.copy( file : expectedLog.getCanonicalPath() , tofile : actualLog.getCanonicalPath() + '.actual')
assertEquals(FileUtils.readLines(expectedLog), FileUtils.readLines(actualLog));
}
@Test
public void scanFolderRecurseTestEmptyPath(){
try {
Two.scanFolderRecurse('')
fail();
}
catch (java.io.FileNotFoundException e) { }
}
}
Two.properties
dummy.credentials.path=test/groovy/dummy-credentials.properties
<pre code_snippet_id="557663" snippet_file_name="blog_20141220_4_5309252" name="code" class="plain">dummy<span style="font-family: Arial, Helvetica, sans-serif;">.target.path=./config;./configChina</span>
file.extension.filter=.xml;.properties