tool-shed 0.0.4
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/Gemfile +9 -0
- data/LICENSE +20 -0
- data/README.md +52 -0
- data/bin/as-asset-detector +16 -0
- data/bin/as-class-detector +16 -0
- data/bin/as-docp +16 -0
- data/bin/as-manifest +16 -0
- data/bin/as-style-detector +16 -0
- data/coverage/unit/index.html +330 -0
- data/coverage/unit/jquery-1.3.2.min.js +19 -0
- data/coverage/unit/jquery.tablesorter.min.js +15 -0
- data/coverage/unit/lib-hel-asdoc_package_rb.html +447 -0
- data/coverage/unit/lib-hel-manifest_rb.html +555 -0
- data/coverage/unit/lib-hel-opts-asdoc_package_opts_rb.html +195 -0
- data/coverage/unit/lib-hel-opts-manifest_opts_rb.html +195 -0
- data/coverage/unit/lib-hel-opts-tool_opts_rb.html +531 -0
- data/coverage/unit/lib-hel-opts-unused_class_opts_rb.html +207 -0
- data/coverage/unit/lib-hel-opts-unused_style_opts_rb.html +201 -0
- data/coverage/unit/lib-hel-project_tools_rb.html +423 -0
- data/coverage/unit/lib-hel-search_rb.html +363 -0
- data/coverage/unit/lib-hel-stripper_rb.html +357 -0
- data/coverage/unit/lib-hel-tool_rb.html +423 -0
- data/coverage/unit/lib-hel-unused_class_rb.html +675 -0
- data/coverage/unit/lib-hel-unused_style_rb.html +747 -0
- data/coverage/unit/lib-hel-version_rb.html +135 -0
- data/coverage/unit/lib-hel_tools_rb.html +165 -0
- data/coverage/unit/print.css +12 -0
- data/coverage/unit/rcov.js +42 -0
- data/coverage/unit/screen.css +270 -0
- data/coverage.data +0 -0
- data/lib/shed/asdoc_package.rb +64 -0
- data/lib/shed/manifest.rb +82 -0
- data/lib/shed/opts/asdoc_package_opts.rb +22 -0
- data/lib/shed/opts/manifest_opts.rb +22 -0
- data/lib/shed/opts/tool_opts.rb +114 -0
- data/lib/shed/opts/unused_asset_opts.rb +24 -0
- data/lib/shed/opts/unused_class_opts.rb +24 -0
- data/lib/shed/opts/unused_style_opts.rb +23 -0
- data/lib/shed/project_tools.rb +60 -0
- data/lib/shed/search.rb +50 -0
- data/lib/shed/stripper.rb +49 -0
- data/lib/shed/tool.rb +60 -0
- data/lib/shed/unused_asset.rb +68 -0
- data/lib/shed/unused_class.rb +102 -0
- data/lib/shed/unused_style.rb +114 -0
- data/lib/shed/version.rb +12 -0
- data/lib/tool_shed.rb +19 -0
- data/rakefile.rb +109 -0
- data/rdoc/classes/ASDocPackage.html +281 -0
- data/rdoc/classes/ASDocPackageOpts.html +204 -0
- data/rdoc/classes/Manifest.html +323 -0
- data/rdoc/classes/ManifestOpts.html +205 -0
- data/rdoc/classes/ProjectTools.html +302 -0
- data/rdoc/classes/Search.html +203 -0
- data/rdoc/classes/Stripper.html +223 -0
- data/rdoc/classes/Tool.html +313 -0
- data/rdoc/classes/ToolOpts.html +297 -0
- data/rdoc/classes/UnusedClass.html +258 -0
- data/rdoc/classes/UnusedClassOpts.html +206 -0
- data/rdoc/classes/UnusedStyle.html +277 -0
- data/rdoc/classes/UnusedStyleOpts.html +205 -0
- data/rdoc/created.rid +1 -0
- data/rdoc/files/LICENSE.html +129 -0
- data/rdoc/files/README_md.html +138 -0
- data/rdoc/files/lib/hel/asdoc_package_rb.html +107 -0
- data/rdoc/files/lib/hel/manifest_rb.html +107 -0
- data/rdoc/files/lib/hel/opts/asdoc_package_opts_rb.html +107 -0
- data/rdoc/files/lib/hel/opts/manifest_opts_rb.html +107 -0
- data/rdoc/files/lib/hel/opts/tool_opts_rb.html +114 -0
- data/rdoc/files/lib/hel/opts/unused_class_opts_rb.html +107 -0
- data/rdoc/files/lib/hel/opts/unused_style_opts_rb.html +107 -0
- data/rdoc/files/lib/hel/project_tools_rb.html +107 -0
- data/rdoc/files/lib/hel/search_rb.html +114 -0
- data/rdoc/files/lib/hel/stripper_rb.html +107 -0
- data/rdoc/files/lib/hel/tool_rb.html +107 -0
- data/rdoc/files/lib/hel/unused_class_rb.html +107 -0
- data/rdoc/files/lib/hel/unused_style_rb.html +107 -0
- data/rdoc/files/lib/hel/version_rb.html +107 -0
- data/rdoc/files/lib/hel_tools_rb.html +127 -0
- data/rdoc/fr_class_index.html +39 -0
- data/rdoc/fr_file_index.html +43 -0
- data/rdoc/fr_method_index.html +75 -0
- data/rdoc/index.html +24 -0
- data/rdoc/rdoc-style.css +208 -0
- data/test/fixtures/search/App.mxml +0 -0
- data/test/fixtures/search/hide/Hidden.as +0 -0
- data/test/fixtures/search/org/helvector/Main.as +0 -0
- data/test/fixtures/src/org/helvector/Helvector.as +16 -0
- data/test/fixtures/src/org/helvector/one/HelOne.as +14 -0
- data/test/fixtures/src/org/helvector/one/HelOneTwo.mxml +0 -0
- data/test/fixtures/src/org/helvector/one/package.asdoc +1 -0
- data/test/fixtures/src/org/helvector/package.asdoc +1 -0
- data/test/fixtures/src/org/helvector/three/HelThree.as +14 -0
- data/test/fixtures/src/org/helvector/three/package.asdoc +1 -0
- data/test/fixtures/src/org/helvector/two/HelTwo.as +14 -0
- data/test/fixtures/src/org/helvector/two/package.asdoc +1 -0
- data/test/fixtures/unused-asset/assets/css/referenced.css +0 -0
- data/test/fixtures/unused-asset/assets/css/un-referenced.css +0 -0
- data/test/fixtures/unused-asset/assets/fonts/referenced.otf +0 -0
- data/test/fixtures/unused-asset/assets/fonts/un-referenced.otf +0 -0
- data/test/fixtures/unused-asset/assets/img/referenced.jpg +0 -0
- data/test/fixtures/unused-asset/assets/img/referenced.png +0 -0
- data/test/fixtures/unused-asset/assets/img/un-referenced.jpg +0 -0
- data/test/fixtures/unused-asset/assets/img/un-referenced.png +0 -0
- data/test/fixtures/unused-asset/src/org/helvector/ToolShed.as +30 -0
- data/test/fixtures/unused-cla/link-report.xml +17 -0
- data/test/fixtures/unused-cla/manifest.xml +6 -0
- data/test/fixtures/unused-cla/src/Unused.as +0 -0
- data/test/fixtures/unused-cla/src/Used.as +0 -0
- data/test/fixtures/unused-css/css/styles.css +2 -0
- data/test/fixtures/unused-css/css-multiple/more.css +2 -0
- data/test/fixtures/unused-css/css-multiple/styles.css +2 -0
- data/test/fixtures/unused-css/css-with-comments/commented.css +6 -0
- data/test/fixtures/unused-css/src/CSSApp.mxml +5 -0
- data/test/test_helper.rb +9 -0
- data/test/unit/test_asdoc_package.rb +72 -0
- data/test/unit/test_asdoc_package_opts.rb +28 -0
- data/test/unit/test_manifest.rb +53 -0
- data/test/unit/test_manifest_opts.rb +28 -0
- data/test/unit/test_search.rb +67 -0
- data/test/unit/test_source_tools.rb +97 -0
- data/test/unit/test_stripper.rb +56 -0
- data/test/unit/test_tool.rb +73 -0
- data/test/unit/test_tool_opts.rb +81 -0
- data/test/unit/test_unused_asset.rb +59 -0
- data/test/unit/test_unused_asset_opts.rb +32 -0
- data/test/unit/test_unused_class.rb +50 -0
- data/test/unit/test_unused_class_opts.rb +32 -0
- data/test/unit/test_unused_style.rb +103 -0
- data/test/unit/test_unused_style_opts.rb +31 -0
- data/tool-shed-0.0.3.gem +0 -0
- data/tool-shed.gemspec +41 -0
- metadata +265 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Scans a specified source tree for ActionScript and MXML files and for each one
|
|
5
|
+
# found creates a manifest entry. When complete writes the resulting manfiest
|
|
6
|
+
# file to disk.
|
|
7
|
+
#
|
|
8
|
+
class Manifest < Tool
|
|
9
|
+
attr_reader :components,
|
|
10
|
+
:xml
|
|
11
|
+
|
|
12
|
+
def initialize(opt,out=STDOUT)
|
|
13
|
+
super(opt,out)
|
|
14
|
+
|
|
15
|
+
@filetypes = /\.(as|mxml)$/
|
|
16
|
+
|
|
17
|
+
build
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Generates a hash containing id and xml vales. The xml can be to be inserted
|
|
22
|
+
# into the manifest for the specified class.
|
|
23
|
+
#
|
|
24
|
+
def add(path, id)
|
|
25
|
+
log("Adding '#{path}'")
|
|
26
|
+
|
|
27
|
+
cp = ProjectTools.import(path)
|
|
28
|
+
|
|
29
|
+
{ :key => id, :xml => "<component id=\"#{id}\" class=\"#{cp}\" />" }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Search the provided path for as and mxml documents and return those found as
|
|
34
|
+
# a list.
|
|
35
|
+
#
|
|
36
|
+
def scan(path)
|
|
37
|
+
puts "Scanning '#{path}' for as and mxml files..."
|
|
38
|
+
|
|
39
|
+
found = []
|
|
40
|
+
|
|
41
|
+
Search.find_all(@filetypes,path,@excludes) do |p|
|
|
42
|
+
ext = File.extname(p)
|
|
43
|
+
cn = File.basename(p, ext)
|
|
44
|
+
|
|
45
|
+
found << add(p, cn) if cn =~ /^[A-Z]/
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
found.uniq! unless found.empty?
|
|
49
|
+
|
|
50
|
+
found
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Build the manifest file and save it to disk.
|
|
55
|
+
#
|
|
56
|
+
def build
|
|
57
|
+
@components = scan(@src)
|
|
58
|
+
|
|
59
|
+
if @components.empty?
|
|
60
|
+
puts "No ActionScript or Mxml files found."
|
|
61
|
+
else
|
|
62
|
+
|
|
63
|
+
@components.sort! {|a,b| a[:xml] <=> b[:xml] }
|
|
64
|
+
|
|
65
|
+
@xml = create_xml(@components)
|
|
66
|
+
|
|
67
|
+
#Open/Create the manifest file and write the output to it.
|
|
68
|
+
to_disk(@xml)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
#
|
|
73
|
+
# Constructs the flex complier config file when given a list of paths to asdoc
|
|
74
|
+
# files.
|
|
75
|
+
#
|
|
76
|
+
def create_xml(comps)
|
|
77
|
+
x = "<?xml version='1.0'?>\n<componentPackage>\n"
|
|
78
|
+
comps.each { |c| x << "\t#{c[:xml]}\n" }
|
|
79
|
+
x << "</componentPackage>"
|
|
80
|
+
x
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Manages the command line interface for the ASDoc Package File tool.
|
|
5
|
+
#
|
|
6
|
+
class ASDocPackageOpts < ToolOpts
|
|
7
|
+
|
|
8
|
+
def self.name
|
|
9
|
+
'as-docp'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.description
|
|
13
|
+
'ASDoc Package Builder'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.default_config
|
|
17
|
+
dc = superclass.default_config
|
|
18
|
+
dc[:output] = 'package-asdoc.xml'
|
|
19
|
+
dc
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Manages the command line interface for the AS3 Manifest File generation tool.
|
|
5
|
+
#
|
|
6
|
+
class ManifestOpts < ToolOpts
|
|
7
|
+
|
|
8
|
+
def self.description
|
|
9
|
+
"ActionScript Manifest Generator Tool"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.name
|
|
13
|
+
"as-manifest"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.default_config
|
|
17
|
+
dc = superclass.default_config
|
|
18
|
+
dc[:output] = "manifest.xml"
|
|
19
|
+
dc
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'optparse'
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# Abstract layer for the tool shed options parsers. This sets the basic
|
|
7
|
+
# paramaters the tools respond to via the command line.
|
|
8
|
+
#
|
|
9
|
+
class ToolOpts
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# The name of the tool, as invoked on the command line.
|
|
13
|
+
#
|
|
14
|
+
def self.name
|
|
15
|
+
ToolShed::NAME
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# A basic description of the tools use.
|
|
20
|
+
#
|
|
21
|
+
def self.description
|
|
22
|
+
'Tool'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# A version string to describe the version of the tool these options are
|
|
27
|
+
# designed to invoke.
|
|
28
|
+
#
|
|
29
|
+
def self.version
|
|
30
|
+
ToolShed::VERSION::STRING
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Default configuration hash.
|
|
35
|
+
#
|
|
36
|
+
def self.default_config
|
|
37
|
+
{
|
|
38
|
+
:src => ".",
|
|
39
|
+
:output => 'output.xml',
|
|
40
|
+
:verbose => false,
|
|
41
|
+
:silent => false
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# Create and return the options parser with the default header.
|
|
47
|
+
#
|
|
48
|
+
def self.create_parser
|
|
49
|
+
op = OptionParser.new
|
|
50
|
+
op.banner = "Usage: #{name} [options]"
|
|
51
|
+
|
|
52
|
+
op.separator ""
|
|
53
|
+
op.separator "Options:"
|
|
54
|
+
op
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Add all mandatory arguments to the options parser.
|
|
59
|
+
#
|
|
60
|
+
def self.add_mandatory(op,config)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#
|
|
64
|
+
# Add all optional arguments to the options parser.
|
|
65
|
+
#
|
|
66
|
+
def self.add_optional(op,config)
|
|
67
|
+
op.on("-s", "--source [PATH]", String, "Path to source folder, defaults to current directory.") do |v|
|
|
68
|
+
config[:src] = v
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
op.on("-o", "--output [FILE PATH]", String, "Path to output file, defaults to #{config[:output]}") do |v|
|
|
72
|
+
config[:output] = v
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
op.on("-v", "--verbose", "Run verbosely") do |v|
|
|
76
|
+
config[:verbose] = v
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
op.on("--silent", "Supress all output.") do |v|
|
|
80
|
+
config[:silent] = v
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def self.add_tail(op,out)
|
|
85
|
+
op.on_tail("-h", "--help", "Show this help message") do
|
|
86
|
+
out.puts op
|
|
87
|
+
exit
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
op.on_tail("--version", "Show version") do
|
|
91
|
+
out.puts "#{description} version #{version}"
|
|
92
|
+
exit
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
#
|
|
97
|
+
# Parse the arugments and return a config hash.
|
|
98
|
+
#
|
|
99
|
+
def self.parse(args,out=STDOUT)
|
|
100
|
+
|
|
101
|
+
config = default_config()
|
|
102
|
+
options = create_parser()
|
|
103
|
+
|
|
104
|
+
add_mandatory(options,config)
|
|
105
|
+
add_optional(options,config)
|
|
106
|
+
|
|
107
|
+
add_tail(options,out)
|
|
108
|
+
|
|
109
|
+
options.parse!(args)
|
|
110
|
+
|
|
111
|
+
config
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Manages the command line interface for the unused assets detection tool.
|
|
5
|
+
#
|
|
6
|
+
class UnusedAssetOpts < ToolOpts
|
|
7
|
+
|
|
8
|
+
def self.name
|
|
9
|
+
"as-asset-detector"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.description
|
|
13
|
+
" ActionScript Unused Asset Detection Tool"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.default_config
|
|
17
|
+
dc = superclass.default_config
|
|
18
|
+
dc[:output] = 'assets.txt'
|
|
19
|
+
dc[:manifest] = 'manifest.xml'
|
|
20
|
+
dc[:link_report] = 'link-report.xml'
|
|
21
|
+
dc
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Manages the command line interface for the unused classes detection tool.
|
|
5
|
+
#
|
|
6
|
+
class UnusedClassOpts < ToolOpts
|
|
7
|
+
|
|
8
|
+
def self.name
|
|
9
|
+
"as-class-detector"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.description
|
|
13
|
+
"ActionScript unused class detection tool"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.default_config
|
|
17
|
+
dc = superclass.default_config
|
|
18
|
+
dc[:output] = 'classes.txt'
|
|
19
|
+
dc[:manifest] = 'manifest.xml'
|
|
20
|
+
dc[:link_report] = 'link-report.xml'
|
|
21
|
+
dc
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Manages the command line interface for the unused style detection tool.
|
|
5
|
+
#
|
|
6
|
+
class UnusedStyleOpts < ToolOpts
|
|
7
|
+
|
|
8
|
+
def self.name
|
|
9
|
+
"as-style-detector"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.description
|
|
13
|
+
" ActionScript Unused Style Detection Tool"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.default_config
|
|
17
|
+
dc = superclass.default_config
|
|
18
|
+
dc[:output] = 'styles.txt'
|
|
19
|
+
dc[:css_dir] = 'style'
|
|
20
|
+
dc
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# A collection of utility methods to help working with ActionScript source.
|
|
5
|
+
#
|
|
6
|
+
class ProjectTools
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# Returns an array of directory names that are commonly used
|
|
10
|
+
# as the root directory for source files.
|
|
11
|
+
#
|
|
12
|
+
def self.common_src_dirs
|
|
13
|
+
['src','source','test','lib']
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Takes a file path and truncates it to the last matching conventionally named
|
|
18
|
+
# source directory.
|
|
19
|
+
#
|
|
20
|
+
def self.truncate_to_src(path)
|
|
21
|
+
common_src_dirs.each do |remove|
|
|
22
|
+
path = path.gsub(/^.*\b#{remove}\b(\/|$)/, '');
|
|
23
|
+
end
|
|
24
|
+
path
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Removes any relative prefixes found in the provided path.
|
|
29
|
+
#
|
|
30
|
+
def self.remove_relative_prefix(path)
|
|
31
|
+
path.sub(/^\W+\b/, '')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Takes a file path and converts it to a package path using conventionally
|
|
36
|
+
# named source folders as the root marker.
|
|
37
|
+
#
|
|
38
|
+
def self.package(path)
|
|
39
|
+
path = remove_relative_prefix(path)
|
|
40
|
+
path = File.dirname(path) if path =~ flex_file_regx
|
|
41
|
+
truncate_to_src(path).gsub('/','.')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# Takes a file path and converts it to a import path using conventionally
|
|
46
|
+
# named source folders as the root marker.
|
|
47
|
+
#
|
|
48
|
+
def self.import(path)
|
|
49
|
+
truncate_to_src(path).gsub('/','.').sub(flex_file_regx,'')
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# Regular expression to match files we expect to find in a ActionScript/Flex
|
|
54
|
+
# project.
|
|
55
|
+
#
|
|
56
|
+
def self.flex_file_regx
|
|
57
|
+
/\.(as|mxml|asdoc)$/
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
data/lib/shed/search.rb
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Collection of methods for searching directories.
|
|
5
|
+
#
|
|
6
|
+
module Search
|
|
7
|
+
|
|
8
|
+
require 'find'
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Searches a directory and it's child directories for all the files whose
|
|
12
|
+
# names match the specified regular expression.
|
|
13
|
+
#
|
|
14
|
+
def self.find_all(files_of_type,dir,excluding=[])
|
|
15
|
+
|
|
16
|
+
Find.find(dir) do |path|
|
|
17
|
+
if FileTest.directory?(path)
|
|
18
|
+
|
|
19
|
+
if excluding.include?(File.basename(path))
|
|
20
|
+
Find.prune
|
|
21
|
+
else
|
|
22
|
+
next
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
elsif File.extname(path) =~ files_of_type
|
|
26
|
+
yield path
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Scans the path and its children for empty directories.
|
|
33
|
+
#
|
|
34
|
+
def self.for_empties(path,excluding=[])
|
|
35
|
+
|
|
36
|
+
Find.find(path) do |p|
|
|
37
|
+
|
|
38
|
+
if FileTest.directory?(p)
|
|
39
|
+
if excluding.include?(File.basename(p))
|
|
40
|
+
Find.prune
|
|
41
|
+
else
|
|
42
|
+
# Any dir that only contains ., .., and .svn or .git are empty.
|
|
43
|
+
yield p if Dir.entries(p).join =~ /^\.\.\.(\.(svn|git))?$/
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Stripper
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Strips xml comments from the document.
|
|
9
|
+
#
|
|
10
|
+
def xml_comments(str)
|
|
11
|
+
str.gsub!(/<!--(?:.|([\r\n]))*?-->/,'')
|
|
12
|
+
str.gsub(/<!--.*-->/,'')
|
|
13
|
+
str
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Strips comments from the document.
|
|
18
|
+
#
|
|
19
|
+
def ecma_comments(str)
|
|
20
|
+
|
|
21
|
+
str.gsub!(/\/\*(?:.|([\r\n]))*?\*\//,'')
|
|
22
|
+
|
|
23
|
+
# This is designed to leave whitespace in
|
|
24
|
+
# place so the caret position remains correct.
|
|
25
|
+
#do |s|
|
|
26
|
+
# if $1
|
|
27
|
+
# a = s.split("\n")
|
|
28
|
+
# r = "\n" * (a.length-1) if a.length > 1
|
|
29
|
+
# r
|
|
30
|
+
# end
|
|
31
|
+
#end
|
|
32
|
+
|
|
33
|
+
str.gsub!(/\/\/.*$/,'')
|
|
34
|
+
str
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Strips both xml and ecma script comments.
|
|
40
|
+
#
|
|
41
|
+
def comments(str)
|
|
42
|
+
str = xml_comments(str)
|
|
43
|
+
str = ecma_comments(str)
|
|
44
|
+
str
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
data/lib/shed/tool.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Abstract base class for tools. Provides basic default settings, and allows
|
|
5
|
+
# control over the level of logging to standard out.
|
|
6
|
+
#
|
|
7
|
+
class Tool
|
|
8
|
+
|
|
9
|
+
INVALID_OPTS = "Warning Invalid Options."
|
|
10
|
+
|
|
11
|
+
def initialize(opt,out=STDOUT)
|
|
12
|
+
@src = opt[:src] || '.'
|
|
13
|
+
@output = opt[:output] || 'tool-shed.txt'
|
|
14
|
+
@verbose = opt[:verbose] || false
|
|
15
|
+
@silent = opt[:silent] || false
|
|
16
|
+
@excludes = opt[:excludes] || ['.svn','.git']
|
|
17
|
+
@out = out
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Puts the message unless we are in silent mode.
|
|
22
|
+
#
|
|
23
|
+
def puts(msg)
|
|
24
|
+
@out.puts msg unless @silent
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Puts the message if we are in verbose mode (but not in silent mode).
|
|
29
|
+
#
|
|
30
|
+
def log(msg)
|
|
31
|
+
puts msg if @verbose
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Validates the opts the tool has been invoked with.
|
|
36
|
+
#
|
|
37
|
+
def valid_opts
|
|
38
|
+
true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#
|
|
42
|
+
# Write the requested string to the output file.
|
|
43
|
+
#
|
|
44
|
+
def to_disk(str)
|
|
45
|
+
f = File.open(@output, "w")
|
|
46
|
+
f.puts str
|
|
47
|
+
f.flush
|
|
48
|
+
f.close
|
|
49
|
+
|
|
50
|
+
puts "Saved result to #{File.expand_path(@output)}."
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Generate a timestamp to include in reports.
|
|
55
|
+
#
|
|
56
|
+
def generated_at
|
|
57
|
+
"Generated at" + Time.now.strftime(" [%m/%d/%Y %H:%M:%S] ")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# This script scans all Actionscript classes and CSS files in a project to
|
|
5
|
+
# identify assets, like PNG files, that are in the project source tree but are
|
|
6
|
+
# no longer used by the application.
|
|
7
|
+
#
|
|
8
|
+
class UnusedAsset < Tool
|
|
9
|
+
def initialize(opt,out=STDOUT)
|
|
10
|
+
super(opt,out)
|
|
11
|
+
|
|
12
|
+
@link_report = opt[:link_report]
|
|
13
|
+
@manifest = opt[:manifest]
|
|
14
|
+
|
|
15
|
+
unless valid_opts
|
|
16
|
+
@out.puts "#{INVALID_OPTS} One or all of specified link report, manifest file, and source directories does not exist."
|
|
17
|
+
return
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
@declared_regex = /^TODO/
|
|
21
|
+
|
|
22
|
+
detect
|
|
23
|
+
|
|
24
|
+
@report = describe
|
|
25
|
+
|
|
26
|
+
to_disk(@report)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def valid_opts
|
|
30
|
+
File.exist?(@link_report) && File.exist?(@manifest) && File.exist?(@src) rescue false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def detect
|
|
34
|
+
@declared = scan_dirs(/\.(css|as|mxml)/, @src, @declared_regex)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Scans directories for all files that match the file extension regex, and
|
|
41
|
+
# for each match goes on to scan that document for items matching the syntax
|
|
42
|
+
# regex.
|
|
43
|
+
#
|
|
44
|
+
def scan_dirs(extension_regex,path,syntax_regex)
|
|
45
|
+
d = []
|
|
46
|
+
|
|
47
|
+
Search.find_all(extension_regex,path,@excludes) do |path|
|
|
48
|
+
d << scan_doc(path,syntax_regex)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
d.flatten!.sort!.uniq! unless d.empty?
|
|
52
|
+
d
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Opens the document specified by path and returns a list of all first capture
|
|
57
|
+
# group matches, after stripping comments.
|
|
58
|
+
#
|
|
59
|
+
def scan_doc(path,regex)
|
|
60
|
+
n = []
|
|
61
|
+
f = File.open(path,"r").read.strip
|
|
62
|
+
f = Stripper.comments(f)
|
|
63
|
+
f.scan(regex) do |style_name|
|
|
64
|
+
n << $1
|
|
65
|
+
end
|
|
66
|
+
n
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# This tool compares a mxmlc generated link-report against a manifest file
|
|
5
|
+
# created by the as-manifest tool to identify files that are in the project
|
|
6
|
+
# source tree but are no longer used by the application.
|
|
7
|
+
#
|
|
8
|
+
# Before executing this script make sure the relevant link reports and manifest
|
|
9
|
+
# files have been generated.
|
|
10
|
+
#
|
|
11
|
+
class UnusedClass < Tool
|
|
12
|
+
attr_reader :report,
|
|
13
|
+
:empty_packages,
|
|
14
|
+
:unused_classes
|
|
15
|
+
|
|
16
|
+
def initialize(opt,out=STDOUT)
|
|
17
|
+
super(opt,out)
|
|
18
|
+
|
|
19
|
+
@link_report = opt[:link_report]
|
|
20
|
+
@manifest = opt[:manifest]
|
|
21
|
+
@link_regex = /<script name=".*\/(\w+)\.(as|mxml)/
|
|
22
|
+
@manifest_regex = /<component id="(\w+)"/
|
|
23
|
+
|
|
24
|
+
unless valid_opts
|
|
25
|
+
@out.puts "#{INVALID_OPTS} One or all of the specified link report, manifest file, or source directory does not exist."
|
|
26
|
+
return
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
detect
|
|
30
|
+
|
|
31
|
+
@report = describe
|
|
32
|
+
|
|
33
|
+
to_disk(@report)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def valid_opts
|
|
37
|
+
File.exist?(@link_report) && File.exist?(@manifest) && File.exist?(@src) rescue false
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def detect
|
|
41
|
+
puts "Scanning project for classes that are uncompiled..."
|
|
42
|
+
|
|
43
|
+
@manifest_classes = linked(@manifest, @manifest_regex, 'manifest')
|
|
44
|
+
@link_classes = linked(@link_report, @link_regex, 'link-report')
|
|
45
|
+
|
|
46
|
+
@unused_classes = @manifest_classes-@link_classes
|
|
47
|
+
@empty_packages = empties(@src)
|
|
48
|
+
|
|
49
|
+
puts "Unused classes: #{@unused_classes.length.to_s}"
|
|
50
|
+
puts "Empty packages: #{@empty_packages.length.to_s}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Scans the path for empty directories and lists them.
|
|
57
|
+
#
|
|
58
|
+
def empties(path)
|
|
59
|
+
e = []
|
|
60
|
+
Search.for_empties(path) { |p| e << p.sub( /^.*src\//, "") }
|
|
61
|
+
e
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Returns a string detailing the findings of the unused class detection.
|
|
66
|
+
#
|
|
67
|
+
def describe
|
|
68
|
+
d = generated_at
|
|
69
|
+
d << add_desc(" classes are in the manifest but not in the link report:", @unused_classes)
|
|
70
|
+
d << add_desc(" packages appear to be empty:", @empty_packages)
|
|
71
|
+
d
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
# Prints a description category.
|
|
76
|
+
#
|
|
77
|
+
def add_desc(txt,list)
|
|
78
|
+
l = list.empty? ? '' : list.join("\n")
|
|
79
|
+
"#{list.length} #{txt}\n#{l}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# Collects all the lines in the specified link file matching the regular
|
|
84
|
+
# expression and returns them in a list.
|
|
85
|
+
#
|
|
86
|
+
def linked(link,rgx,desc)
|
|
87
|
+
log("Loading #{desc}: #{File.expand_path(link)}")
|
|
88
|
+
|
|
89
|
+
classes = []
|
|
90
|
+
|
|
91
|
+
return classes unless !link.nil? && File.exists?(link)
|
|
92
|
+
|
|
93
|
+
IO.readlines(link).each { |line|
|
|
94
|
+
if line =~ rgx
|
|
95
|
+
classes << $1.to_s
|
|
96
|
+
end
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
classes
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|