)";
78 | //
79 | // Pattern pattern = Pattern.compile(regex);
80 | // Matcher matcher = pattern.matcher(str);
81 | // while(matcher.find()) {
82 | //
83 | // System.out.println(matcher.group(1));
84 | // System.out.println(matcher.group(2));
85 | // System.out.println(matcher.group(3));
86 | // }
87 |
88 |
89 | }
90 | }
91 | */
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/ResToolsConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.github.better.restools;
2 |
3 | public class ResToolsConfiguration {
4 | /**
5 | * 新的资源前缀
6 | */
7 | public String new_prefix = "";
8 | /**
9 | * 老的资源前缀,取值说明如下:
10 | *
11 | * 1. 使用空字符串:
12 | * 比如:new_prefix 为 'mae_', module_main_activity.xml 会被替换成 mae_module_main_activity.xml
13 | * 2. 取值字符串时:
14 | * 比如:old_prefix='module_', new_prefix='mae_', module_main_activity.xml 会被替换成 mae_main_activity.xml
15 | */
16 | public String old_prefix = "";
17 |
18 | /**
19 | * 源代码目录
20 | */
21 | public String srcFolderPath = "";
22 |
23 | /**
24 | * 资源文件目录
25 | */
26 | public String resFolderPath = "";
27 |
28 | /**
29 | * 清单文件路径
30 | */
31 | public String manifestFilePath = "";
32 |
33 |
34 | public ResToolsConfiguration(String new_prefix, String old_prefix, String srcFolderPath, String resFolderPath, String manifestFilePath) {
35 | this.new_prefix = new_prefix;
36 | this.old_prefix = old_prefix;
37 | this.srcFolderPath = srcFolderPath;
38 | this.resFolderPath = resFolderPath;
39 | this.manifestFilePath = manifestFilePath;
40 | }
41 |
42 | public ResToolsConfiguration() {
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/ResToolsPlugin.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools
2 |
3 | import com.github.better.restools.folder.AnimReplace
4 | import com.github.better.restools.folder.ColorReplace
5 | import com.github.better.restools.folder.DrawableReplace
6 | import com.github.better.restools.folder.LayoutReplace
7 | import com.github.better.restools.folder.MenuReplace
8 | import com.github.better.restools.folder.MipmapReplace
9 | import com.github.better.restools.folder.RawReplace
10 | import com.github.better.restools.folder.XmlReplace
11 | import com.github.better.restools.values.ValuesReplace
12 | import com.github.better.restools.ResToolsConfiguration
13 | import org.gradle.api.Plugin
14 | import org.gradle.api.Project
15 |
16 | /**
17 | * zhaoyu1
18 | */
19 | class ResToolsPlugin implements Plugin {
20 |
21 | static final String APP = "com.android.application"
22 | static final String LIBRARY = "com.android.library"
23 |
24 | @Override
25 | void apply(Project project) {
26 | if (!(project.plugins.hasPlugin(APP) || project.plugins.hasPlugin(LIBRARY))) {
27 | throw new IllegalArgumentException(
28 | 'ResTools gradle plugin can only be applied to android projects.')
29 | }
30 |
31 | // config
32 | project.extensions.create('resConfig', ResToolsConfiguration.class)
33 |
34 | // === Create Task
35 | project.tasks.create(["name": "replaceResName", "group": "resourceTools"]) << {
36 | if (!project.android) {
37 | throw new IllegalStateException('Must apply \'com.android.application\' or \'com.android.library\' first!')
38 | }
39 |
40 | if (project.resConfig == null) { // check config
41 | throw new IllegalArgumentException(
42 | 'ResTools gradle plugin "resConfig DSL" config can not be null.')
43 | }
44 |
45 | // === System default
46 | String sourceFolder = project.android.sourceSets.main.java.srcDirs[0].getAbsolutePath()
47 | String resFolder = project.android.sourceSets.main.res.srcDirs[0].getAbsolutePath()
48 | String manifestFilePath = project.android.sourceSets.main.manifest.srcFile.getAbsolutePath()
49 |
50 | long startTime = System.currentTimeMillis() // startTime
51 |
52 | // === User settings
53 | def config = project.resConfig
54 | if (config.new_prefix == null || config.new_prefix.trim().length() == 0) {
55 | throw new IllegalArgumentException(
56 | 'the [new_prefix] can not be null (必须配置新的前缀)')
57 | }
58 | if (config.srcFolderPath != null && config.srcFolderPath.trim().length() > 0) {
59 | sourceFolder = config.srcFolderPath
60 | }
61 | if (config.resFolderPath != null && config.resFolderPath.trim().length() > 0) {
62 | resFolder = config.resFolderPath
63 | }
64 | if (config.manifestFilePath != null && config.manifestFilePath.trim().length() > 0) {
65 | manifestFilePath = config.manifestFilePath
66 | }
67 |
68 | // === print all settings
69 |
70 | println(">>>>>> old_prefix: ${config.old_prefix}")
71 | println(">>>>>> new_prefix: ${config.new_prefix}")
72 | println(">>>>>> srcFolder : ${sourceFolder}")
73 | println(">>>>>> resFolder : ${resFolder}")
74 | println(">>>>>> AndroidManifest.xml file path : ${manifestFilePath}")
75 |
76 | // === do work
77 | println "++++++++++++++++++++++ Start replace Android resources..."
78 |
79 | ResToolsConfiguration workConfig = new ResToolsConfiguration(
80 | config.new_prefix,
81 | config.old_prefix,
82 | sourceFolder,
83 | resFolder,
84 | manifestFilePath
85 | )
86 | doWork(workConfig)
87 |
88 | println("++++++++++++++++++++++ Finish replace resouces name, Total time: ${(System.currentTimeMillis() - startTime) / 1000} ")
89 | }
90 | }
91 |
92 | private def doWork(ResToolsConfiguration config) {
93 | // 1. layout
94 | LayoutReplace layoutReplace = new LayoutReplace(config);
95 | layoutReplace.replaceThis();
96 |
97 | // // 2. drawable
98 | DrawableReplace drawableReplace = new DrawableReplace(config);
99 | drawableReplace.replaceThis();
100 | //
101 | //
102 | // // 3. color
103 | ColorReplace colorReplace = new ColorReplace(config);
104 | colorReplace.replaceThis();
105 | //
106 | //
107 | // // 4. Anim
108 | AnimReplace anim = new AnimReplace(config);
109 | anim.replaceThis();
110 | //
111 | // // 5. menu
112 | MenuReplace menuReplace = new MenuReplace(config);
113 | menuReplace.replaceThis();
114 | //
115 | // // 6. mipmap
116 | MipmapReplace mipmapReplace = new MipmapReplace(config);
117 | mipmapReplace.replaceThis();
118 | //
119 | // // 7. raw
120 | RawReplace rawReplace = new RawReplace(config);
121 | rawReplace.replaceThis();
122 | //
123 | // // 8. xml
124 | XmlReplace xmlReplace = new XmlReplace(config);
125 | xmlReplace.replaceThis();
126 |
127 | ////////////// all values types ////////////////////
128 | // === 9. values test not support attrs
129 | ValuesReplace valuesReplace = new ValuesReplace(config);
130 | valuesReplace.replaceValues(ValuesReplace.ALL_VALUES_TYPES);
131 | }
132 | }
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/Tools.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools
2 |
3 |
4 | class Tools {
5 |
6 | final static OUTPUT = "out/android/export/"
7 | final static USER_CURRENT_DIR = System.getProperty("user.dir")
8 |
9 | static void checkDir(String moduleDir, String appResDir) {
10 | File moduleDirFile = new File(moduleDir)
11 | if (!moduleDirFile.exists() || !moduleDirFile.isDirectory()) {
12 | throw new RuntimeException("the Aodule ${moduleDir} Directory is wrong!")
13 | }
14 | // app 主工程资源目录,默认values
15 | File tappResDir = new File(appResDir)
16 | if (!tappResDir.exists() || !tappResDir.isDirectory()) {
17 | throw new RuntimeException("the App ${appResDir} Res Directory is wrong!")
18 | }
19 | }
20 |
21 | // 文件夹名称过滤
22 | final static class DirNamePrefixFilter implements FilenameFilter {
23 | def prefix = ""
24 |
25 | DirNamePrefixFilter(String prefix) {
26 | this.prefix = prefix
27 | }
28 |
29 | @Override
30 | boolean accept(File dir, String name) {
31 | return dir.isDirectory() && name.startsWith(prefix)
32 | }
33 | }
34 |
35 | final static class FileNameSuffixFilter implements FileFilter {
36 | def suffix = ""
37 |
38 | def FileNameSuffixFilter(suffix) {
39 | this.suffix = suffix
40 | }
41 |
42 | @Override
43 | boolean accept(File pathname) {
44 | return pathname.name.endsWith(suffix)
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/base/BaseFolderResReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.base
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 |
5 | /**
6 | * 资源Base
7 | * @auther better
8 | */
9 | abstract class BaseFolderResReplace extends BaseReplace {
10 |
11 | BaseFolderResReplace(ResToolsConfiguration config) {
12 | super(config)
13 | }
14 |
15 | /**
16 | * 获取资源类型名称
17 | * @return
18 | */
19 | abstract String getResTypeName()
20 |
21 | /**
22 | * 匹配源代码的正则表达式
23 | * @return
24 | */
25 | abstract String getJavaRegex()
26 |
27 | /**
28 | * 匹配xml中的正则表达式
29 | * @return
30 | */
31 | abstract String getXmlRegex()
32 |
33 | /**
34 | * 获取特定类型的资源名集合,比如:
35 | * drawable,需要注意,必须包含 drawable-xx的
36 | * @return
37 | */
38 | abstract Set getResNameSet()
39 |
40 | /**
41 | * 模板方法
42 | * @throws IOException
43 | */
44 | final void replaceThis() throws IOException {
45 | println("***** $resTypeName ***** do $resTypeName start...")
46 |
47 | def java_regx = ~getJavaRegex()
48 | def xml_regx = ~getXmlRegex()
49 | Set resNameSet = getResNameSet()
50 |
51 | // 1.源代码目录部分
52 | replaceSrc(resNameSet, java_regx)
53 | // 2.资源目录部分
54 | replaceRes(resNameSet, xml_regx)
55 |
56 | println("***** $resTypeName ***** do $resTypeName finish")
57 | }
58 |
59 | abstract void replaceSrc(Set resNameSet, java_regx) throws IOException
60 |
61 | abstract void replaceRes(Set resNameSet, xml_regx) throws IOException
62 |
63 |
64 | /**
65 | * 文件重命名,处理各种文件的重命名
66 | * @param file
67 | * @param resNameSet 资源名
68 | * @param dir_filter
69 | * @param resTypeName 资源类型名
70 | */
71 | protected void renameFile(File file, Set resNameSet, dir_filter, resTypeName) {
72 | File[] dirs = file.listFiles(dir_filter)
73 | dirs?.each { dir ->
74 | dir?.eachFile { it ->
75 | String fileName = it.name
76 | if (it.name.lastIndexOf('.' ) > -1) {
77 | // 可能是 png .9 图片
78 | fileName = it.name.substring(0, it.name.lastIndexOf("."))
79 | if (fileName.endsWith(".9")) { // 可能有.9
80 | fileName = fileName.substring(0, fileName.lastIndexOf("."))
81 | }
82 | }
83 |
84 | // 只替换指定的资源
85 | if (resNameSet.contains(fileName)) {
86 | String oldName = it.name
87 | String newName = config.new_prefix + oldName
88 | if (oldName.startsWith(config.old_prefix)) {
89 | newName = config.new_prefix + oldName.substring(config.old_prefix.length())
90 | }
91 |
92 | File newFile = new File(it.getParent(), newName)
93 | if (newFile.exists()) {
94 | newFile.delete()
95 | }
96 |
97 | if (!it.renameTo(newFile)) {
98 | println("--------------- $resTypeName ${it.name} 重命名失败!,请手动修改成:${newFile.name}")
99 | }
100 | }
101 | }
102 | }
103 | }
104 |
105 | /*
106 | void export(String moduleFolder, String appResFolder) {
107 | Tools.checkDir(moduleFolder, appResFolder)
108 |
109 | File moduleDirFile = new File(moduleFolder)
110 | // === 1.layout name map from module. (XXX to R.xxx.XXX)
111 | Map moduleMap = new HashMap<>()
112 | moduleMap(moduleDirFile, moduleDirFile, moduleMap)
113 | // === 2. layout name map from 'MainGo App Res'
114 | File appResDirFile = new File(appResFolder)
115 | // folderName to layout filename list
116 | Map> dirFileMap = getAppLayoutMap(appResDirFile, moduleLayoutMap)
117 | // === 3.according to 'moduleLayoutMap' key, find all layout from 'main app res' and copy layout.xml file from dirs
118 | export(dirFileMap, appResDir)
119 | }*/
120 | }
121 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/base/BaseReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.base
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 |
5 | import java.util.regex.Matcher
6 |
7 | abstract class BaseReplace {
8 | /**
9 | * 源代码路径
10 | */
11 | protected File srcDir
12 | /**
13 | * 资源文件路径
14 | */
15 | protected File resDir
16 |
17 | /**
18 | * AndroidManifest
19 | */
20 | protected File manifestFile
21 |
22 | protected ResToolsConfiguration config
23 |
24 | BaseReplace(ResToolsConfiguration config) {
25 | this.config = config
26 | this.srcDir = new File(config.srcFolderPath)
27 | this.resDir = new File(config.resFolderPath)
28 | this.manifestFile = new File(config.manifestFilePath)
29 | }
30 |
31 | // ====== 源代码中的部分 start =============================================
32 | /**
33 | * 替换 src 源代码目录中的资源名
34 | * @param file 源代码目录
35 | * @param set 当前module下所有资源名 set
36 | * @param java_regx 匹配正则
37 | */
38 | protected void replaceSrcDir(File file, Set set, java_regx) {
39 | if (file.exists()) {
40 | if (file.isDirectory()) {
41 | file.eachFile { it -> replaceSrcDir(it, set, java_regx) }
42 | } else {
43 | if (file.name.endsWith(".java") || file.name.endsWith(".kt")) { // only .java or .kt files
44 | handleSrcFile(file, set, java_regx)
45 | }
46 | }
47 | }
48 | }
49 |
50 | private void handleSrcFile(File file, Set set, regex) {
51 | String fileContent = file.getText() // every file is a text file
52 | StringBuffer sb = new StringBuffer() // result content
53 | Matcher matcher = fileContent =~ regex
54 | while (matcher.find()) {
55 | String oldResName = matcher.group(6) // the old res name
56 | if (set.contains(oldResName)) { // 本模块中包含的资源名,才替换
57 | String newResName = config.new_prefix + oldResName
58 | if (oldResName.startsWith(config.old_prefix)) { // 替换掉旧的前缀
59 | newResName = config.new_prefix + oldResName.substring(config.old_prefix.length())
60 | }
61 | matcher.appendReplacement(sb, "\$1$newResName") // 拼接 保留$1分组,替换$6分组
62 | }
63 | }
64 | // 修改了文件时,才写入文件
65 | if (sb.length() > 0) {
66 | matcher.appendTail(sb) // 添加结尾
67 | file.write(sb.toString()) // 写回文件
68 | }
69 | }
70 | // ====== 源代码中的部分 end =============================================
71 |
72 | // ====== 资源文件部分公用方法 start =====================
73 | // def xml_regx = ~/(@XXX\/)(w+)"/ xxx 表示各种资源,如:layout、drawable 等
74 | /**
75 | * 操作资源
76 | * @param file
77 | * @param set
78 | * @param regex
79 | * @param valuesType 是否是 values 类型资源(values-xx, values-en这种)
80 | * values 类型资源时,需要保留 $3 分组
81 | * @return
82 | */
83 | def handleResFile(File file, Set set, regex, valuesType = false) {
84 | boolean hasUpdate = false // 是否有修改
85 | StringBuilder sb = new StringBuilder() // 文件内容
86 | file.each { line ->
87 | Matcher matcher = line =~ regex
88 | StringBuffer tSb = new StringBuffer()
89 | while (matcher.find()) {
90 | String oldResName = matcher.group(2)
91 | if (set.contains(oldResName)) {
92 | String newResName = config.new_prefix + oldResName
93 | if (oldResName.startsWith(config.old_prefix)) {
94 | newResName = config.new_prefix + oldResName.substring(config.old_prefix.length())
95 | }
96 |
97 | if (valuesType) {
98 | matcher.appendReplacement(tSb, "\$1$newResName\$3") // 拼接 保留$1分组,替换组2,保留组3
99 | } else {
100 | matcher.appendReplacement(tSb, "\$1$newResName") // 拼接 保留$1分组,替换组2
101 | }
102 | }
103 | }
104 | if (tSb.length() > 0) { // 如果包含了,则重新赋值line,并拼接余下部分
105 | matcher.appendTail(tSb)
106 | hasUpdate = true
107 | line = tSb.toString()
108 | }
109 |
110 | sb.append(line).append("\r\n")
111 | }
112 |
113 | // 有修改了,才重新写入文件
114 | if (hasUpdate) {
115 | file.write(sb.toString())
116 | }
117 | }
118 | // ====== 资源文件部分公用方法 end =====================
119 |
120 | /**
121 | * res目录下的资源 - 替换名称
122 | * @param file
123 | * @param set
124 | * @param regx
125 | * @param dir_filter null no filter
126 | * @param valuesType 是否是 values 文件夹 类型(如:values,values-en)
127 | */
128 | protected def replaceResDir(File file, Set set, regx, dir_filter, valuesType = false) {
129 | File[] dirs = file.listFiles(dir_filter as FilenameFilter)
130 | dirs?.each { dir ->
131 | if (dir != null && dir.isDirectory()) {
132 | dir.eachFile { it ->
133 | if (it.name.endsWith(".xml")) { // 只在xml有引用
134 | handleResFile(it, set, regx, valuesType)
135 | }
136 | }
137 | }
138 | }
139 |
140 | // 清单文件 manifest file
141 | if (manifestFile != null) {
142 | handleResFile(manifestFile, set, regx)
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/folder/AnimReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.folder
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseFolderResReplace
6 |
7 | /**
8 | * anim
9 | */
10 | class AnimReplace extends BaseFolderResReplace {
11 |
12 | private def final DIR_FILTER = new Tools.DirNamePrefixFilter("anim")
13 | private def final RES_TYPE_NAME = "anim"
14 |
15 | AnimReplace(ResToolsConfiguration config) {
16 | super(config)
17 | }
18 |
19 | @Override
20 | String getResTypeName() {
21 | return RES_TYPE_NAME
22 | }
23 |
24 | @Override
25 | String getJavaRegex() {
26 | return "(R(\\s*?)\\.(\\s*?)anim(\\s*?)\\.(\\s*?))(\\w+)"
27 | }
28 |
29 | @Override
30 | String getXmlRegex() {
31 | return "(@anim/)(\\w+)"
32 | }
33 |
34 | @Override
35 | Set getResNameSet() {
36 | Set resNameSet = new HashSet<>()
37 | // 1.获取所有drawable开头的文件夹
38 | File[] dirs = resDir.listFiles(DIR_FILTER)
39 | // 2.获取drawable名字并存储
40 | dirs?.each { dir ->
41 | dir.eachFile { it ->
42 | String fileName = it.name.substring(0, it.name.lastIndexOf("."))
43 | resNameSet.add(fileName)
44 | }
45 | }
46 | return resNameSet
47 | }
48 |
49 | @Override
50 | void replaceSrc(Set resNameSet, Object java_regx) throws IOException {
51 | println("---------- $RES_TYPE_NAME ----- replace source folder start...")
52 | replaceSrcDir(srcDir, resNameSet, java_regx)
53 | println("---------- $RES_TYPE_NAME ----- replace source folder end")
54 | }
55 |
56 | @Override
57 | void replaceRes(Set resNameSet, Object xml_regx) throws IOException {
58 | // 1.替换文件内容
59 | println("---------- $RES_TYPE_NAME ----- replace res folder start...")
60 | replaceResDir(resDir, resNameSet, xml_regx, null)
61 | println("---------- $RES_TYPE_NAME ----- replace res folder end")
62 |
63 | // 2.修改文件名
64 | println("---------- $RES_TYPE_NAME ----- rename start...")
65 | renameFile(resDir, resNameSet, DIR_FILTER, RES_TYPE_NAME)
66 | println("---------- $RES_TYPE_NAME ----- rename end")
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/folder/ColorReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.folder
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseFolderResReplace
6 |
7 | /**
8 | * color
9 | */
10 | class ColorReplace extends BaseFolderResReplace {
11 |
12 | private def final DIR_FILTER = new Tools.DirNamePrefixFilter("color")
13 | private def final RES_TYPE_NAME = "color"
14 |
15 | ColorReplace(ResToolsConfiguration config) {
16 | super(config)
17 | }
18 |
19 | @Override
20 | String getResTypeName() {
21 | return RES_TYPE_NAME
22 | }
23 |
24 | @Override
25 | String getJavaRegex() {
26 | return "(R(\\s*?)\\.(\\s*?)color(\\s*?)\\.(\\s*?))(\\w+)"
27 | }
28 |
29 | @Override
30 | String getXmlRegex() {
31 | return "(@color/)(\\w+)"
32 | }
33 |
34 | @Override
35 | Set getResNameSet() {
36 | Set resNameSet = new HashSet<>()
37 | // 1.获取所有drawable开头的文件夹
38 | File[] dirs = resDir.listFiles(DIR_FILTER)
39 | // 2.获取drawable名字并存储
40 | dirs?.each { dir ->
41 | dir.eachFile { it ->
42 | String fileName = it.name.substring(0, it.name.lastIndexOf("."))
43 | resNameSet.add(fileName)
44 | }
45 | }
46 | return resNameSet
47 | }
48 |
49 | @Override
50 | void replaceSrc(Set resNameSet, Object java_regx) throws IOException {
51 | println("---------- $RES_TYPE_NAME ----- replace source folder start...")
52 | replaceSrcDir(srcDir, resNameSet, java_regx)
53 | println("---------- $RES_TYPE_NAME ----- replace source folder end")
54 | }
55 |
56 | @Override
57 | void replaceRes(Set resNameSet, Object xml_regx) throws IOException {
58 | // 1.替换文件内容
59 | println("---------- $RES_TYPE_NAME ----- replace res folder start...")
60 | replaceResDir(resDir, resNameSet, xml_regx, null)
61 | println("---------- $RES_TYPE_NAME ----- replace res folder end")
62 |
63 | // 2.修改文件名
64 | println("---------- $RES_TYPE_NAME ----- rename start...")
65 | renameFile(resDir, resNameSet, DIR_FILTER, RES_TYPE_NAME)
66 | println("---------- $RES_TYPE_NAME ----- rename end")
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/folder/DrawableReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.folder
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseFolderResReplace
6 |
7 | /**
8 | * drawable
9 | */
10 | class DrawableReplace extends BaseFolderResReplace {
11 |
12 | private def final static DIR_FILTER = new Tools.DirNamePrefixFilter("drawable")
13 | private def final static RES_TYPE_NAME = "drawable"
14 |
15 | DrawableReplace(ResToolsConfiguration config) {
16 | super(config)
17 | }
18 |
19 | @Override
20 | String getResTypeName() {
21 | return RES_TYPE_NAME
22 | }
23 |
24 | @Override
25 | String getJavaRegex() {
26 | return "(R(\\s*?)\\.(\\s*?)drawable(\\s*?)\\.(\\s*?))(\\w+)"
27 | }
28 |
29 | @Override
30 | String getXmlRegex() {
31 | return "(@drawable/)(\\w+)"
32 | }
33 |
34 | @Override
35 | Set getResNameSet() {
36 | Set drawableNameSet = new HashSet<>()
37 | // 1.获取所有drawable开头的文件夹
38 | File[] dirs = resDir.listFiles(DIR_FILTER)
39 | // 2.获取drawable名字并存储
40 | dirs?.each { dir ->
41 | dir.eachFile { it ->
42 | String fileName = it.name.substring(0, it.name.lastIndexOf("."))
43 | if (fileName.endsWith(".9")) { // 可能有.9
44 | fileName = fileName.substring(0, fileName.lastIndexOf("."))
45 | }
46 | drawableNameSet.add(fileName)
47 | }
48 | }
49 |
50 | return drawableNameSet
51 | }
52 |
53 | @Override
54 | void replaceSrc(Set resNameSet, Object java_regx) throws IOException {
55 | println("---------- $RES_TYPE_NAME ----- replace source folder start...")
56 | replaceSrcDir(srcDir, resNameSet, java_regx)
57 | println("---------- $RES_TYPE_NAME ----- replace source folder end")
58 | }
59 |
60 | @Override
61 | void replaceRes(Set resNameSet, Object xml_regx) throws IOException {
62 | // 1.替换文件内容
63 | println("---------- $RES_TYPE_NAME ----- replace res folder start...")
64 | replaceResDir(resDir, resNameSet, xml_regx, null)
65 | println("---------- $RES_TYPE_NAME ----- replace res folder end")
66 |
67 |
68 | // 2.修改文件名
69 | println("---------- $RES_TYPE_NAME ----- rename start...")
70 | renameFile(resDir, resNameSet, DIR_FILTER, RES_TYPE_NAME)
71 | println("---------- $RES_TYPE_NAME ----- rename end")
72 |
73 |
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/folder/LayoutReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.folder
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseFolderResReplace
6 |
7 | import java.util.regex.Matcher
8 |
9 |
10 | /**
11 | * layout 布局资源
12 | */
13 | public class LayoutReplace extends BaseFolderResReplace {
14 |
15 | private def final DIR_FILTER = new Tools.DirNamePrefixFilter("layout")
16 | private def final RES_TYPE_NAME = "layout"
17 |
18 | LayoutReplace(ResToolsConfiguration config) {
19 | super(config)
20 | }
21 |
22 | @Override
23 | String getResTypeName() {
24 | return RES_TYPE_NAME
25 | }
26 |
27 | @Override
28 | String getJavaRegex() {
29 | // group 6 为名字
30 | return "(R(\\s*?)\\.(\\s*?)layout(\\s*?)\\.(\\s*?))(\\w+)"
31 | }
32 |
33 | @Override
34 | String getXmlRegex() {
35 | // group 2为名字
36 | return "(@layout/)(\\w+)"
37 | }
38 |
39 | @Override
40 | Set getResNameSet() {
41 | Set layoutNameSet = new HashSet<>()
42 | // 1.获取所有layout开头的文件夹
43 | File[] layoutDirs = resDir.listFiles(DIR_FILTER)
44 | // 2.获取layout名字并存储
45 | layoutDirs?.each { layoutDir ->
46 | layoutDir.eachFile { it ->
47 | layoutNameSet.add(it.name.substring(0, it.name.lastIndexOf(".")))
48 | }
49 | }
50 | return layoutNameSet
51 | }
52 |
53 | @Override
54 | void replaceSrc(Set resNameSet, java_regx) throws IOException {
55 | println("---------- layout ----- replace source folder start...")
56 | replaceSrcDir(srcDir, resNameSet, java_regx)
57 |
58 | // 替换kt源代码文件 layout 文件
59 | replaceKtSrcFile(srcDir, resNameSet)
60 |
61 | println("---------- layout ----- replace source folder end")
62 | }
63 |
64 |
65 | @Override
66 | void replaceRes(Set resNameSet, xml_regx) throws IOException {
67 | println("---------- layout ----- replace res folder start...")
68 | // 1.替换文件内容,经验证,xml文件夹的小部分布局,可能引用到了layout文件,所以filter 传 null
69 | replaceResDir(resDir, resNameSet, xml_regx, null)
70 | println("---------- layout ----- replace res folder end")
71 |
72 | // 2.修改文件名
73 | println("---------- layout ----- rename start...")
74 | renameFile(resDir, resNameSet, DIR_FILTER, RES_TYPE_NAME)
75 | println("---------- layout ----- rename end")
76 | }
77 |
78 |
79 | /**
80 | * kt 文件特殊处理,layout 导入包时,需要重新替换,如:
81 | * import kotlinx.android.synthetic.main.activity_main.*
82 | * 替换成:
83 | * import kotlinx.android.synthetic.main.new_prefix_activity_main.*
84 | * @param file
85 | * @param set
86 | */
87 | private void replaceKtSrcFile(File file, Set set) {
88 | if (file.exists()) {
89 | if (file.isDirectory()) {
90 | file.eachFile { it -> replaceKtSrcFile(it, set) }
91 | } else {
92 | if (file.name.endsWith(".kt")) { // kt
93 | handleKtSrcFileLayout(file, set)
94 | }
95 | }
96 | }
97 | }
98 |
99 | private void handleKtSrcFileLayout(file, set) {
100 | def regex = "(synthetic.main\\.)(\\w+)(\\.)"
101 | String fileContent = file.getText() // every file is a text file
102 | StringBuffer sb = new StringBuffer() // result content
103 | Matcher matcher = fileContent =~ regex
104 | while (matcher.find()) {
105 | String oldResName = matcher.group(2) // the old res name
106 | if (set.contains(oldResName)) { // 本模块中包含的资源名,才替换
107 | String newResName = config.new_prefix + oldResName
108 | if (oldResName.startsWith(config.old_prefix)) { // 替换掉旧的前缀
109 | newResName = config.new_prefix + oldResName.substring(config.old_prefix.length())
110 | }
111 | matcher.appendReplacement(sb, "\$1$newResName\$3") // 拼接 保留$1$3分组,替换$2分组
112 | }
113 | }
114 | // 修改了文件时,才写入文件
115 | if (sb.length() > 0) {
116 | matcher.appendTail(sb) // 添加结尾
117 | file.write(sb.toString()) // 写回文件
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/folder/MenuReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.folder
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseFolderResReplace
6 |
7 |
8 | /**
9 | * menu
10 | * @menu/xxx 暂时没有,所以res先不处理
11 | */
12 | class MenuReplace extends BaseFolderResReplace {
13 |
14 | private def final DIR_FILTER = new Tools.DirNamePrefixFilter("menu")
15 | private def final RES_TYPE_NAME = "menu"
16 |
17 | MenuReplace(ResToolsConfiguration config) {
18 | super(config)
19 | }
20 |
21 | @Override
22 | String getResTypeName() {
23 | return RES_TYPE_NAME
24 | }
25 |
26 | @Override
27 | String getJavaRegex() {
28 | return "(R(\\s*?)\\.(\\s*?)menu(\\s*?)\\.(\\s*?))(\\w+)"
29 | }
30 |
31 | @Override
32 | String getXmlRegex() {
33 | return "(@menu/)(\\w+)"
34 | }
35 |
36 | @Override
37 | Set getResNameSet() {
38 | Set resNameSet = new HashSet<>()
39 | // 1.获取所有drawable开头的文件夹
40 | File[] dirs = resDir.listFiles(DIR_FILTER)
41 | // 2.获取drawable名字并存储
42 | dirs?.each { dir ->
43 | dir.eachFile { it ->
44 | String fileName = it.name.substring(0, it.name.lastIndexOf("."))
45 | resNameSet.add(fileName)
46 | }
47 | }
48 | return resNameSet
49 | }
50 |
51 | @Override
52 | void replaceSrc(Set resNameSet, Object java_regx) throws IOException {
53 | println("---------- $RES_TYPE_NAME ----- replace source folder start...")
54 | replaceSrcDir(srcDir, resNameSet, java_regx)
55 | println("---------- $RES_TYPE_NAME ----- replace source folder end")
56 | }
57 |
58 | @Override
59 | void replaceRes(Set resNameSet, Object xml_regx) throws IOException {
60 | println("---------- $RES_TYPE_NAME ----- $RES_TYPE_NAME not used in the res folder now, so replace res not implemented.")
61 | // 1.替换文件内容
62 |
63 | // 2.修改文件名
64 | println("---------- $RES_TYPE_NAME ----- rename start...")
65 | renameFile(resDir,resNameSet, DIR_FILTER, RES_TYPE_NAME)
66 | println("---------- $RES_TYPE_NAME ----- rename end")
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/folder/MipmapReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.folder
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseFolderResReplace
6 |
7 |
8 | /**
9 | * mipmap
10 | */
11 | class MipmapReplace extends BaseFolderResReplace {
12 |
13 | private def final static DIR_FILTER = new Tools.DirNamePrefixFilter("mipmap")
14 | private def final static String RES_TYPE_NAME = "mipmap"
15 |
16 | MipmapReplace(ResToolsConfiguration config) {
17 | super(config)
18 | }
19 | @Override
20 | String getResTypeName() {
21 | return RES_TYPE_NAME
22 | }
23 |
24 | @Override
25 | String getJavaRegex() {
26 | return "(R(\\s*?)\\.(\\s*?)mipmap(\\s*?)\\.(\\s*?))(\\w+)"
27 | }
28 |
29 | @Override
30 | String getXmlRegex() {
31 | return "(@mipmap/)(\\w+)"
32 | }
33 |
34 | @Override
35 | Set getResNameSet() {
36 | Set drawableNameSet = new HashSet<>()
37 | // 1.获取所有drawable开头的文件夹
38 | File[] dirs = resDir.listFiles(DIR_FILTER)
39 | // 2.获取drawable名字并存储
40 | dirs?.each { dir ->
41 | dir.eachFile { it ->
42 | String fileName = it.name.substring(0, it.name.lastIndexOf("."))
43 | if (fileName.endsWith(".9")) { // 可能有.9
44 | fileName = fileName.substring(0, fileName.lastIndexOf("."))
45 | }
46 | drawableNameSet.add(fileName)
47 | }
48 | }
49 |
50 | return drawableNameSet
51 | }
52 |
53 | @Override
54 | void replaceSrc(Set resNameSet, Object java_regx) throws IOException {
55 | println("---------- $RES_TYPE_NAME ----- replace source folder start...")
56 | replaceSrcDir(srcDir, resNameSet, java_regx)
57 | println("---------- $RES_TYPE_NAME ----- replace source folder end")
58 | }
59 |
60 | @Override
61 | void replaceRes(Set resNameSet, Object xml_regx) throws IOException {
62 | // 1.替换文件内容
63 | println("---------- $RES_TYPE_NAME ----- replace res folder start...")
64 | replaceResDir(resDir, resNameSet, xml_regx, null)
65 | println("---------- $RES_TYPE_NAME ----- replace res folder end")
66 |
67 | // 2.修改文件名
68 | println("---------- $RES_TYPE_NAME ----- rename start...")
69 | renameFile(resDir,resNameSet, DIR_FILTER, RES_TYPE_NAME)
70 | println("---------- $RES_TYPE_NAME ----- rename end")
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/folder/RawReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.folder
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseFolderResReplace
6 |
7 |
8 | /**
9 | * raw
10 | * @raw / x x x 暂时没有,所以res先不处理
11 | */
12 | class RawReplace extends BaseFolderResReplace {
13 |
14 | private def final DIR_FILTER = new Tools.DirNamePrefixFilter("raw")
15 | private def final RES_TYPE_NAME = "raw"
16 |
17 | RawReplace(ResToolsConfiguration config) {
18 | super(config)
19 | }
20 |
21 | @Override
22 | String getResTypeName() {
23 | return RES_TYPE_NAME
24 | }
25 |
26 | @Override
27 | String getJavaRegex() {
28 | return "(R(\\s*?)\\.(\\s*?)raw(\\s*?)\\.(\\s*?))(\\w+)"
29 | }
30 |
31 | @Override
32 | String getXmlRegex() {
33 | return "(@raw/)(\\w+)"
34 | }
35 |
36 | @Override
37 | Set getResNameSet() {
38 | Set resNameSet = new HashSet<>()
39 | // 1.获取所有drawable开头的文件夹
40 | File[] dirs = resDir.listFiles(DIR_FILTER)
41 | // 2.获取drawable名字并存储
42 | dirs?.each { dir ->
43 | dir.eachFile { it ->
44 | // may be no file suffixes
45 | if(it.name.lastIndexOf('.') > -1) {
46 | String fileName = it.name.substring(0, it.name.lastIndexOf("."))
47 | resNameSet.add(fileName)
48 | } else {
49 | resNameSet.add(it.name)
50 | }
51 | }
52 | }
53 | return resNameSet
54 | }
55 |
56 | @Override
57 | void replaceSrc(Set resNameSet, Object java_regx) throws IOException {
58 | println("---------- $RES_TYPE_NAME ----- replace source folder start...")
59 | replaceSrcDir(srcDir, resNameSet, java_regx)
60 | println("---------- $RES_TYPE_NAME ----- replace source folder end")
61 | }
62 |
63 | @Override
64 | void replaceRes(Set resNameSet, Object xml_regx) throws IOException {
65 | // 1.替换文件内容
66 | println("---------- $RES_TYPE_NAME ----- $RES_TYPE_NAME not used in the res folder now, so replace res not implemented.")
67 |
68 |
69 | // 2.修改文件名
70 | println("---------- $RES_TYPE_NAME ----- rename start...")
71 | renameFile(resDir, resNameSet, DIR_FILTER, RES_TYPE_NAME)
72 | println("---------- $RES_TYPE_NAME ----- rename end")
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/folder/XmlReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.folder
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseFolderResReplace
6 |
7 | /**
8 | * xml
9 | * @xml / x x x 暂时没有,所以res文件夹先不处理
10 | */
11 | class XmlReplace extends BaseFolderResReplace {
12 |
13 | private def final DIR_FILTER = new Tools.DirNamePrefixFilter("xml")
14 | private def final RES_TYPE_NAME = "xml"
15 |
16 | XmlReplace(ResToolsConfiguration config) {
17 | super(config)
18 | }
19 | @Override
20 | String getResTypeName() {
21 | return RES_TYPE_NAME
22 | }
23 |
24 | @Override
25 | String getJavaRegex() {
26 | return "(R(\\s*?)\\.(\\s*?)xml(\\s*?)\\.(\\s*?))(\\w+)"
27 | }
28 |
29 | @Override
30 | String getXmlRegex() {
31 | return "(@xml/)(\\w+)"
32 | }
33 |
34 | @Override
35 | Set getResNameSet() {
36 | Set resNameSet = new HashSet<>()
37 | // 1.获取所有drawable开头的文件夹
38 | File[] dirs = resDir.listFiles(DIR_FILTER)
39 | // 2.获取drawable名字并存储
40 | dirs?.each { dir ->
41 | dir.eachFile { it ->
42 | String fileName = it.name.substring(0, it.name.lastIndexOf("."))
43 | resNameSet.add(fileName)
44 | }
45 | }
46 | return resNameSet
47 | }
48 |
49 | @Override
50 | void replaceSrc(Set resNameSet, Object java_regx) throws IOException {
51 | println("---------- $RES_TYPE_NAME ----- replace source folder start...")
52 | replaceSrcDir(srcDir, resNameSet, java_regx)
53 | println("---------- $RES_TYPE_NAME ----- replace source folder end")
54 | }
55 |
56 | @Override
57 | void replaceRes(Set resNameSet, Object xml_regx) throws IOException {
58 | // 1.替换文件内容
59 | println("---------- $RES_TYPE_NAME ----- replace res folder start...")
60 | replaceResDir(resDir, resNameSet, xml_regx, DIR_FILTER) // only replace xml folder
61 | println("---------- $RES_TYPE_NAME ----- replace res folder end")
62 |
63 |
64 | // 2.修改文件名
65 | println("---------- $RES_TYPE_NAME ----- rename start...")
66 | renameFile(resDir, resNameSet, DIR_FILTER, RES_TYPE_NAME)
67 | println("---------- $RES_TYPE_NAME ----- rename end")
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/ResTools/src/main/groovy/com/github/better/restools/values/ValuesReplace.groovy:
--------------------------------------------------------------------------------
1 | package com.github.better.restools.values
2 |
3 | import com.github.better.restools.ResToolsConfiguration
4 | import com.github.better.restools.Tools
5 | import com.github.better.restools.base.BaseReplace
6 |
7 | import java.util.regex.Matcher
8 |
9 | /**
10 | - string
11 | - string_arrays
12 | - color
13 | - dimens
14 | - bool
15 | - integer
16 | - attr not support
17 | - style not support well need repaired
18 | */
19 | class ValuesReplace extends BaseReplace {
20 |
21 | private def final DIR_FILTER = new Tools.DirNamePrefixFilter("values")
22 | public static final Set ALL_VALUES_TYPES
23 |
24 | static {
25 | ALL_VALUES_TYPES = new LinkedHashSet<>()
26 | ALL_VALUES_TYPES.add(ValuesType.string)
27 | ALL_VALUES_TYPES.add(ValuesType.string_arrays)
28 | ALL_VALUES_TYPES.add(ValuesType.color)
29 | ALL_VALUES_TYPES.add(ValuesType.bool)
30 | ALL_VALUES_TYPES.add(ValuesType.integer)
31 | ALL_VALUES_TYPES.add(ValuesType.dimens)
32 |
33 | // not support now
34 | ALL_VALUES_TYPES.add(ValuesType.attr)
35 | ALL_VALUES_TYPES.add(ValuesType.style)
36 | }
37 |
38 | public ValuesReplace(ResToolsConfiguration config) {
39 | super(config)
40 | }
41 |
42 | /**
43 | * values 类型
44 | */
45 | public static enum ValuesType {
46 | /*
47 | appName
50 | appName
51 | */
52 |
53 | string("()",
54 | "(R(\\s*?)\\.(\\s*?)string(\\s*?)\\.(\\s*?))(\\w+)",
55 | "(@string/)(\\w+)"
56 | ),
57 |
58 | string_arrays("()",
59 | "(R(\\s*?)\\.(\\s*?)array(\\s*?)\\.(\\s*?))(\\w+)",
60 | "()"
61 | ),
62 |
63 | color("()",
64 | "(R(\\s*?)\\.(\\s*?)color(\\s*?)\\.(\\s*?))(\\w+)",
65 | "(@color/)(\\w+)"
66 | ),
67 |
68 | dimens("()",
69 | "(R(\\s*?)\\.(\\s*?)dimen(\\s*?)\\.(\\s*?))(\\w+)",
70 | "(@dimen/)(\\w+)"
71 | ),
72 |
73 | bool("()",
74 | "(R(\\s*?)\\.(\\s*?)bool(\\s*?)\\.(\\s*?))(\\w+)",
75 | "(@bool/)(\\w+)"
76 | ),
77 |
78 | integer("()",
79 | "(R(\\s*?)\\.(\\s*?)integer(\\s*?)\\.(\\s*?))(\\w+)",
80 | "(@integer/)(\\w+)"
81 | ),
82 |
83 | attr("",
84 | "",
85 | ""
86 | ),
87 |
88 | style("(
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/github/better/restools/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.github.better.restools
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.11'
5 | repositories {
6 | google()
7 | jcenter()
8 | mavenLocal()
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.1.3'
12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | classpath 'com.github.better.restools:ResTools:1.0.1'
17 |
18 | classpath 'com.novoda:bintray-release:0.8.0'//添加
19 |
20 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
21 | }
22 | }
23 |
24 | allprojects {
25 | repositories {
26 | google()
27 | jcenter()
28 | }
29 |
30 | tasks.withType(Javadoc) {
31 | options.addStringOption('Xdoclint:none', '-quiet')
32 | options.addStringOption('encoding', 'UTF-8')
33 | }
34 | }
35 |
36 | task clean(type: Delete) {
37 | delete rootProject.buildDir
38 | }
39 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':ResTools', ':ResourceTools'
2 |
--------------------------------------------------------------------------------