squash_java 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE.txt ADDED
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ Squash Java Deobfuscation Library
2
+ =================================
3
+
4
+ This gem serves three purposes:
5
+
6
+ * to upload yGuard obfuscation data to Squash,
7
+ * to map class names to their file paths, and upload that data to Squash, and
8
+ * to notify Squash of new releases of Java software (internally or externally).
9
+
10
+ This gem installs a `deobfuscate` binary that converts a renamelog.xml file into
11
+ a format usable for Squash, locates the files in which classes are defined, and
12
+ then uploads that data to the Squash host. It also installs a `squash_release`
13
+ binary that notifies Squash of the release.
14
+
15
+ Documentation
16
+ -------------
17
+
18
+ Comprehensive documentation is written in YARD- and Markdown-formatted comments
19
+ throughout the source. To view this documentation as an HTML site, run
20
+ `rake doc`.
21
+
22
+ For an overview of the various components of Squash, see the website
23
+ documentation at https://github.com/SquareSquash/web.
24
+
25
+ Compatibility
26
+ -------------
27
+
28
+ This library is compatible with Ruby 1.8.6 and later, including Ruby Enterprise
29
+ Edition.
30
+
31
+ Requirements
32
+ ------------
33
+
34
+ This gem requires the `json` gem (http://rubygems.org/gems/json). You can use
35
+ any JSON gem that conforms to the typical standard
36
+ (`require 'json'; object.to_json`).
37
+
38
+ Usage
39
+ -----
40
+
41
+ ### Uploading Obfuscation and Class Path Data
42
+
43
+ This gem installs a command-line binary named `deobfuscate`. It is called in the
44
+ following format:
45
+
46
+ ````
47
+ deobfuscate [options] <API key> <environment> <build number> <renamelog file>
48
+ ````
49
+
50
+ Example: `deobfuscate --no-ssl-verification a9232f94-6c2d-45ae-8f9e-9add5bd7ff35 production 103 /path/to/renamelog.xml`
51
+
52
+ This binary is intended to be used as part of your release process. It will
53
+ first parse the renamelog file and generate an internal representation of your
54
+ program's namespace, along with all obfuscated aliases. Then it will attempt to
55
+ map class names to the files in which the classes are defined. In order for this
56
+ to work, your classes should be organized in folder structures according to
57
+ their package names. For example, the source of the class `com.foo.bar.Baz`
58
+ should be found in a "com/foo/bar/Baz.java" file path somewhere in your project.
59
+
60
+ By default this program assumes it's being run from the project root, but you
61
+ can also specify the root with the `--project-dir` switch. For documentation on
62
+ `deobfuscate`'s command-line options, run `deobfuscate --help.`
63
+
64
+ ### Release Notification
65
+
66
+ This gem installs a command-line binary named `squash_release`. It is called in
67
+ the following format:
68
+
69
+ ````
70
+ squash_release [options] <API key> <environment> <build number>
71
+ ````
72
+
73
+ Example: `squash_release a9232f94-6c2d-45ae-8f9e-9add5bd7ff35 production 103 `
74
+
75
+ This binary is intended to be used as part of your release process, similar to
76
+ `deobfuscate` (see above). Like `deobfuscate`, sensible defaults are provided
77
+ for all command line switches.
78
+
79
+ For documentation on `squash_release`'s command-line options, run
80
+ `squash_release --help`.
81
+
82
+ Data Transmission
83
+ -----------------
84
+
85
+ Deobfuscation and release data is transmitted to Squash using JSON-over-HTTPS. A
86
+ default API endpoint is pre-configured, though you can always set your own (see
87
+ `deobfuscate --help` or `squash_release --help`).
88
+
89
+ By default, `Net::HTTP` is used to transmit errors to the API server. If you
90
+ would prefer to use your own HTTP library, see the `squash_uploader` gem.
91
+
92
+ Use as a Library
93
+ ----------------
94
+
95
+ In addition to using the rename map with Squash, you can also use the gem as
96
+ a library, to perform deobfuscation for your own purposes (even unrelated to
97
+ Squash). See the {Squash::Java::Namespace} class documentation for more
98
+ information.
data/bin/deobfuscate ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright 2012 Square Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'optparse'
18
+ require 'base64'
19
+ require 'zlib'
20
+ require 'yaml'
21
+
22
+ require 'rubygems'
23
+ require 'squash/uploader'
24
+ require 'squash/java'
25
+
26
+ def git_revision(dir)
27
+ head = File.read(File.join(dir, '.git', 'HEAD')).chomp
28
+ if head =~ /^ref: (.+)$/
29
+ File.read(File.join(dir, '.git', $1)).chomp
30
+ else
31
+ raise "Couldn't determine current revision from #{head.inspect}"
32
+ end
33
+ end
34
+
35
+ project_dir = Dir.getwd
36
+ revision = nil
37
+ options = {}
38
+
39
+ parser = OptionParser.new do |parser|
40
+ parser.banner = "Usage: deobfuscate [options] YOUR_SQUASH_HOST YOUR_API_KEY ENVIRONMENT_NAME BUILD_NUMBER /path/to/renamelog_or_mapping"
41
+ parser.on('-o', '--open-timeout N', Integer, "HTTP connection open timeout") { |ot| options[:open_timeout] = ot }
42
+ parser.on('-r', '--read-timeout N', Integer, "HTTP connection data received timeout") { |rt| options[:read_timeout] = rt }
43
+ parser.on('-k', '--[no-]skip-verification', "Do not perform SSL peer verification") { |sv| options[:skip_verification] = sv }
44
+
45
+ parser.on('-p', '--project-dir F', "Specify a custom project directory (default current directory)") { |pd| project_dir = pd }
46
+ parser.on('-r', '--revision R', "Specify a code revision that was deployed (default current revision)") { |r| revision = r }
47
+
48
+ parser.on('-h', '--help', "Show this message") { puts parser; exit }
49
+ parser.on('--version', "Display version number of this program") { puts "1.0.0"; exit }
50
+ end
51
+ parser.parse!(ARGV)
52
+
53
+ if ARGV.size != 5
54
+ puts parser
55
+ exit 1
56
+ end
57
+
58
+ host = ARGV.shift
59
+ api_key = ARGV.shift
60
+ environment = ARGV.shift
61
+ build = ARGV.shift
62
+ file = ARGV.shift
63
+ revision = revision || git_revision(project_dir)
64
+
65
+ namespace = Squash::Java::RenameLog.new(file).parse
66
+ namespace.find_files project_dir
67
+
68
+ Squash::Uploader.new(host, options).transmit '/api/1.0/deobfuscation.json',
69
+ {
70
+ 'api_key' => api_key,
71
+ 'environment' => environment,
72
+ 'build' => build,
73
+ 'namespace' => Base64.encode64(Zlib::Deflate.deflate(namespace.to_yaml))
74
+ }
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright 2012 Square Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'optparse'
18
+ require 'rubygems'
19
+ require 'squash/uploader'
20
+
21
+ def git_revision(dir)
22
+ head = File.read(File.join(dir, '.git', 'HEAD')).chomp
23
+ if head =~ /^ref: (.+)$/
24
+ File.read(File.join(dir, '.git', $1)).chomp
25
+ else
26
+ raise "Couldn't determine current revision from #{head.inspect}"
27
+ end
28
+ end
29
+
30
+ project_dir = Dir.getwd
31
+ revision = nil
32
+ options = {}
33
+
34
+ parser = OptionParser.new do |parser|
35
+ parser.banner = "Usage: squash_release [options] YOUR_SQUASH_HOST YOUR_API_KEY ENVIRONMENT BUILD_NUMBER"
36
+ parser.on('-o', '--open-timeout N', Integer, "HTTP connection open timeout") { |ot| options[:open_timeout] = ot }
37
+ parser.on('-r', '--read-timeout N', Integer, "HTTP connection data received timeout") { |rt| options[:read_timeout] = rt }
38
+ parser.on('-k', '--[no-]skip-verification', "Do not perform SSL peer verification") { |sv| options[:skip_verification] = sv }
39
+
40
+ parser.on('-p', '--project-dir F', "Specify a custom project directory (default current directory)") { |pd| project_dir = pd }
41
+ parser.on('-r', '--revision R', "Specify a code revision that was deployed (default current revision)") { |r| revision = r }
42
+
43
+ parser.on('-h', '--help', "Show this message") { puts parser; exit }
44
+ parser.on('--version', "Display version number of this program") { puts "1.0.0"; exit }
45
+ end
46
+ parser.parse!(ARGV)
47
+
48
+ if ARGV.size != 4
49
+ puts parser
50
+ exit 1
51
+ end
52
+
53
+ host = ARGV.shift
54
+ api_key = ARGV.shift
55
+ environment = ARGV.shift
56
+ build = ARGV.shift
57
+ revision = revision || git_revision(project_dir)
58
+
59
+ Squash::Uploader.new(host, options).transmit '/api/1.0/deploy.json',
60
+ {
61
+ 'project' => {'api_key' => api_key},
62
+ 'environment' => {'name' => environment},
63
+ 'deploy' => {
64
+ 'deployed_at' => Time.now,
65
+ 'revision' => revision,
66
+ 'build' => build
67
+ }
68
+ }
@@ -0,0 +1,553 @@
1
+ # Copyright 2012 Square Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'set'
16
+ require 'find'
17
+
18
+
19
+ # A Ruby representation of the packages, classes, methods, and fields of a
20
+ # Java project, with their full and obfuscated names. The {RenameLog} class
21
+ # loads a Namespace from a yGuard or ProGuard rename log file.
22
+ #
23
+ # **Note:** Some of the finder methods of this class and its enclosed classes
24
+ # are find-or-create-type methods. Read the method documentation for each
25
+ # method carefully.
26
+ #
27
+ # **Another note:** A distinction is made between _full_ and _partial_ names
28
+ # (e.g., "MyClass" vs. "com.mycompany.MyClass"), and _cleartext_ and
29
+ # _obfuscated_ names (e.g., "com.mycompany.MyClass" vs. "com.A.B"). Note that
30
+ # there are four possible combinations of these states. Method docs will state
31
+ # what naming format is expected for each parameter.
32
+
33
+ class Squash::Java::Namespace
34
+ # @private
35
+ METHOD_REGEX = /^([a-z0-9_.$\[\]]+) ([a-z0-9_$]+)\(([a-z$0-9_.\[\] ,]*)\)/i
36
+
37
+ # Creates a new empty Namespace.
38
+
39
+ def initialize
40
+ @package_roots = Set.new
41
+ end
42
+
43
+ # @overload find_files(root)
44
+ # Attempts to locate the paths to the {Squash::Java::Class Classes} defined
45
+ # in this Namespace. Classes must be defined in files named after the class,
46
+ # organized into folders structured after the classes' packages. For
47
+ # example, the source of the `com.foo.bar.Baz` class should be defined in a
48
+ # file located at "com/foo/bar/Baz.java", somewhere inside your project
49
+ # root. This is a "best guess" attempt and will not work every time.
50
+ #
51
+ # Once this method is complete, any Class objects under this namespace that
52
+ # were successfully matched will have their {Squash::Java::Class#path path}
53
+ # attributes set.
54
+ #
55
+ # @param [String] root The project root. All source directories must be
56
+ # under this root.
57
+
58
+ def find_files(root, package_or_class=nil)
59
+ case package_or_class
60
+ when nil
61
+ root.sub! /\/$/, ''
62
+ @package_roots.each { |pkg| find_files root, pkg }
63
+ when Squash::Java::Package
64
+ package_or_class.classes.each { |cl| find_files root, cl }
65
+ package_or_class.children.each { |pkg| find_files root, pkg }
66
+ when Squash::Java::Class
67
+ class_subpath = package_or_class.subpath
68
+ Find.find(root) do |project_path|
69
+ if project_path[0, root.length + 2] == root + '/.'
70
+ Find.prune
71
+ next
72
+ end
73
+ if project_path[-class_subpath.length, class_subpath.length] == class_subpath
74
+ package_or_class.path = project_path.sub(/^#{Regexp.escape root}\//, '')
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ # Returns the path to a {Squash::Java::Class Class}'s source .java file,
81
+ # relative to the project root, if a) the class exists in the namespace, and
82
+ # b) the class has a known path.
83
+ #
84
+ # @param [String] klass The full class name (parts of which can be
85
+ # obfuscated), e.g., "com.foo.A.Baz".
86
+ # @return [String, nil] The path to the class's source file, if known.
87
+ # @see #find_files
88
+
89
+ def path_for_class(klass)
90
+ cl = obfuscated_class(klass)
91
+ cl ? cl.path : nil
92
+ end
93
+
94
+ # Associates a full package name with an obfuscated name.
95
+ #
96
+ # @param [String] name The full package name (e.g., "com.foo.bar").
97
+ # @param [String] obfuscation The obfuscated name for just the last segment of
98
+ # the full name (e.g., "A").
99
+ # @return [Squash::Java::Package] The newly created package object.
100
+
101
+ def add_package_alias(name, obfuscation)
102
+ pkg = package(name)
103
+ pkg.obfuscation = obfuscation
104
+ return pkg
105
+ end
106
+
107
+ # Associates a full class name with an obfuscated name.
108
+ #
109
+ # @param [String] name The full class name (e.g., "com.foo.bar.Baz").
110
+ # @param [String] obfuscation The obfuscated name for just the last segment of
111
+ # the full name (e.g., "A").
112
+ # @return [Squash::Java::Class] The newly created class object.
113
+
114
+ def add_class_alias(name, obfuscation)
115
+ cl = klass(name)
116
+ cl.obfuscation = obfuscation
117
+ return cl
118
+ end
119
+
120
+ # Associates a method name with an obfuscated alias.
121
+ #
122
+ # @param [String, Squash::Java::Class] class_or_name A full class name (e.g.,
123
+ # "com.foo.bar.Baz"), or a class object.
124
+ # @param [String] method_name A method name, with return value and argument
125
+ # types (e.g., "com.foo.Type1 methodName(com.foo.Type2, int[])").
126
+ # @return [Squash::Java::Method] The newly created method object.
127
+
128
+ def add_method_alias(class_or_name, method_name, obfuscation)
129
+ cl = (class_or_name.kind_of?(Squash::Java::Class) ? class_or_name : klass(class_or_name))
130
+ meth = method(cl, method_name)
131
+ meth.obfuscation = obfuscation
132
+ return meth
133
+ end
134
+
135
+ # **Finds or creates** a package by its full name.
136
+ #
137
+ # @param [String] identifier A full package name (e.g., "com.foo.bar").
138
+ # @return [Squash::Java::Package] The package with that name.
139
+
140
+ def package(identifier)
141
+ parts = identifier.split('.')
142
+ root_name = parts.shift
143
+ root = @package_roots.detect { |pkg| pkg.name == root_name } || begin
144
+ pkg = Squash::Java::Package.new(root_name)
145
+ @package_roots << pkg
146
+ pkg
147
+ end
148
+ if parts.empty?
149
+ root
150
+ else
151
+ root.find_or_create(parts.join('.'))
152
+ end
153
+ end
154
+
155
+ alias klass package
156
+
157
+ # **Finds** a package by its obfuscated (or partially obfuscated) full name.
158
+ # (Technically it also works as a **find-only** variant of {#package} since
159
+ # all, some, or none of the name need be obfuscated.)
160
+ #
161
+ # @param [String] identifier An obfuscated full package name (e.g.,
162
+ # "com.foo.A").
163
+ # @return [Squash::Java::Package, nil] The package with that obfuscated name.
164
+
165
+ def obfuscated_package(identifier)
166
+ parts = identifier.split('.')
167
+ root_name = parts.shift
168
+ root = @package_roots.detect { |pkg| pkg.name == root_name }
169
+ if parts.empty?
170
+ root
171
+ else
172
+ root ? root.find_obfuscated(parts.join('.')) : nil
173
+ end
174
+ end
175
+
176
+ # **Finds** a class by its obfuscated (or partially obfuscated) full name.
177
+ # (Technically it also works as a **find-only** variant of {#klass} since all
178
+ # some, or none of the name need be obfuscated.)
179
+ #
180
+ # @param [String] identifier An obfuscated full class name (e.g.,
181
+ # "com.foo.A.B").
182
+ # @return [Squash::Java::Class, nil] The class with that obfuscated name.
183
+
184
+ def obfuscated_class(identifier)
185
+ parts = identifier.split('.')
186
+ class_name = parts.pop
187
+ pkg = obfuscated_package(parts.join('.'))
188
+ return nil unless pkg
189
+
190
+ pkg.classes.detect { |cl| cl.obfuscation == class_name || cl.name == class_name }
191
+ end
192
+
193
+ # **Finds or creates** a primitive or class type by its name.
194
+ #
195
+ # @param [String] name The type name (e.g., "int" or "FooClass").
196
+ # @return [Squash::Java::Type] The type object.
197
+
198
+ def type(name)
199
+ Squash::Java::PRIMITIVES.detect { |prim| prim.name == name } || klass(name)
200
+ end
201
+
202
+ # **Finds** a class or primitive type by its obfuscated name. Primitives are
203
+ # never obfuscated.
204
+ #
205
+ # @param [String] name The obfuscated full class name (e.g.,
206
+ # "com.squareup.A.B") or full primitive name
207
+ # @return [Squash::Java::Type, nil] The type of that name, if found.
208
+
209
+ def obfuscated_type(name)
210
+ Squash::Java::PRIMITIVES.detect { |prim| prim.name == name } || obfuscated_class(name)
211
+ end
212
+
213
+ # **Finds or creates** a method by its name and parent class. Polymorphism is
214
+ # supported: Two methods can share the same name so long as their argument
215
+ # count or types are different.
216
+ #
217
+ # @param [Squash::Java::Class] klass The class containing the method.
218
+ # @param [String] name The method name, with return type and arguments as
219
+ # full, unobfuscated types (e.g., "com.foo.Bar myMethod(com.foo.Baz, int[])".
220
+ # @return [Squash::Java::Method] The corresponding method.
221
+
222
+ def method(klass, name)
223
+ matches = name.match(METHOD_REGEX) or raise "Invalid method name #{name.inspect}"
224
+ return_type = type(matches[1])
225
+ method_name = matches[2]
226
+ args = matches[3].split(/,\s*/).map { |arg| argument(arg) }
227
+ args = [] if matches[3].empty?
228
+
229
+ klass.java_methods.detect { |meth| meth.name == method_name && meth.arguments == args } ||
230
+ Squash::Java::Method.new(klass, method_name, return_type, *args)
231
+ end
232
+
233
+ # **Finds** a method by its obfuscated name and parent class. Polymorphism is
234
+ # supported: Two methods can share the same name so long as their argument
235
+ # count or types are different.
236
+ #
237
+ # @param [Squash::Java::Class] klass The class containing the method.
238
+ # @param [String] name The obfuscated method name, with return type and
239
+ # arguments as full, obfuscated types (e.g., "com.foo.A myMethod(com.foo.B, int[])".
240
+ # @return [Squash::Java::Method, nil] The corresponding method.
241
+
242
+ def obfuscated_method(klass, name)
243
+ matches = name.match(METHOD_REGEX) or raise "Invalid method name #{name.inspect}"
244
+ return_type = obfuscated_type(matches[1])
245
+ method_name = matches[2]
246
+ args = matches[3].split(/,\s*/).map { |arg| obfuscated_argument(arg) }
247
+ args = [] if matches[3].empty?
248
+ klass.java_methods.detect { |m| m.obfuscation == method_name && m.arguments == args }
249
+ end
250
+
251
+ # Creates a new Argument for a given type descriptor. This can be a
252
+ # primitive (e.g., "float") or a full class name (e.g., "com.foo.Bar"), and
253
+ # can be a scalar or an array (e.g., "float[]" or "com.foo.Bar[]"). **Finds or
254
+ # creates** the {Squash::Java::Type Type}, and **always creates** a new
255
+ # Argument.
256
+ #
257
+ # @param [String] type_descriptor The type description.
258
+ # @return [Squash::Java::Argument] The argument object, unbound to any
259
+ # {Squash::Java::Method Method}.
260
+
261
+ def argument(type_descriptor)
262
+ array = type_descriptor[-2..-1] == '[]'
263
+ type_name = type_descriptor.sub(/\[\]$/, '')
264
+ Squash::Java::Argument.new type(type_name), array
265
+ end
266
+
267
+ # Creates a new Argument for a given type descriptor, which can be fully or
268
+ # partially obfuscated. This can be an unobfuscated primitive (e.g., "float")
269
+ # or a possibly-obfuscated full class name (e.g., "com.foo.A"), and can be a
270
+ # scalar or an array (e.g., "float[]" or "com.foo.A[]"). **Finds** the
271
+ # {Squash::Java::Type Type}, and **always creates** a new Argument. Returns
272
+ # `nil` for unknown types.
273
+ #
274
+ # @param [String] type_descriptor The type description.
275
+ # @return [Squash::Java::Argument, nil] The argument object, unbound to any
276
+ # {Squash::Java::Method Method}, or `nil` if the type is not recognized.
277
+
278
+ def obfuscated_argument(type_descriptor)
279
+ array = type_descriptor[-2..-1] == '[]'
280
+ type_name = type_descriptor.sub(/\[\]$/, '')
281
+ type = obfuscated_type(type_name)
282
+ return nil unless type
283
+ Squash::Java::Argument.new type, array
284
+ end
285
+ end
286
+
287
+ # Represents a Java package.
288
+
289
+ class Squash::Java::Package
290
+
291
+ # @return [String] The last part of the package name (e.g., "bar" for package
292
+ # "com.foo.bar").
293
+ attr_reader :name
294
+
295
+ # @return [String, nil] The obfuscated package name (e.g., "A" for
296
+ # "com.foo.A").
297
+ attr_reader :obfuscation
298
+
299
+ # Sets the method's obfuscation.
300
+ # @raise [ArgumentError] If the obfuscation is taken by another class or in
301
+ # package the same namespace.
302
+
303
+ def obfuscation=(name)
304
+ if (package = parent.children.detect { |p| p.obfuscation == name })
305
+ raise ArgumentError, "Tried to assign obfuscation #{name} to #{package.inspect} and #{inspect}"
306
+ end
307
+ @obfuscation = name
308
+ end
309
+
310
+ # @return [Squash::Java::Package] The parent package (e.g., package "com.foo"
311
+ # for "com.foo.bar").
312
+ attr_reader :parent
313
+
314
+ # @return [Array<Squash::Java::Package>] Packages nested underneath this
315
+ # package (see {#parent}).
316
+ attr_reader :children
317
+
318
+ # @return [Array<Squash::Java::Class>] Classes belonging to this package.
319
+ attr_reader :classes
320
+
321
+ # @private
322
+ def initialize(name, parent=nil)
323
+ @name = name
324
+ @parent = parent
325
+ @parent.children << self if @parent
326
+ @children = Set.new
327
+ @classes = Set.new
328
+ end
329
+
330
+ # **Finds** a package underneath this package.
331
+ #
332
+ # @param [String] identifier The package name relative to this package. If
333
+ # finding package "com.foo.bar", pass "foo.bar" to Package "com".
334
+ # @return [Squash::Java::Package, nil] The matching package, if found.
335
+
336
+ def find(identifier)
337
+ parts = identifier.split('.')
338
+ name = parts.shift
339
+ child = children.detect { |pkg| pkg.name == name }
340
+ if parts.empty?
341
+ child
342
+ else
343
+ child ? child.find(parts.join('.')) : nil
344
+ end
345
+ end
346
+
347
+ # **Finds** a package by obfuscated (or non-obfuscated) name relative to this
348
+ # package.
349
+ #
350
+ # @param [String] identifier The package name relative to this package (parts
351
+ # may be obfuscated). If finding package "com.A.B", pass "A.B" to package
352
+ # "com".
353
+ # @return [Squash::Java::Package, nil] The matching package, if found.
354
+
355
+ def find_obfuscated(identifier)
356
+ parts = identifier.split('.')
357
+ name = parts.shift
358
+ child = children.detect { |pkg| pkg.obfuscation == name || pkg.name == name }
359
+ if parts.empty?
360
+ child
361
+ else
362
+ child ? child.find_obfuscated(parts.join('.')) : nil
363
+ end
364
+ end
365
+
366
+ # **Finds or creates** A package underneath this package.
367
+ #
368
+ # @param [String] identifier The package name relative to this package. If
369
+ # finding package "com.foo.bar", pass "foo.bar" to Package "com".
370
+ # @return [Squash::Java::Package] The matching package, or the newly created
371
+ # package.
372
+
373
+ def find_or_create(identifier)
374
+ parts = identifier.split('.')
375
+ name = parts.shift
376
+
377
+ if ('A'..'Z').include? name[0, 1] # class
378
+ raise "Unexpected class midway through identifier" unless parts.empty?
379
+ classes.detect { |cl| cl.name == name } || Squash::Java::Class.new(self, name)
380
+ else # package
381
+ child = children.detect { |pkg| pkg.name == name } || Squash::Java::Package.new(name, self)
382
+ parts.empty? ? child : child.find_or_create(parts.join('.'))
383
+ end
384
+ end
385
+
386
+ # @return [String] The full name of this package (e.g., "com.foo.bar").
387
+ def full_name() parent ? "#{parent.full_name}.#{name}" : name end
388
+
389
+ # @private
390
+ def inspect() "#<#{self.class.to_s} #{full_name}>" end
391
+
392
+ # @private
393
+ def subpath() parent ? "#{parent.subpath}/#{name}" : name end
394
+ end
395
+
396
+ # Superclass describing both {Squash::Java::Primitive Primitive} types and
397
+ # {Squash::Java::Class Classes}.
398
+
399
+ class Squash::Java::Type
400
+ # @return [String] The type name.
401
+ attr_reader :name
402
+
403
+ # @return [String] The full type name. By default this is equal to {#name},
404
+ # but can be overridden.
405
+ def full_name() name end
406
+
407
+ # @private
408
+ def inspect() "#<#{self.class.to_s} #{full_name}>" end
409
+ end
410
+
411
+ # Represents a Java class or inner class.
412
+
413
+ class Squash::Java::Class < Squash::Java::Type
414
+ # @return [Squash::Java::Class, Squash::Java::Package] The parent package (or
415
+ # parent class for inner classes).
416
+ attr_reader :parent
417
+
418
+ # @return [String, nil] The obfuscated name of this class.
419
+ attr_accessor :obfuscation
420
+
421
+ # @return [Array<Squash::Java::Method>] The instance methods of this class.
422
+ attr_reader :java_methods
423
+
424
+ # @return [Array<Squash::Java::Class>] The inner classes of this class.
425
+ attr_reader :classes
426
+
427
+ # @return [String] The path to the .java file defining this class, relative to
428
+ # the project root.
429
+ # @see Squash::Java::Namespace#find_files
430
+ attr_accessor :path
431
+
432
+ # @private
433
+ def initialize(parent, name)
434
+ @parent = parent
435
+ @java_methods = Set.new
436
+ @classes = Array.new
437
+ @name = name
438
+
439
+ @parent.classes << self
440
+ end
441
+
442
+ # @return [String] The name of this class (with package and parent class
443
+ # names).
444
+
445
+ def full_name
446
+ "#{parent.full_name}.#{name}"
447
+ end
448
+
449
+ # @private
450
+ def subpath() parent.kind_of?(Squash::Java::Package) ? "#{parent.subpath}/#{name}.java" : parent.subpath end
451
+ end
452
+
453
+ # Represents a primitive Java type, like `int` or `float`.
454
+
455
+ class Squash::Java::Primitive < Squash::Java::Type
456
+
457
+ # @private
458
+ def initialize(name)
459
+ @name = name
460
+ end
461
+ end
462
+
463
+ # Represents a Java instance method. Polymorphism is handled by using separate
464
+ # Method instances with different {#arguments} values.
465
+
466
+ class Squash::Java::Method
467
+ # @return [Squash::Java::Class] The class owning this method.
468
+ attr_reader :klass
469
+
470
+ # @return [Squash::Java::Argument] The type of object returned.
471
+ attr_reader :return_type
472
+
473
+ # @return [String] The method name.
474
+ attr_reader :name
475
+
476
+ # @return [Array<Squash::Java::Argument>] The method arguments.
477
+ attr_reader :arguments
478
+
479
+ # @return [String, nil] The obfuscated method name.
480
+ attr_reader :obfuscation
481
+
482
+ # Sets the method's obfuscation.
483
+ # @raise [ArgumentError] If the obfuscation is taken by another method in
484
+ # the same class.
485
+
486
+ def obfuscation=(name)
487
+ if (meth = klass.java_methods.detect { |m| m.arguments == arguments && m.obfuscation == name })
488
+ raise ArgumentError, "Tried to assign obfuscation #{name} to #{meth.inspect} and #{inspect}"
489
+ end
490
+ @obfuscation = name
491
+ end
492
+
493
+ # @private
494
+ def initialize(klass, name, return_type, *arguments)
495
+ @klass = klass
496
+ @name = name
497
+ @return_type = return_type
498
+ @arguments = arguments
499
+ klass.java_methods << self
500
+ end
501
+
502
+ # @private
503
+ def add_argument(type)
504
+ @arguments << type
505
+ @arguments.size - 1
506
+ end
507
+
508
+ # @return [String] The full method name, along with return value and arguments
509
+ # as full type names.
510
+
511
+ def full_name
512
+ args = arguments.map { |type| type.to_s }.join(', ')
513
+ "#{return_type.full_name} #{name}(#{args})"
514
+ end
515
+
516
+ # @private
517
+ def inspect() "#<#{self.class.to_s} #{full_name}>" end
518
+ end
519
+
520
+ # A {Squash::Java::Method Method} argument. Includes the argument
521
+ # {Squash::Java::Type} and whether it is a scalar or an array.
522
+
523
+ class Squash::Java::Argument
524
+ # @return [Squash::Java::Type] The argument type.
525
+ attr_reader :type
526
+
527
+ # @return [true, false] `true` if the argument is an array, false if it is a
528
+ # scalar.
529
+ attr_reader :array
530
+ alias array? array
531
+
532
+ # @private
533
+ def initialize(type, array=false)
534
+ @type = type
535
+ @array = array
536
+ end
537
+
538
+ # @private
539
+ def ==(other)
540
+ other.kind_of?(Squash::Java::Argument) &&
541
+ type == other.type &&
542
+ array? == other.array?
543
+ end
544
+
545
+ # @return [String] The type's full name, with "[]" appended for arrays.
546
+ def to_s() "#{type.full_name}#{'[]' if array?}" end
547
+
548
+ # @private
549
+ def inspect() "#<#{self.class} #{to_s}>" end
550
+ end
551
+
552
+ # All known Java primitives.
553
+ Squash::Java::PRIMITIVES = %w(boolean byte char short int long float double void).map { |name| Squash::Java::Primitive.new name }
@@ -0,0 +1,119 @@
1
+ # Copyright 2012 Square Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'rexml/document'
16
+
17
+ # Parses a rename log file (generated from yGuard or ProGuard) and generates a
18
+ # {Squash::Java::Namespace} object from it.
19
+
20
+ class Squash::Java::RenameLog
21
+ # @private
22
+ JAVA_PACKAGE_COMPONENT = '[a-z][a-z0-9_]*'
23
+ # @private
24
+ JAVA_PACKAGE_NAME = "#{JAVA_PACKAGE_COMPONENT}(?:\\.#{JAVA_PACKAGE_COMPONENT})*"
25
+ # @private
26
+ JAVA_CLASS_NAME = JAVA_VARIABLE_NAME = JAVA_OBFUSCATED_NAME = JAVA_METHOD_NAME = "[A-Za-z0-9_$]+"
27
+ # @private
28
+ JAVA_CLASS_PATH = "(?:#{JAVA_PACKAGE_NAME}\\.)?#{JAVA_CLASS_NAME}"
29
+ # @private
30
+ JAVA_PRIMITIVE = '(?:boolean|byte|char|short|int|long|float|double|void)'
31
+ # @private
32
+ JAVA_TYPE = "(?:#{JAVA_PRIMITIVE}|#{JAVA_CLASS_PATH})(?:\\[\\])*"
33
+ # @private
34
+ JAVA_TYPE_LIST = "#{JAVA_TYPE}(?:,\\s?#{JAVA_TYPE})*"
35
+ # @private
36
+ JAVA_METHOD_SIGNATURE = "#{JAVA_TYPE} #{JAVA_METHOD_NAME}\\((?:#{JAVA_TYPE_LIST})?\\)"
37
+
38
+ # Creates a new parser for a given rename log file. The file is assumed to be
39
+ # in the yGuard format if it ends in ".xml", and in the ProGuard format if it
40
+ # ends in ".txt".
41
+ #
42
+ # @param [String] logfile The path to a rename log file.
43
+
44
+ def initialize(logfile)
45
+ @logfile = logfile
46
+ end
47
+
48
+ # @return [Squash::Java::Namespace] The name mapping in the file.
49
+
50
+ def parse
51
+ return parse_yguard if File.extname(@logfile) == '.xml'
52
+ return parse_proguard if File.extname(@logfile) == '.txt'
53
+ end
54
+
55
+ private
56
+
57
+ def parse_yguard
58
+ namespace = Squash::Java::Namespace.new
59
+
60
+ xml = REXML::Document.new(File.new(@logfile))
61
+ xml.elements.each("//yguard/map/*") do |element|
62
+ obfuscation = element.attributes['map']
63
+ name = element.attributes['name']
64
+ case element.name
65
+ when 'package'
66
+ namespace.add_package_alias name, obfuscation
67
+ when 'class'
68
+ # "com.hvilela.Wallpaperer$6" gets an obfuscation of "6" when it should be "Wallpaperer$6"
69
+ class_name = name.split('.').last
70
+ if class_name.include?('$')
71
+ base_class = namespace.klass(class_name.split('$').first)
72
+ new_obfuscation = [base_class.obfuscation || base_class.name]
73
+ new_obfuscation += class_name.split('$')[1..-2] << obfuscation
74
+ obfuscation = new_obfuscation.join('$')
75
+ end
76
+ namespace.add_class_alias name, obfuscation
77
+ when 'method'
78
+ namespace.add_method_alias element.attributes['class'], name, obfuscation
79
+ end
80
+ end
81
+
82
+ xml.elements.each("//yguard/expose/class") do |element|
83
+ name = element.attributes['name']
84
+ namespace.klass name
85
+ end
86
+
87
+ return namespace
88
+ end
89
+
90
+ def parse_proguard
91
+ namespace = Squash::Java::Namespace.new
92
+
93
+ File.open(@logfile) do |f|
94
+ current_class = nil
95
+ f.each_line do |line|
96
+ if line =~ /^(#{JAVA_CLASS_PATH}) -> (#{JAVA_CLASS_PATH}):$/ # class
97
+ current_class = namespace.add_class_alias($1, $2.split('.').last)
98
+ elsif line =~ /^ #{JAVA_TYPE} #{JAVA_VARIABLE_NAME} -> #{JAVA_OBFUSCATED_NAME}$/ # field, skip
99
+ raise "Unexpected field mapping outside of class" unless current_class
100
+ elsif line =~ /^ (?:\d+:\d+:)?(#{JAVA_METHOD_SIGNATURE}) -> (#{JAVA_OBFUSCATED_NAME})$/ # method
101
+ raise "Unexpected method mapping outside of class" unless current_class
102
+ begin
103
+ namespace.add_method_alias(current_class, $1, $2) if current_class.kind_of?(Squash::Java::Class)
104
+ rescue ArgumentError
105
+ # duplicate obfuscation -- this happens when the Java compiler
106
+ # generates multiple methods with the same signature to support
107
+ # generics. ignore the less specific variant (all later variants)
108
+ raise unless $!.to_s =~ /Tried to assign obfuscation/
109
+ end
110
+ elsif line.empty? # blank, skip
111
+ else
112
+ raise "Invalid mapping line: #{line}"
113
+ end
114
+ end
115
+ end
116
+
117
+ return namespace
118
+ end
119
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright 2012 Square Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Container module for Squash-related code.
16
+
17
+ module Squash
18
+
19
+ # Container module for Squash Java-related code.
20
+
21
+ module Java
22
+ end
23
+ end
24
+
25
+ require 'squash/java/namespace'
26
+ require 'squash/java/rename_log'
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: squash_java
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Tim Morgan
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-12-07 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 3
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ name: json
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ hash: 3
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :runtime
46
+ name: squash_uploader
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ prerelease: false
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ type: :development
60
+ name: rspec
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ prerelease: false
64
+ requirement: &id004 !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ hash: 3
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ type: :development
74
+ name: yard
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ prerelease: false
78
+ requirement: &id005 !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ hash: 3
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ type: :development
88
+ name: redcarpet
89
+ version_requirements: *id005
90
+ - !ruby/object:Gem::Dependency
91
+ prerelease: false
92
+ requirement: &id006 !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ type: :development
102
+ name: jeweler
103
+ version_requirements: *id006
104
+ description: This gem includes a library that imports yGuard or ProGuard rename logs, and a binary that uploads the data to Squash.
105
+ email: tim@squareup.com
106
+ executables:
107
+ - squash_release
108
+ - deobfuscate
109
+ extensions: []
110
+
111
+ extra_rdoc_files:
112
+ - LICENSE.txt
113
+ - README.md
114
+ files:
115
+ - LICENSE.txt
116
+ - README.md
117
+ - bin/deobfuscate
118
+ - bin/squash_release
119
+ - lib/squash/java.rb
120
+ - lib/squash/java/namespace.rb
121
+ - lib/squash/java/rename_log.rb
122
+ homepage: http://github.com/SquareSquash/java_deobfuscator
123
+ licenses:
124
+ - Apache 2.0
125
+ post_install_message:
126
+ rdoc_options: []
127
+
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ hash: 3
136
+ segments:
137
+ - 0
138
+ version: "0"
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ hash: 3
145
+ segments:
146
+ - 0
147
+ version: "0"
148
+ requirements: []
149
+
150
+ rubyforge_project:
151
+ rubygems_version: 1.8.24
152
+ signing_key:
153
+ specification_version: 3
154
+ summary: Binary and library for deobfuscating your Java project and uploading the rename log to Squash.
155
+ test_files: []
156
+