一键执行更新密文密码到指定目录下的所有文件, 附单元测试

2 篇文章 0 订阅
2 篇文章 0 订阅

一键执行更新密文密码到指定目录下的所有文件

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
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值