lock_block 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p194
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lock_block.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Joe Nelson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Lock Block
2
+
3
+ Mark sections of Ruby code as important. Check if these sections
4
+ have changed. The difference checking intelligently ignores code
5
+ formatting.
6
+
7
+ ## Usage
8
+
9
+ Installing this gem provides a command line program to annotate Ruby
10
+ code.
11
+
12
+ `lock_block [options] [filename]`
13
+
14
+ If a file is not specified, the program will read from STDIN.
15
+
16
+ <table>
17
+ <caption>Options</caption>
18
+ <tbody>
19
+ <tr>
20
+ <td>--lock, -l</td>
21
+ <td>(default) Lock the block. Wraps code in tagged annotation.</td>
22
+ </tr>
23
+ <tr>
24
+ <td>--check, -c</td>
25
+ <td>List all blocks thare are outdated.</td>
26
+ </tr>
27
+ <tr>
28
+ <td>--resolve, -r</td>
29
+ <td>Update tags in annotation to mark blocks as up to date.</td>
30
+ </tr>
31
+ </tbody>
32
+ </table>
33
+
34
+ ## Vim Configuration
35
+
36
+ Lock Block is good on its own but better with Vim. Add the
37
+ following to your `~/.vimrc`:
38
+
39
+ function! LockBlockCheck(arg)
40
+ let tmp1=&grepprg
41
+ set grepprg=lock_block
42
+ exe "silent! grep -c ".a:arg
43
+ exe "cw"
44
+ let &grepprg=tmp1
45
+ endf
46
+ command! -nargs=1 LBCheck call LockBlockCheck(<f-args>)
47
+ " Check for broken locks in current file
48
+ nmap <leader>lc :LBCheck %<CR>
49
+
50
+ " Lock selected block
51
+ vmap <silent> <Leader>ll !lock_block<CR>
52
+ " Resolved selected blocks
53
+ vmap <silent> <Leader>lr !lock_block -r<CR>
54
+
55
+ This will give you three commands:
56
+
57
+ <table>
58
+ <tbody>
59
+ <tr>
60
+ <td>&lt;leader&gt;lc</td>
61
+ <td>Check the current file, open problems in quicklist.</td>
62
+ </tr>
63
+ <tr>
64
+ <td>&lt;leader&gt;ll</td>
65
+ <td>Replace selection with locked version.</td>
66
+ </tr>
67
+ <tr>
68
+ <td>&lt;leader&gt;lr</td>
69
+ <td>Resolve all blocks in selected region.</td>
70
+ </tr>
71
+ </tbody>
72
+ </table>
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.pattern = "test/*_spec.rb"
6
+ end
7
+
8
+ task default: [:test]
data/bin/lock_block ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ require 'lock_block'
3
+ require 'trollop'
4
+
5
+ opts = Trollop::options do
6
+ opt :lock, "Annotate input with lock hash", default: true
7
+ opt :check, "Check input for broken locks"
8
+ opt :resolve, "Update all lock tags in input"
9
+ end
10
+
11
+ input = ARGF.read
12
+ if opts[:check]
13
+ errs = LockBlock.broken_locks input
14
+ if errs.any?
15
+ errs.each do |error|
16
+ puts [ARGF.path, error[:line], error[:got]].join ':'
17
+ end
18
+ exit 1
19
+ end
20
+ elsif opts[:resolve]
21
+ puts LockBlock.resolve input
22
+ else
23
+ puts LockBlock.lock input
24
+ end
@@ -0,0 +1,3 @@
1
+ module LockBlock
2
+ VERSION = "0.0.1"
3
+ end
data/lib/lock_block.rb ADDED
@@ -0,0 +1,53 @@
1
+ require 'lock_block/version'
2
+ require 'ripper'
3
+ require 'digest/sha1'
4
+
5
+ module LockBlock
6
+ def LockBlock.lock source
7
+ indent = source.match(/^(\s+)/) ? $1 : ''
8
+ tag = tag source
9
+ "#{indent}# lock do #{tag}\n#{source}#{indent}# lock end #{tag}"
10
+ end
11
+
12
+ def LockBlock.resolve source
13
+ tags(source).each do |tag|
14
+ resolved_tag = tag innards(source, tag)
15
+ source = update_tag source, tag, resolved_tag
16
+ end
17
+ source
18
+ end
19
+
20
+ def LockBlock.broken_locks source
21
+ broken = []
22
+ source.lines.each_with_index do |line, number|
23
+ if tags(line).any?
24
+ got = tags(line).first
25
+ expected = tag innards(source, got)
26
+ if got != expected
27
+ broken.push({line: number+1, expected: expected, got: got})
28
+ end
29
+ end
30
+ end
31
+ broken
32
+ end
33
+
34
+ def LockBlock.tag source
35
+ tokens = Ripper.tokenize(source).select do |t|
36
+ t.gsub(/\s+/, "") != ''
37
+ end
38
+ Digest::SHA1.hexdigest tokens.to_s
39
+ end
40
+
41
+ def LockBlock.tags source
42
+ source.scan(/# lock do ([a-f0-9]{40})/).map &:first
43
+ end
44
+
45
+ def LockBlock.update_tag source, old_tag, new_tag
46
+ source.gsub /# lock (do|end) #{old_tag}/, "# lock \\1 #{new_tag}"
47
+ end
48
+
49
+ def LockBlock.innards source, tag
50
+ match = source.match /# lock do #{tag}\n(.*?)# lock end #{tag}/m
51
+ match ? match[1] : ''
52
+ end
53
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'lock_block/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "lock_block"
8
+ gem.version = LockBlock::VERSION
9
+ gem.authors = ["Joe Nelson"]
10
+ gem.email = ["cred+github@begriffs.com"]
11
+ gem.description = %q{Mark code blocks important, monitor them}
12
+ gem.summary = %q{Provides command-line tool to annotate and check blocks of code}
13
+ gem.homepage = "https://github.com/begriffs/lock_block"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.required_ruby_version = '>= 1.9'
20
+
21
+ gem.add_dependency 'trollop', '~> 2.0'
22
+ end
@@ -0,0 +1,92 @@
1
+ require 'minitest/autorun'
2
+ require 'lock_block'
3
+
4
+ code_block = <<EOT
5
+ def foo x
6
+ x + 1
7
+ end
8
+ EOT
9
+
10
+ code_block_dedent = <<EOT
11
+ def foo x
12
+ x + 1
13
+ end
14
+ EOT
15
+
16
+ code_block_outdated = <<EOT
17
+ # stuff
18
+ # lock do 0000000000000000000000000000000000000000
19
+ 1+1
20
+ # lock end 0000000000000000000000000000000000000000
21
+ # bother
22
+ # lock do 0000000000000000000000000000000000000000
23
+ 1+2
24
+ # lock end 0000000000000000000000000000000000000000
25
+ EOT
26
+
27
+ code_block_resolved = <<EOT
28
+ # stuff
29
+ # lock do 921fbda07b9630c541f486c666238d1c0d6384c8
30
+ 1+1
31
+ # lock end 921fbda07b9630c541f486c666238d1c0d6384c8
32
+ # bother
33
+ # lock do 921fbda07b9630c541f486c666238d1c0d6384c8
34
+ 1+2
35
+ # lock end 921fbda07b9630c541f486c666238d1c0d6384c8
36
+ EOT
37
+
38
+ describe LockBlock do
39
+ describe '#tag' do
40
+ it 'ignores spacing differences' do
41
+ LockBlock.tag('1+1').must_equal LockBlock.tag('1 + 1')
42
+ end
43
+
44
+ it 'respects constant differences' do
45
+ LockBlock.tag('1+1').wont_be_same_as LockBlock.tag('1+2')
46
+ end
47
+
48
+ it 'respects differing comments' do
49
+ LockBlock.tag('#hi').wont_be_same_as LockBlock.tag('#bye')
50
+ end
51
+
52
+ it 'ignores Ruby indentation' do
53
+ LockBlock.tag(code_block).must_equal LockBlock.tag(code_block_dedent)
54
+ end
55
+ end
56
+
57
+ describe '#lock' do
58
+ it 'wraps a block of code' do
59
+ code = "1+1\n"
60
+ h = LockBlock.tag code
61
+ wrapped_code = "# lock do #{h}\n1+1\n# lock end #{h}"
62
+ LockBlock.lock(code).must_equal wrapped_code
63
+ end
64
+ it 'matches indentation' do
65
+ code = "\t1+1\n"
66
+ h = LockBlock.tag code
67
+ wrapped_code = "\t# lock do #{h}\n\t1+1\n\t# lock end #{h}"
68
+ LockBlock.lock(code).must_equal wrapped_code
69
+ end
70
+ it 'leaves non-Ruby untouched' do
71
+ code = "It isn't Ruby, is it?\n"
72
+ expected_tag = LockBlock.tag code
73
+ wrapped_code = "# lock do #{expected_tag}\n#{code}# lock end #{expected_tag}"
74
+ LockBlock.lock(code).must_equal wrapped_code
75
+ end
76
+ end
77
+
78
+ describe '#resolve' do
79
+ it 'updates the hash on a block and leaves other lines untouched' do
80
+ LockBlock.resolve(code_block_outdated).must_equal code_block_resolved
81
+ end
82
+ end
83
+
84
+ describe '#broken_locks' do
85
+ it 'finds line numbers of lock blocks that are outdated' do
86
+ errs = LockBlock.broken_locks code_block_outdated
87
+ errs.length.must_equal 2
88
+ errs[0][:line].must_equal 2
89
+ errs[1][:line].must_equal 6
90
+ end
91
+ end
92
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lock_block
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joe Nelson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: trollop
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ description: Mark code blocks important, monitor them
31
+ email:
32
+ - cred+github@begriffs.com
33
+ executables:
34
+ - lock_block
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - .gitignore
39
+ - .rbenv-version
40
+ - Gemfile
41
+ - LICENSE.txt
42
+ - README.md
43
+ - Rakefile
44
+ - bin/lock_block
45
+ - lib/lock_block.rb
46
+ - lib/lock_block/version.rb
47
+ - lock_block.gemspec
48
+ - test/lock_block_spec.rb
49
+ homepage: https://github.com/begriffs/lock_block
50
+ licenses: []
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '1.9'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 1.8.24
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Provides command-line tool to annotate and check blocks of code
73
+ test_files:
74
+ - test/lock_block_spec.rb