vbsmin 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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/bin/vbsmin +52 -0
- data/lib/vbsmin.rb +148 -0
- data/lib/vbsmin/version.rb +5 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f20bc497c7112197f64f96e3c8c3da2011532550cc2b7394bda862f9f1202390
|
4
|
+
data.tar.gz: 6d15264fe085ef8ab8312aa50052a137b2b756a559064ee7defae8a32c51956d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 04d51468991b87872b94e50a7941cd9836a4dda21f5354460359fed834362996a8be448e53db896951f7ac99008765b4ea622eadb5368916eba98c34e5fde863
|
7
|
+
data.tar.gz: 79666d44546ff04c6f6b8064d2cb779a61a4b044043d9b4396c96f49b70c7324a479f6f9e8eef55554cc7b1dcd199be1cb46b3a6126e3e78df4337f0dfc4dbea
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Alexandre ZANNI
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/bin/vbsmin
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Ruby internal
|
5
|
+
require 'pp'
|
6
|
+
# Project internal
|
7
|
+
require 'vbsmin'
|
8
|
+
# External
|
9
|
+
require 'docopt'
|
10
|
+
require 'paint'
|
11
|
+
|
12
|
+
doc = <<~DOCOPT
|
13
|
+
vbsmin - VBScript minifier
|
14
|
+
|
15
|
+
Usage:
|
16
|
+
vbsmin [options] <filepath>
|
17
|
+
vbsmin -h | --help
|
18
|
+
vbsmin --version
|
19
|
+
|
20
|
+
Options:
|
21
|
+
--no-color Disable colorized output
|
22
|
+
--debug Display arguments
|
23
|
+
-h, --help Show this screen
|
24
|
+
--version Show version
|
25
|
+
|
26
|
+
Examples:
|
27
|
+
vbsmin samples/pyenv.vbs
|
28
|
+
vbsmin --no-color samples/pyenv.vbs
|
29
|
+
DOCOPT
|
30
|
+
|
31
|
+
begin
|
32
|
+
args = Docopt.docopt(doc, version: VBSMin::VERSION)
|
33
|
+
Paint.mode = 0 if args['--no-color']
|
34
|
+
pp args if args['--debug']
|
35
|
+
# use case 1, using the tool
|
36
|
+
if args['<filepath>']
|
37
|
+
vm = VBSMin.new
|
38
|
+
vm.minify(args['<filepath>'])
|
39
|
+
print Paint['Original file size: ', :bold]
|
40
|
+
puts Paint["#{vm.input_size} bytes", :red]
|
41
|
+
print Paint['Minified file size: ', :bold]
|
42
|
+
puts Paint["#{vm.output_size} bytes", :green]
|
43
|
+
print Paint['Size saved: ', :bold]
|
44
|
+
puts Paint["#{vm.diff_size} bytes", :green, :inverse]
|
45
|
+
puts "\nOriginal file path: #{vm.original_filepath}"
|
46
|
+
puts "Minified file path: #{vm.min_filepath}"
|
47
|
+
end
|
48
|
+
# use case 2, help: already handled by docopt
|
49
|
+
# use case 3, version: already handled by docopt
|
50
|
+
rescue Docopt::Exit => e
|
51
|
+
puts e.message
|
52
|
+
end
|
data/lib/vbsmin.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Ruby internal
|
4
|
+
require 'fileutils'
|
5
|
+
# Project internal
|
6
|
+
require 'vbsmin/version'
|
7
|
+
|
8
|
+
# Global VBSmin class
|
9
|
+
class VBSMin
|
10
|
+
# Constants
|
11
|
+
include Version
|
12
|
+
|
13
|
+
# @return [Integer] Size (in bytes) of the original file
|
14
|
+
attr_reader :input_size
|
15
|
+
|
16
|
+
# @return [Integer] Size (in bytes) of the minified file
|
17
|
+
attr_reader :output_size
|
18
|
+
|
19
|
+
# @return [Integer] Saved size (in bytes)
|
20
|
+
attr_reader :diff_size
|
21
|
+
|
22
|
+
# @return [String] Path of the original file
|
23
|
+
attr_reader :original_filepath
|
24
|
+
|
25
|
+
# @return [String] Path of the minified file
|
26
|
+
attr_reader :min_filepath
|
27
|
+
|
28
|
+
# Instantiate a VBSmin object
|
29
|
+
def initialize
|
30
|
+
@input_size = nil
|
31
|
+
@output_size = nil
|
32
|
+
@diff_size = nil
|
33
|
+
@original_filepath = nil
|
34
|
+
@min_filepath = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
# Minify a VBScript file (make a minified copy: file.min.vbs)
|
38
|
+
# @param filepath [String] Path to the VBS file to minify
|
39
|
+
# @return [String] Path of the minified file
|
40
|
+
def minify(filepath)
|
41
|
+
@original_filepath = filepath
|
42
|
+
# Count number of line of input
|
43
|
+
input_lines = IO.readlines(filepath).length
|
44
|
+
# File streaming
|
45
|
+
File.open(min_ext, 'w') do |output|
|
46
|
+
File.foreach(filepath).with_index(1) do |line, i|
|
47
|
+
eol = ':' # End of file char
|
48
|
+
# Remove inline comment (must be before whitespace striping)
|
49
|
+
line = inline_comment(line)
|
50
|
+
# Remove leading and trailing whitespaces: null, horizontal tab, line feed,
|
51
|
+
# vertical tab, form feed, carriage return, space
|
52
|
+
line.strip!
|
53
|
+
# Remove comments except inline ones (must be after whitespace striping)
|
54
|
+
line = '' if line[0] == "'" || line[0..2].upcase == 'REM'
|
55
|
+
# Remove space when several spaces between two keywords
|
56
|
+
line = internal_space(line)
|
57
|
+
# Remove line splitting
|
58
|
+
line[-1] = '' && eol = '' if line[-2..] == ' _'
|
59
|
+
# Write processed line unless it is a blank line or the last line
|
60
|
+
unless line.empty?
|
61
|
+
output.write(line)
|
62
|
+
output.write(eol) unless i == input_lines
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
calc_size
|
67
|
+
return @min_filepath
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# Create the path of the minified file from the path of the original file
|
73
|
+
def min_ext
|
74
|
+
extension = File.extname(@original_filepath).downcase
|
75
|
+
abort 'Not a .vbs file' unless extension == '.vbs'
|
76
|
+
min_filepath = @original_filepath.chomp(extension) + '.min.vbs'
|
77
|
+
@min_filepath = min_filepath
|
78
|
+
return min_filepath
|
79
|
+
end
|
80
|
+
|
81
|
+
# Calculate the size of the files and the saved size
|
82
|
+
def calc_size
|
83
|
+
@input_size = File.size(@original_filepath)
|
84
|
+
@output_size = File.size(@min_filepath)
|
85
|
+
@diff_size = @input_size - @output_size
|
86
|
+
end
|
87
|
+
|
88
|
+
# DO NOT USE, use internal_space instead()
|
89
|
+
def internal_space_old(line)
|
90
|
+
arr = []
|
91
|
+
single_quote = line.count('"')
|
92
|
+
# This method won't work when there is two consecutive double quote
|
93
|
+
# so we must replace them else they will get removed.
|
94
|
+
line.gsub!('""', '☠')
|
95
|
+
line.split('"').each_with_index do |item, i|
|
96
|
+
# if odd number of double quote we are in a string else we are out
|
97
|
+
# process only if out of a string
|
98
|
+
item.gsub!(/ +/, ' ') if i.even?
|
99
|
+
arr.push(item)
|
100
|
+
end
|
101
|
+
output = arr.join('"')
|
102
|
+
output.gsub!('☠', '""')
|
103
|
+
output += '"' unless single_quote == output.count('"')
|
104
|
+
return output
|
105
|
+
end
|
106
|
+
|
107
|
+
# Remove extra spaces (several spaces between two keywords except in a string)
|
108
|
+
# More reliable than internal_space_old which use string replacement and string
|
109
|
+
# split
|
110
|
+
def internal_space(line)
|
111
|
+
# For each single quote, if there is an odd number of double quote before
|
112
|
+
# we are in a string, but if there is an even number of double quote before
|
113
|
+
# we are out of a string.
|
114
|
+
double_quote = 0
|
115
|
+
previous_char = nil
|
116
|
+
output = ''
|
117
|
+
i = 0
|
118
|
+
line.each_char do |c|
|
119
|
+
double_quote += 1 if c == '"'
|
120
|
+
output += c unless previous_char == ' ' && c == ' ' && double_quote.even?
|
121
|
+
i += 1
|
122
|
+
previous_char = c
|
123
|
+
end
|
124
|
+
return output
|
125
|
+
end
|
126
|
+
|
127
|
+
# Remove inline comments
|
128
|
+
# In VBS there is no single quote strings so it's safe to remove until the end
|
129
|
+
# of string when ecountering a single quote.
|
130
|
+
# The only case to handle if is a single quote appears in a double quote string.
|
131
|
+
def inline_comment(line)
|
132
|
+
# For each single quote, if there is an odd number of double quote before
|
133
|
+
# we are in a string, but if there is an even number of double quote before
|
134
|
+
# we are out of a string so this is an inline comment and we can remove all
|
135
|
+
# that comes after.
|
136
|
+
double_quote = 0
|
137
|
+
i = 0
|
138
|
+
line.each_char do |c|
|
139
|
+
double_quote += 1 if c == '"'
|
140
|
+
if c == "'" && double_quote.even?
|
141
|
+
line = line[...i]
|
142
|
+
break
|
143
|
+
end
|
144
|
+
i += 1
|
145
|
+
end
|
146
|
+
return line
|
147
|
+
end
|
148
|
+
end
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vbsmin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexandre ZANNI
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-06-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: docopt
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: paint
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: commonmarker
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.21'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.21'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: github-markup
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '5.12'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '5.12'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '13.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '13.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: redcarpet
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.5'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.5'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.80'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.80'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: yard
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.9'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.9'
|
153
|
+
description: VBScript minifier CLI tool and library
|
154
|
+
email: alexandre.zanni@engineer.com
|
155
|
+
executables:
|
156
|
+
- vbsmin
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- LICENSE
|
161
|
+
- bin/vbsmin
|
162
|
+
- lib/vbsmin.rb
|
163
|
+
- lib/vbsmin/version.rb
|
164
|
+
homepage: https://noraj.github.io/vbsmin/
|
165
|
+
licenses:
|
166
|
+
- MIT
|
167
|
+
metadata:
|
168
|
+
yard.run: yard
|
169
|
+
bug_tracker_uri: https://github.com/noraj/vbsmin/issues
|
170
|
+
changelog_uri: https://github.com/noraj/vbsmin/blob/master/docs/CHANGELOG.md
|
171
|
+
documentation_uri: https://noraj.github.io/vbsmin/
|
172
|
+
homepage_uri: https://noraj.github.io/vbsmin/
|
173
|
+
source_code_uri: https://github.com/noraj/vbsmin/
|
174
|
+
post_install_message:
|
175
|
+
rdoc_options: []
|
176
|
+
require_paths:
|
177
|
+
- lib
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - "~>"
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '2.7'
|
183
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
requirements: []
|
189
|
+
rubygems_version: 3.1.2
|
190
|
+
signing_key:
|
191
|
+
specification_version: 4
|
192
|
+
summary: VBScript minifier
|
193
|
+
test_files: []
|