git-gsub 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4bb2c9e366b42ad834a11590b47beebf6d866b1
4
- data.tar.gz: 12fa7b4d29e60e241eaf46e7f7f0f56016a5902b
3
+ metadata.gz: 83807335e80f98fadabfb3952e2791973f3402fc
4
+ data.tar.gz: 8cb9229c0bfdc60b580fafc80269424f33fe041c
5
5
  SHA512:
6
- metadata.gz: 91991a9c7329b9dcb883c5270577fa7779bb6a6f680dfd840aacdcac00fc79745a58a6c55744f2e1cad730fa39ddf6fc8e30876fbe4ad896b43b48cf852233b8
7
- data.tar.gz: 4b3e90f5d4706c5a47720f49448ee1f5cae3ac19af372b5f612add9507855ac31af1c2476a1432002d4020dfd3757a0af05e7484569db112ceef659d975c3b00
6
+ metadata.gz: 6e26c83eb04af98873ef2b479f408eea7b29ee997ac38a835cb58f918a3c1a3f4924f8238b2f9d03de000e71247104276265c400ab7a41b8a8de589e165f83a0
7
+ data.tar.gz: 806e3d07a225082419864df8fd74a1dc3d0b0aa37c47f6363c93a27298e874b826efe16fe39a2acffba8ec49e95f362306dd0eaec98e853261c779710a9e3a0f
@@ -1,5 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.0
4
- - 2.1.1
5
- - 2.1.2
3
+ - 2.1
4
+ - 2.2
5
+ - 2.3
6
+ - 2.4
@@ -1,6 +1,14 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.0.6]
5
+ ### Added
6
+ - Add option to substitute in camel/kebab/snake case
7
+ - Add option to rename files
8
+ ### Changed
9
+ - Do substitution with Perl, not sed to reduce platform issues
10
+ - No escape required to command line arguments
11
+
4
12
  ## [0.0.5] - 2017-05-23
5
13
  ### Fixed
6
14
  - Fix bug on assigning target directories
data/README.md CHANGED
@@ -4,13 +4,25 @@ A Git subcommand to do gsub in a repository
4
4
 
5
5
  ## Usage
6
6
 
7
- To substitute `Git` with `Subversion`, run
7
+ ```
8
+ Usage: git gsub [options] FROM TO [PATHS]
9
+ -v, --version Print version
10
+ --snake Experimental: substitute snake-cased expressions
11
+ --camel Experimental: substitute camel-cased expressions
12
+ --kebab Experimental: substitute kebab-cased expressions
13
+ --rename Rename files along with substitution
14
+ --dry-run Print commands to be run
15
+ ```
16
+
17
+ ## Example
18
+
19
+ To substitute `Git` with `Subversion`:
8
20
 
9
21
  ```
10
22
  $ git gsub Git Subversion
11
23
  ```
12
24
 
13
- Then you will get
25
+ Result:
14
26
 
15
27
  ```diff
16
28
  diff --git a/README.md b/README.md
@@ -35,25 +47,74 @@ index c30f093..03b7c4c 100755
35
47
  +Subversion::Gsub.run
36
48
  ```
37
49
 
38
- ## Installation
50
+ ## Experimental features
51
+ To substitute `CommonLisp` with `VisualBasic` with case-awareness:
39
52
 
40
53
  ```
41
- $ gem install git-gsub
54
+ $ git gsub CommonLisp VisualBasic --kebab --snake --camel
55
+ ```
56
+
57
+ Result:
58
+
59
+ ```diff
60
+ diff --git a/README.md b/README.md
61
+ index 2185dbf..393dbc6 100644
62
+ --- a/README.md
63
+ +++ b/README.md
64
+ @@ -1,4 +1,4 @@
65
+ -# CommonLisp common_lisp common-lisp
66
+ +# VisualBasic visual_basic visual-basic
67
+ ```
68
+
69
+ Substitute and rename file:
70
+
42
71
  ```
72
+ $ git gsub ruby haskell --rename --camel
73
+ ```
74
+
75
+ Result:
43
76
 
44
- ## Escaping special characters
77
+ ```diff
78
+ diff --git a/haskell.hs b/haskell.hs
79
+ new file mode 100644
80
+ index 0000000..ae86ce3
81
+ --- /dev/null
82
+ +++ b/haskell.hs
83
+ @@ -0,0 +1 @@
84
+ +putStrLn "Haskell"
85
+ diff --git a/haskell.rb b/haskell.rb
86
+ new file mode 100644
87
+ index 0000000..9f363d3
88
+ --- /dev/null
89
+ +++ b/haskell.rb
90
+ @@ -0,0 +1 @@
91
+ +puts "haskell"
92
+ diff --git a/ruby.hs b/ruby.hs
93
+ deleted file mode 100644
94
+ index 70db14d..0000000
95
+ --- a/ruby.hs
96
+ +++ /dev/null
97
+ @@ -1 +0,0 @@
98
+ -putStrLn "Ruby"
99
+ diff --git a/ruby.rb b/ruby.rb
100
+ deleted file mode 100644
101
+ index 966eb68..0000000
102
+ --- a/ruby.rb
103
+ +++ /dev/null
104
+ @@ -1 +0,0 @@
105
+ ```
45
106
 
46
- `git-gsub` uses `sed` internally, so escaping is same as it.
107
+ Caution: Case conversion is done with [ActiveSupport/Inflector](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html) , which substitutes `::` with `/`. This may cause unexpected result in the language other than Ruby.
47
108
 
48
- If you want to replace `git/gsub` with `svn/gsub`, the command will be
109
+ ## Installation
49
110
 
50
111
  ```
51
- $ git gsub "git\/gsub" "svn\/gsub"
112
+ $ gem install git-gsub
52
113
  ```
53
114
 
54
115
  ## Supported platforms
55
116
 
56
- Maybe on many *nix like OS which has sed/gsed.
117
+ Maybe on many *nix like OS which has Perl and sed.
57
118
 
58
119
  ## Contributing
59
120
 
@@ -1,4 +1,4 @@
1
1
  #! /usr/bin/env ruby
2
2
 
3
3
  require 'git/gsub'
4
- Git::Gsub.run
4
+ Git::Gsub.run(ARGV)
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.add_dependency "activesupport", "~> 4"
19
20
  spec.require_paths = ["lib"]
20
21
 
21
22
  spec.add_development_dependency "bundler", "~> 1.5"
@@ -1,14 +1,63 @@
1
- require "git/gsub/version"
1
+ require 'git/gsub/version'
2
+ require 'active_support/inflector'
3
+ require 'optparse'
2
4
  require 'shellwords'
5
+ require 'English'
3
6
 
4
7
  module Git
5
8
  module Gsub
6
- def self.run
7
- case ARGV.first
8
- when '-v', '--version'
9
+ def self.run(argv)
10
+ opts = OptionParser.new
11
+
12
+ self.class.module_eval do
13
+ define_method(:usage) do |msg = nil|
14
+ puts opts.to_s
15
+ puts "error: #{msg}" if msg
16
+ exit 1
17
+ end
18
+ end
19
+
20
+ options = {}
21
+ opts.on('-v', '--version', 'Print version') do |_v|
22
+ options[:version] = true
23
+ end
24
+
25
+ opts.on('--snake', 'Experimental: substitute snake-cased expressions') do |_v|
26
+ options[:snake] = true
27
+ end
28
+
29
+ opts.on('--camel', 'Experimental: substitute camel-cased expressions') do |_v|
30
+ options[:camel] = true
31
+ end
32
+
33
+ opts.on('--kebab', 'Experimental: substitute kebab-cased expressions') do |_v|
34
+ options[:kebab] = true
35
+ end
36
+
37
+ opts.on('--rename', 'Rename files along with substitution') do |_v|
38
+ options[:rename] = true
39
+ end
40
+
41
+ opts.on('--dry-run', 'Print commands to be run') do |_v|
42
+ options[:dry] = true
43
+ end
44
+
45
+ opts.banner = 'Usage: git gsub [options] FROM TO [PATHS]'
46
+
47
+ begin
48
+ args = opts.parse(argv)
49
+ rescue OptionParser::InvalidOption => e
50
+ usage e.message
51
+ end
52
+
53
+ if options[:version]
9
54
  version
10
55
  else
11
- gsub *ARGV
56
+ from, to, *paths = args
57
+ usage 'No FROM given' unless from
58
+ usage 'No TO given' unless to
59
+ Commands::Gsub.new(from, to, paths, options).run
60
+ Commands::Rename.new(from, to, paths, options).run if options[:rename]
12
61
  end
13
62
  end
14
63
 
@@ -16,29 +65,64 @@ module Git
16
65
  puts Git::Gsub::VERSION
17
66
  end
18
67
 
19
- def self.gsub *args
20
- from, to, *paths = args.map do |arg|
21
- Shellwords.escape arg if arg
22
- end
68
+ module Commands
69
+ class Command
70
+ attr_accessor :from, :to, :paths, :options
71
+
72
+ def initialize(from, to, paths = [], options = {})
73
+ @from = from
74
+ @to = to
75
+ @paths = paths
76
+ @options = options
77
+ end
78
+
79
+ def run_commands(commands)
80
+ if options[:dry]
81
+ commands.each { |c| puts c }
82
+ else
83
+ commands.each { |c| system c }
84
+ end
85
+ end
23
86
 
24
- if to.nil?
25
- abort "No argument to gsub was given"
87
+ def args
88
+ args = []
89
+ args << [from, to]
90
+ args << [from.camelcase, to.camelcase] if options[:camel]
91
+ args << [from.underscore, to.underscore] if options[:snake]
92
+ args << [from.underscore.dasherize, to.underscore.dasherize] if options[:kebab]
93
+
94
+ args.compact
95
+ end
26
96
  end
27
97
 
28
- target_files = (`git grep -l #{from} #{paths.join ' '}`).each_line.map(&:chomp).join ' '
98
+ class Gsub < Command
99
+ def run
100
+ commands = args.map { |from, to| build_command(from, to, paths) }.compact
101
+ run_commands commands
102
+ end
29
103
 
30
- if system_support_gsed?
31
- system %|gsed -i s/#{from}/#{to}/g #{target_files}|
32
- else
33
- system %|sed -i "" -e s/#{from}/#{to}/g #{target_files}|
104
+ def build_command(from, to, paths = [], _options = {})
105
+ from, to, *paths = [from, to, *paths].map { |s| Shellwords.escape s }
106
+
107
+ target_files = `git grep -l #{from} #{paths.join ' '}`.each_line.map(&:chomp).join ' '
108
+ return if target_files.empty?
109
+
110
+ %(perl -pi -e 's{#{from}}{#{to}}g' #{target_files})
111
+ end
34
112
  end
35
- end
36
113
 
37
- private
114
+ class Rename < Command
115
+ def run
116
+ commands = args.map { |from, to| build_command(from, to, paths) }
117
+ run_commands commands
118
+ end
119
+
120
+ def build_command(from, to, paths = [], _options = {})
121
+ from, to, *paths = [from, to, *paths].map { |s| Shellwords.escape s }
38
122
 
39
- def self.system_support_gsed?
40
- `which gsed`
41
- $?.success?
123
+ %[for f in $(git ls-files #{paths.join ' '} | grep #{from}); do mkdir -p $(dirname $(echo $f | sed 's/#{from}/#{to}/g')); git mv $f $(echo $f | sed 's/#{from}/#{to}/g') 2>/dev/null; done]
124
+ end
125
+ end
42
126
  end
43
127
  end
44
128
  end
@@ -1,5 +1,5 @@
1
1
  module Git
2
2
  module Gsub
3
- VERSION = "0.0.5"
3
+ VERSION = '0.0.6'.freeze
4
4
  end
5
5
  end
@@ -4,51 +4,79 @@ require 'git/gsub'
4
4
  require 'pry'
5
5
 
6
6
  describe 'git-gsub' do
7
- def run_in_directory_with_a_file content
7
+ def run_in_directory_with_a_file(filename, content)
8
8
  Dir.mktmpdir do |dir|
9
- filename = "FOO"
10
9
  Dir.chdir dir do
10
+ dirname = File.dirname(filename)
11
+ FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
11
12
  File.open(filename, 'w') { |f| f << content }
12
13
  `git init`
13
14
  `git config --local user.email "you@example.com"`
14
15
  `git config --local user.name "Your Name"`
15
16
  `git add .`
16
17
  `git commit -m init`
17
- yield filename
18
+ yield
18
19
  end
19
20
  end
20
21
  end
21
22
 
22
23
  it 'should substitute files' do
23
- run_in_directory_with_a_file "Git Subversion Bzr" do |filename|
24
- Git::Gsub.gsub "Bzr", "Mercurial"
25
- file = File.read(filename).chomp
26
- expect(file).to eq "Git Subversion Mercurial"
24
+ run_in_directory_with_a_file 'README.md', 'Git Subversion Bzr' do
25
+ Git::Gsub.run %w[Bzr Mercurial]
26
+ expect(File.read('README.md')).to eq 'Git Subversion Mercurial'
27
27
  end
28
28
  end
29
29
 
30
- it 'should escape well' do
31
- run_in_directory_with_a_file %|<h1 class="foo">| do |filename|
32
- Git::Gsub.gsub %|<h1 class="foo">|, %|<h1 class="bar">|
33
- file = File.read(filename).chomp
34
- expect(file).to eq %|<h1 class="bar">|
30
+ it 'should substitute files with case conversion' do
31
+ run_in_directory_with_a_file 'README.md', 'GitGsub git_gsub git-gsub' do
32
+ Git::Gsub.run %w[GitGsub SvnGsub --camel --kebab --snake]
33
+ expect(File.read('README.md')).to eq 'SvnGsub svn_gsub svn-gsub'
35
34
  end
36
35
  end
37
36
 
38
- it 'should raise error if second argument wasn\'t given' do
39
- run_in_directory_with_a_file "Git Subversion Bzr" do |filename|
40
- begin
41
- Git::Gsub.gsub "Bzr"
42
- rescue SystemExit => e
43
- expect(e.message).to match /No argument/
44
- end
37
+ it 'should escape well' do
38
+ run_in_directory_with_a_file 'README.md', %(<h1 class="foo">) do
39
+ Git::Gsub.run [%(<h1 class="foo">), %(<h1 class="bar">)]
40
+ expect(File.read('README.md')).to eq %(<h1 class="bar">)
41
+ end
42
+
43
+ run_in_directory_with_a_file 'README.md', %(git/gsub) do
44
+ Git::Gsub.run [%(git/gsub), %(svn/sub)]
45
+ expect(File.read('README.md')).to eq %(svn/sub)
46
+ end
47
+
48
+ run_in_directory_with_a_file 'README.md', %({git{svn}) do
49
+ Git::Gsub.run [%({git{svn}), %({hg{svn})]
50
+ expect(File.read('README.md')).to eq %({hg{svn})
45
51
  end
46
52
  end
47
53
 
48
54
  it 'should not create backup file' do
49
- run_in_directory_with_a_file "Git Subversion Bzr" do |filename|
50
- Git::Gsub.gsub "Bzr", "Darcs"
51
- expect(`ls`).to eql "FOO\n"
55
+ run_in_directory_with_a_file 'README.md', 'Git Subversion Bzr' do
56
+ Git::Gsub.run %w[Bzr Darcs]
57
+ expect(`ls`).to eql "README.md\n"
58
+ end
59
+ end
60
+
61
+ it 'should rename with --rename' do
62
+ run_in_directory_with_a_file 'README-git_gsub.md', 'GitGsub git_gsub git-gsub' do
63
+ Git::Gsub.run %w[GitGsub SvnGsub --snake --rename]
64
+ expect(`ls`).to eql "README-svn_gsub.md\n"
65
+ expect(File.read('README-svn_gsub.md')).to eq 'SvnGsub svn_gsub git-gsub'
66
+ end
67
+
68
+ run_in_directory_with_a_file 'lib/git.rb', 'puts "Git"' do
69
+ Git::Gsub.run %w[git svn --camel --rename]
70
+ expect(`ls lib`).to eql "svn.rb\n"
71
+ expect(File.read('lib/svn.rb')).to eq 'puts "Svn"'
72
+ end
73
+ end
74
+
75
+ it 'should do nothing if no file found' do
76
+ run_in_directory_with_a_file 'README-git_gsub.md', 'GitGsub git_gsub git-gsub' do
77
+ expect {
78
+ Git::Gsub.run %w[Atlanta Chicago --snake --rename]
79
+ }.not_to raise_error
52
80
  end
53
81
  end
54
82
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-gsub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fujimura Daisuke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-23 00:00:00.000000000 Z
11
+ date: 2017-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement