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 +4 -4
- data/.travis.yml +4 -3
- data/CHANGELOG.md +8 -0
- data/README.md +70 -9
- data/bin/git-gsub +1 -1
- data/git-gsub.gemspec +1 -0
- data/lib/git/gsub.rb +105 -21
- data/lib/git/gsub/version.rb +1 -1
- data/spec/git_gsub_spec.rb +50 -22
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83807335e80f98fadabfb3952e2791973f3402fc
|
4
|
+
data.tar.gz: 8cb9229c0bfdc60b580fafc80269424f33fe041c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e26c83eb04af98873ef2b479f408eea7b29ee997ac38a835cb58f918a3c1a3f4924f8238b2f9d03de000e71247104276265c400ab7a41b8a8de589e165f83a0
|
7
|
+
data.tar.gz: 806e3d07a225082419864df8fd74a1dc3d0b0aa37c47f6363c93a27298e874b826efe16fe39a2acffba8ec49e95f362306dd0eaec98e853261c779710a9e3a0f
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
##
|
50
|
+
## Experimental features
|
51
|
+
To substitute `CommonLisp` with `VisualBasic` with case-awareness:
|
39
52
|
|
40
53
|
```
|
41
|
-
$
|
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
|
-
|
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
|
-
|
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
|
-
|
109
|
+
## Installation
|
49
110
|
|
50
111
|
```
|
51
|
-
$
|
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
|
117
|
+
Maybe on many *nix like OS which has Perl and sed.
|
57
118
|
|
58
119
|
## Contributing
|
59
120
|
|
data/bin/git-gsub
CHANGED
data/git-gsub.gemspec
CHANGED
@@ -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"
|
data/lib/git/gsub.rb
CHANGED
@@ -1,14 +1,63 @@
|
|
1
|
-
require
|
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
|
-
|
8
|
-
|
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
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
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
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
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
|
data/lib/git/gsub/version.rb
CHANGED
data/spec/git_gsub_spec.rb
CHANGED
@@ -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
|
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
|
24
|
-
Git::Gsub.
|
25
|
-
|
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
|
31
|
-
run_in_directory_with_a_file
|
32
|
-
Git::Gsub.
|
33
|
-
|
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
|
39
|
-
run_in_directory_with_a_file
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
50
|
-
Git::Gsub.
|
51
|
-
expect(`ls`).to eql "
|
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.
|
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-
|
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
|