code_caser 0.0.4 → 0.1.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 +4 -4
- data/README.md +3 -2
- data/bin/code_caser +56 -15
- data/lib/code_caser/analyzer.rb +74 -0
- data/lib/code_caser/caser.rb +8 -17
- data/lib/code_caser/converters.rb +42 -4
- data/lib/code_caser/path_converter.rb +20 -0
- data/lib/code_caser/version.rb +1 -1
- data/lib/code_caser.rb +17 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dff1ea58bc087c06e16db95c43a0ea694919d88e
|
4
|
+
data.tar.gz: 1d538e2ec7a88d444f52fa6760927ce11cfec071
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c3af265ff4d2e4bb8b03af507ed976b48da522b361a637965a2bc2530d61cba00d063b7cdcd77b86c9163d528841fb3646951f218981e529053c27dadc8755b
|
7
|
+
data.tar.gz: 2eeefc372f4022f8fbcd612a93cda2cf236273b5924542de0284138f3bc17fb96838ff446b8548b39a7da9904e2e14fc7e54e7d0e32828f3f8d0b32bcb6a5775
|
data/README.md
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# CodeCaser
|
2
|
-
|
3
2
|
A simple Ruby command line utility that converts files from camelCase to snake_case and vice-versa.
|
4
3
|
|
5
4
|
## Installation
|
6
|
-
|
7
5
|
To install:
|
8
6
|
```
|
9
7
|
$ gem install code_caser
|
@@ -34,3 +32,6 @@ $ code_caser to_camel --path=/folder/subfolder/*.js
|
|
34
32
|
Use the ```--verbose``` flag to print any changes made to each file to the terminal.
|
35
33
|
|
36
34
|
By default, backup copies of each file converted will be saved to a timestamped backup folder in the ```--path``` directory. You can prevent backups from being created by passing in the ```--no-save``` flag.
|
35
|
+
|
36
|
+
## License
|
37
|
+
code_caser is available under the MIT License.
|
data/bin/code_caser
CHANGED
@@ -3,24 +3,65 @@ require "rubygems"
|
|
3
3
|
require "thor"
|
4
4
|
require_relative "../lib/code_caser"
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
module CodeCaser
|
7
|
+
|
8
|
+
module FileArgs
|
9
|
+
def self.included(base)
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
module ClassMethods
|
13
|
+
def annotate(method_name, desc, save_option=true)
|
14
|
+
class_eval do # help keep things DRY:
|
15
|
+
desc method_name, desc
|
16
|
+
option :path, type: :string, required: true
|
17
|
+
option :ignore_after, type: :string, required: false,
|
18
|
+
desc: "ignore all text in each line after the string IGNORE_AFTER"
|
19
|
+
option :verbose, type: :boolean, default: false
|
20
|
+
option :save, type: :boolean, default: true if save_option
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class AnalyzerCLI < Thor
|
27
|
+
include FileArgs
|
28
|
+
annotate "to_camel", "checks if any existing identifiers would be overridden by converting to camelCase", false
|
29
|
+
def to_camel
|
30
|
+
CodeCaser::Analyze::to_camel(options)
|
31
|
+
end
|
32
|
+
annotate "to_snake", "checks if any existing identifiers would be overridden by converting to snake_case", false
|
33
|
+
def to_snake
|
34
|
+
CodeCaser::Analyze::to_snake(options)
|
35
|
+
end
|
14
36
|
end
|
15
37
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
38
|
+
class CaserCLI < Thor
|
39
|
+
include FileArgs
|
40
|
+
annotate "to_camel", "converts files in PATH from snake_case to camelCase"
|
41
|
+
def to_camel
|
42
|
+
CodeCaser::to_camel(options)
|
43
|
+
end
|
44
|
+
|
45
|
+
annotate "to_snake", "converts files in PATH from camelCase to snake_case"
|
46
|
+
def to_snake
|
47
|
+
CodeCaser::to_snake(options)
|
48
|
+
end
|
49
|
+
|
50
|
+
# TODO: add methods to convert a single string
|
51
|
+
|
52
|
+
register CodeCaser::AnalyzerCLI, "analyze", "analyze to_camel",
|
53
|
+
"checks if any existing identifiers would be overridden by converting to camelCase" #, options
|
54
|
+
|
55
|
+
register CodeCaser::AnalyzerCLI, "analyze", "analyze to_snake",
|
56
|
+
"checks if any existing identifiers would be overridden by converting to snake_case" #, options
|
57
|
+
|
58
|
+
desc "--version, -v", "print the version number"
|
59
|
+
def __print_version
|
60
|
+
puts CodeCaser::VERSION
|
61
|
+
end
|
62
|
+
map %w(--version -v) => :__print_version
|
22
63
|
end
|
23
64
|
|
24
65
|
end
|
25
66
|
|
26
|
-
CaserCLI.start
|
67
|
+
CodeCaser::CaserCLI.start
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module CodeCaser
|
2
|
+
|
3
|
+
# This class scans the provided files to determine if any converted identifiers
|
4
|
+
# overlap with existing identifiers.
|
5
|
+
class Analyzer
|
6
|
+
def initialize(opts)
|
7
|
+
@converter = opts.fetch(:converter)
|
8
|
+
@files = PathConverter.new(opts.fetch(:path)).get_files
|
9
|
+
@verbose = opts.fetch(:verbose, false)
|
10
|
+
@existing_identifiers = {}
|
11
|
+
@new_identifiers = {}
|
12
|
+
@overlapping_identifiers = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def analyze
|
16
|
+
load_existing_identifiers
|
17
|
+
@files.each { |f| analyze_file(f) if File.file?(f) }
|
18
|
+
puts @existing_identifiers.keys.sort.inspect
|
19
|
+
print_new_identifiers if @verbose
|
20
|
+
@overlapping_identifiers = @new_identifiers.select {|k,v| @existing_identifiers.key?(k) }.keys
|
21
|
+
print_overlap
|
22
|
+
end
|
23
|
+
|
24
|
+
def load_existing_identifiers
|
25
|
+
@files.each { |f| load_existing_identifiers_from_file(f) if File.file?(f) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_existing_identifiers_from_file(file_path)
|
29
|
+
puts "loading file: #{file_path}" if @verbose
|
30
|
+
IO.foreach(file_path) { |line| load_existing_identifiers_from_line(line) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def load_existing_identifiers_from_line(line)
|
34
|
+
split_line(line).each { |l| @existing_identifiers[l] = true }
|
35
|
+
end
|
36
|
+
|
37
|
+
def analyze_file(file_path)
|
38
|
+
puts "loading file: #{file_path}" if @verbose
|
39
|
+
IO.foreach(file_path) { |line| analyze_line(line) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def print_overlap
|
43
|
+
if @overlapping_identifiers.empty?
|
44
|
+
puts "\nNo overlapping identifiers found.".colorize(:green)
|
45
|
+
else
|
46
|
+
puts "\nThe following identifiers would overlap with existing names:".colorize(:yellow)
|
47
|
+
puts @overlapping_identifiers.join(",").colorize(:yellow)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def print_new_identifiers
|
52
|
+
puts "\nThe following identifiers would be replaced:".colorize(:yellow)
|
53
|
+
@new_identifiers.sort.to_h.each {|k,v| puts "#{v} -> #{k.colorize(:green)}" }
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def analyze_line(original_line)
|
59
|
+
# discard anything after the ignore_after identifier
|
60
|
+
original_identifiers = @converter.chop(original_line).split(/\W+/)
|
61
|
+
original_identifiers.each do |identifier|
|
62
|
+
if identifier != (new_identifier = @converter.convert_line(identifier))
|
63
|
+
@new_identifiers[new_identifier] = identifier
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def split_line(line)
|
69
|
+
@converter.chop(line).split(/\W+/)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/lib/code_caser/caser.rb
CHANGED
@@ -2,17 +2,16 @@ require 'fileutils'
|
|
2
2
|
require 'colorize'
|
3
3
|
|
4
4
|
module CodeCaser
|
5
|
-
|
6
5
|
class Caser
|
7
6
|
def initialize(opts = {})
|
8
|
-
@converter
|
9
|
-
@
|
10
|
-
@save
|
11
|
-
@verbose
|
7
|
+
@converter = opts.fetch(:converter)
|
8
|
+
@path_converter = PathConverter.new(opts.fetch(:path))
|
9
|
+
@save = opts.fetch(:save, true)
|
10
|
+
@verbose = opts.fetch(:verbose, false)
|
12
11
|
end
|
13
12
|
|
14
13
|
def start
|
15
|
-
files = get_files
|
14
|
+
files = @path_converter.get_files
|
16
15
|
if files.empty?
|
17
16
|
puts "File or folder not found.\n"
|
18
17
|
return
|
@@ -30,12 +29,8 @@ module CodeCaser
|
|
30
29
|
|
31
30
|
private
|
32
31
|
|
33
|
-
def get_files
|
34
|
-
Dir.glob(File.expand_path(@path))
|
35
|
-
end
|
36
|
-
|
37
32
|
def backup_folder
|
38
|
-
@backup_folder ||=
|
33
|
+
@backup_folder ||= @path_converter.join("_backup_#{Time.new.to_i}")
|
39
34
|
end
|
40
35
|
|
41
36
|
def convert_files(files)
|
@@ -53,16 +48,12 @@ module CodeCaser
|
|
53
48
|
FileUtils.rm(file_path)
|
54
49
|
f = File.new(file_path, "w+")
|
55
50
|
IO.foreach(backup_file_path) do |line|
|
56
|
-
f.puts(convert_line(line))
|
51
|
+
f.puts(convert_line(line.chomp))
|
57
52
|
end
|
58
53
|
end
|
59
54
|
|
60
55
|
def convert_line(line)
|
61
|
-
|
62
|
-
puts " " + line.strip
|
63
|
-
puts " " + converted_line.strip.colorize(:green)
|
64
|
-
end
|
65
|
-
converted_line
|
56
|
+
@converter.convert_line(line, @verbose)
|
66
57
|
end
|
67
58
|
|
68
59
|
def user_aborted?(files)
|
@@ -1,6 +1,44 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
|
1
3
|
module CodeCaser
|
2
|
-
class
|
3
|
-
def
|
4
|
+
class Converter
|
5
|
+
def initialize(opts={})
|
6
|
+
if opts[:ignore_after]
|
7
|
+
@ignore_after = Regexp.new('(^.*?)(' + Regexp.escape(opts[:ignore_after]) + '.*)')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def convert_line(line, verbose=false)
|
12
|
+
converted_line = if @ignore_after && (data = match_data(line))
|
13
|
+
convert_string(data[1]) + data[2]
|
14
|
+
else
|
15
|
+
convert_string(line)
|
16
|
+
end
|
17
|
+
if verbose && converted_line != line
|
18
|
+
puts "\n " + line.strip
|
19
|
+
puts " " + converted_line.strip.colorize(:green)
|
20
|
+
end
|
21
|
+
|
22
|
+
converted_line
|
23
|
+
end
|
24
|
+
|
25
|
+
def chop(line)
|
26
|
+
@ignore_after && (data = match_data(line)) ? data[1] : line
|
27
|
+
end
|
28
|
+
|
29
|
+
def convert_string # concrete Converter implementations must supply this method
|
30
|
+
raise NotImplementedError
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def match_data(line)
|
36
|
+
line.match(@ignore_after)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class CamelConverter < Converter
|
41
|
+
def convert_string(str)
|
4
42
|
match = false
|
5
43
|
output = str.reverse.gsub(/([a-z]+[A-Z]\B)(.)(?!\w*[A-Z]\b)/) { |s|
|
6
44
|
match = true
|
@@ -17,8 +55,8 @@ module CodeCaser
|
|
17
55
|
end
|
18
56
|
end
|
19
57
|
|
20
|
-
class SnakeConverter
|
21
|
-
def
|
58
|
+
class SnakeConverter < Converter
|
59
|
+
def convert_string(str)
|
22
60
|
str.gsub(/([a-z0-9])_([a-z0-9])/) { |s| $1 + $2.upcase }
|
23
61
|
end
|
24
62
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CodeCaser
|
2
|
+
class PathConverter
|
3
|
+
|
4
|
+
def initialize(path)
|
5
|
+
@path = File.directory?(path) ? File.join(path, "*") : path
|
6
|
+
end
|
7
|
+
|
8
|
+
def dirname
|
9
|
+
File.expand_path(File.dirname(@path))
|
10
|
+
end
|
11
|
+
|
12
|
+
def join(name)
|
13
|
+
File.join(dirname + name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_files
|
17
|
+
Dir.glob(File.expand_path(@path))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/code_caser/version.rb
CHANGED
data/lib/code_caser.rb
CHANGED
@@ -1,11 +1,22 @@
|
|
1
|
+
|
1
2
|
Dir[File.dirname(__FILE__) + '/code_caser/*.rb'].each {|file| require file }
|
2
3
|
|
3
4
|
module CodeCaser
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def self.to_camel(opts)
|
6
|
+
Caser.new(opts.merge({ converter: SnakeConverter.new(opts) })).start
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.to_snake(opts)
|
10
|
+
Caser.new(opts.merge({ converter: CamelConverter.new(opts) })).start
|
11
|
+
end
|
12
|
+
|
13
|
+
module Analyze
|
14
|
+
def self.to_camel(opts)
|
15
|
+
Analyzer.new(opts.merge(converter: SnakeConverter.new(opts))).analyze
|
16
|
+
end
|
7
17
|
|
8
|
-
|
9
|
-
|
10
|
-
|
18
|
+
def self.to_snake(opts)
|
19
|
+
Analyzer.new(opts.merge(converter: CamelConverter.new(opts))).analyze
|
20
|
+
end
|
21
|
+
end
|
11
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: code_caser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Lovell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -71,8 +71,10 @@ files:
|
|
71
71
|
- Rakefile
|
72
72
|
- bin/code_caser
|
73
73
|
- lib/code_caser.rb
|
74
|
+
- lib/code_caser/analyzer.rb
|
74
75
|
- lib/code_caser/caser.rb
|
75
76
|
- lib/code_caser/converters.rb
|
77
|
+
- lib/code_caser/path_converter.rb
|
76
78
|
- lib/code_caser/version.rb
|
77
79
|
homepage: https://github.com/stephenjlovell/code_caser
|
78
80
|
licenses:
|