This repository has been archived by the owner on Apr 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
aar-to-eclipse.py
executable file
·172 lines (135 loc) · 4.82 KB
/
aar-to-eclipse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env python3
#
# Copyright 2015 HiHex Ltd.
#
# Licensed 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 argparse
import pathlib
import zipfile
import subprocess
import shutil
import sys
import uuid
import xml.etree.ElementTree as xml
BUILD_XML = '''\
<?xml version="1.0" encoding="UTF-8"?>
<project name="." default="help">
<property file="local.properties"/>
<property file="ant.properties"/>
<property environment="env"/>
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME"/>
</condition>
<loadproperties srcFile="project.properties"/>
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update lib-project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<import file="custom_rules.xml" optional="true"/>
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml"/>
</project>
'''
PROJECT_PROPERTIES_TEMPLATE = '''\
proguard.config=${{sdk.dir}}/tools/proguard/proguard-android.txt:proguard.txt
android.library=true
target=android-{}
'''
def create_arg_parser():
parser = argparse.ArgumentParser(description='''
Convert *.aar to Eclipse library project
''')
parser.add_argument('-o', '--output', help='''
the directory to contain the Eclipse library project; by default it
will write to a directory having the same name as the *.aar file
''')
parser.add_argument('-f', '--force', action='store_true', help='''
force rewriting the output directory even if it already exists
''')
parser.add_argument('aar', help='''
the input *.aar file
''')
return parser
def merge_libs(output_dir):
'''Move all libraries back into the libs/ directory.'''
libs_dir = output_dir / 'libs'
try:
libs_dir.mkdir()
except FileExistsError:
pass
try:
jni_dir = output_dir / 'jni'
for child in jni_dir.iterdir():
target_path = libs_dir / child.relative_to(jni_dir)
child.rename(target_path)
jni_dir.rmdir()
except FileNotFoundError:
pass
target_path = libs_dir / 'classes.jar'
source_path = output_dir / 'classes.jar'
while True:
if target_path.exists():
target_path = libs_dir / 'classes.{}.jar'.format(uuid.uuid4())
else:
source_path.rename(target_path)
break
def write_eclipse_specific_files(output_dir):
# proguard.txt (required even if we don't run proguard)
(output_dir / 'proguard.txt').touch()
# project.properties
tree = xml.parse(str(output_dir / 'AndroidManifest.xml'))
target_sdk = tree.find('uses-sdk').get('{http://schemas.android.com/apk/res/android}targetSdkVersion')
with (output_dir / 'project.properties').open('w') as f:
f.write(PROJECT_PROPERTIES_TEMPLATE.format(target_sdk))
# build.xml
with (output_dir / 'build.xml').open('w') as f:
f.write(BUILD_XML)
(output_dir / 'src').touch()
def convert(aar, output_dir):
aar.extractall(str(output_dir))
merge_libs(output_dir)
write_eclipse_specific_files(output_dir)
try:
(output_dir / 'aapt/AndroidManifest.xml').unlink()
except FileNotFoundError:
pass
try:
subprocess.call(['android', 'update', 'lib-project', '-p', str(output_dir)])
except FileNotFoundError:
print('Warning: Cannot create "local.properties".',
'Please perform `android update lib-project` manually.', file=sys.stderr)
def main():
parser = create_arg_parser()
ns = parser.parse_args()
if ns.output is not None:
output_dir = pathlib.Path(ns.output)
else:
output_dir = pathlib.Path(ns.aar).with_suffix('')
try:
output_dir.mkdir()
except FileExistsError:
try:
output_dir.rmdir()
except OSError:
if ns.force:
shutil.rmtree(str(output_dir))
else:
print('Output folder "{}" already exists.'.format(output_dir),
'Please remove it or choose another name.', file=sys.stderr)
return 1
with zipfile.ZipFile(ns.aar) as aar:
convert(aar, output_dir)
print('Done.', file=sys.stderr)
return 0
if __name__ == '__main__':
sys.exit(main())