cucumber-slice 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,18 @@
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
18
+ .rbenv-version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cucumber-slice.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Test Double, LLC
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,29 @@
1
+ # CucumberSlice
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'cucumber_slice'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install cucumber_slice
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cucumber_slice'
4
+ require "cucumber_slice/cli"
5
+
6
+ CucumberSlice::Cli.start(ARGV)
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cucumber_slice/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "cucumber-slice"
8
+ gem.version = CucumberSlice::VERSION
9
+ gem.authors = ["Justin Searls"]
10
+ gem.email = ["searls@gmail.com"]
11
+ gem.description = <<-TEXT.gsub /^\s+/, ""
12
+ This tool can be used both locally and by build systems to
13
+ quickly narrow down which Cucumber features to run based on
14
+ which features may have been impacted by a code change.
15
+
16
+ Provides a CLI that filters Cucumber features based on
17
+ changes to production code since a specified git revision.
18
+
19
+ This is particular useful in systems of wide logical breadth,
20
+ where each individual commit is unlikely to have an impact on the
21
+ vast majority of the system's behavior.
22
+ TEXT
23
+ gem.summary = %q{Helps you narrow down which Cucumber features to run based on recent code changes}
24
+ gem.homepage = "https://github.com/testdouble/cucumber-slice"
25
+
26
+ gem.files = `git ls-files`.split($/)
27
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
28
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
29
+ gem.require_paths = ["lib"]
30
+
31
+ gem.add_dependency 'thor', '~> 0.14'
32
+ gem.add_dependency 'git', '~> 1.2.5'
33
+ end
@@ -0,0 +1 @@
1
+ require "cucumber_slice/version"
@@ -0,0 +1,39 @@
1
+ require 'thor'
2
+
3
+ module CucumberSlice
4
+ class Cli < Thor
5
+
6
+ desc "list", "list the features cucumber-slice thinks should run"
7
+ long_desc <<-LONGDESC
8
+ `cucumber-slice list` will print a list of all feature files that it
9
+ thinks should be run based on the current changeset of files since the
10
+ previous passing run.
11
+
12
+ > $ cucumber-slice list --since a3989b6
13
+
14
+ If the `since` option is not supplied, then HEAD is assumed and uncommitted
15
+ changes in your working
16
+
17
+ > $ cucumber-slice list
18
+
19
+ In the event you don't want to filter out any features (perhaps following an
20
+ unstable build), you can use the `--all` option to prevent filtering
21
+
22
+ > $ cucumber-slice list --since a3989b6 --all true
23
+
24
+ If the features you wish to filter are anywhere but <git_root>/features, you can specify them:
25
+
26
+ > $ cucumber-slice list --since a3989b6 --features "project/features"
27
+
28
+ LONGDESC
29
+ option :since, :type => :string, :default => "HEAD", :banner => "REV"
30
+ option :all, :type => :boolean, :default => false
31
+ option :features, :default => "features", :aliases => ["f"]
32
+ def list
33
+ require 'cucumber_slice/lists_features'
34
+ features = ListsFeatures.new(options[:features], options[:since], !!options[:all])
35
+ puts features.list
36
+ end
37
+
38
+ end
39
+ end
File without changes
@@ -0,0 +1,109 @@
1
+ require 'git'
2
+
3
+ module CucumberSlice
4
+ module ListCore
5
+ #feature stuff
6
+ def list_features_under(path)
7
+ glob = if path.include?('*')
8
+ path
9
+ else
10
+ File.join(path, "**/*.feature")
11
+ end
12
+
13
+ Dir.glob(File.join(git_repo_path, glob))
14
+ end
15
+
16
+ def format_feature_list(feature_list)
17
+ if feature_list.empty?
18
+ #point to an empty file to insist cucumber not run anything.
19
+ # cucumber's default behavior is to run everything when it's passed nothing.
20
+ # Super hacky stuff.
21
+ File.expand_path(File.join(File.dirname(__FILE__), "empty_file"))
22
+ else
23
+ feature_list.join(" ")
24
+ end
25
+ end
26
+
27
+ def dependencies_declared_in(feature_path)
28
+ dependencies = nil
29
+ File.open(feature_path) do |feature|
30
+ dependencies = feature.each_line.map do |line|
31
+ if match = line.match(/^#=\s*?depends_on (.*)$/)
32
+ match[1]
33
+ end
34
+ end.compact
35
+ end
36
+ dependencies
37
+ end
38
+
39
+ def any_dependencies_in_changeset?(dependencies, changeset)
40
+ (dependencies & changeset).any?
41
+ end
42
+
43
+ #file stuff
44
+ def find_up(dir, root_checked = false)
45
+ raise "No git repository found at or above `#{Dir.pwd}`!" if root_checked
46
+ is_dir?(File.join(dir, ".git")) ? dir : find_up(File.join(dir,'..'), is_root?(dir))
47
+ end
48
+
49
+ def is_dir?(path)
50
+ File.exist?(path) && File.ftype(path) == "directory"
51
+ end
52
+
53
+ def is_root?(path)
54
+ File.expand_path(path) == "/"
55
+ end
56
+
57
+ def expand_globs(patterns)
58
+ expand_paths(patterns.map do |pattern|
59
+ Dir.glob(File.join(git_repo_path, pattern))
60
+ end.flatten).compact.uniq
61
+ end
62
+
63
+ def expand_paths(paths)
64
+ paths.map {|path| File.expand_path(path) }
65
+ end
66
+
67
+ #git stuff
68
+ def git_repo_path
69
+ File.expand_path(find_up(Dir.pwd))
70
+ end
71
+
72
+ def files_changed_since(rev)
73
+ git = Git.open(git_repo_path)
74
+ changed_files = diff_files(git, rev) + changed_files(git)
75
+
76
+ expand_paths(changed_files.map {|p| File.join(git_repo_path, p)}).uniq
77
+ end
78
+
79
+ def diff_files(git, since)
80
+ git.diff(since, "HEAD").map(&:path)
81
+ end
82
+
83
+ def changed_files(git)
84
+ git.status.changed.map(&:first)
85
+ end
86
+ end
87
+
88
+ class ListsFeatures
89
+ include ListCore
90
+
91
+ def initialize(path, rev, disabled)
92
+ @path = path
93
+ @rev = rev
94
+ @disabled = disabled
95
+ end
96
+
97
+ def list
98
+ all_features = list_features_under(@path)
99
+ return format_feature_list(all_features) if @disabled
100
+ changeset = files_changed_since(@rev)
101
+
102
+ format_feature_list(all_features.select do |feature_path|
103
+ dependency_patterns = dependencies_declared_in(feature_path)
104
+ dependency_paths = expand_globs(dependency_patterns) + [feature_path]
105
+ any_dependencies_in_changeset?(dependency_paths, changeset)
106
+ end)
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,3 @@
1
+ module CucumberSlice
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cucumber-slice
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Justin Searls
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-03-29 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: thor
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 23
29
+ segments:
30
+ - 0
31
+ - 14
32
+ version: "0.14"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: git
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 21
44
+ segments:
45
+ - 1
46
+ - 2
47
+ - 5
48
+ version: 1.2.5
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ description: |
52
+ This tool can be used both locally and by build systems to
53
+ quickly narrow down which Cucumber features to run based on
54
+ which features may have been impacted by a code change.
55
+ Provides a CLI that filters Cucumber features based on
56
+ changes to production code since a specified git revision.
57
+ This is particular useful in systems of wide logical breadth,
58
+ where each individual commit is unlikely to have an impact on the
59
+ vast majority of the system's behavior.
60
+
61
+ email:
62
+ - searls@gmail.com
63
+ executables:
64
+ - cucumber-slice
65
+ extensions: []
66
+
67
+ extra_rdoc_files: []
68
+
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - bin/cucumber-slice
76
+ - cucumber-slice.gemspec
77
+ - lib/cucumber_slice.rb
78
+ - lib/cucumber_slice/cli.rb
79
+ - lib/cucumber_slice/empty_file
80
+ - lib/cucumber_slice/lists_features.rb
81
+ - lib/cucumber_slice/version.rb
82
+ homepage: https://github.com/testdouble/cucumber-slice
83
+ licenses: []
84
+
85
+ post_install_message:
86
+ rdoc_options: []
87
+
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ hash: 3
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ hash: 3
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ requirements: []
109
+
110
+ rubyforge_project:
111
+ rubygems_version: 1.8.15
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: Helps you narrow down which Cucumber features to run based on recent code changes
115
+ test_files: []
116
+