repos 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c2dc04f09bab4927a06925024375fc8870e32946
4
+ data.tar.gz: 3b05ab236f66ed462b91d08f88c1538e2741a1ce
5
+ SHA512:
6
+ metadata.gz: 48886bd57762f32ed30f8f418f487282584ee4e80b2d9e9290b69b43e2e511006a35a5e09240f0e4b2cb8e09dc268dd7347c0823452da3e38b44ed06b0ce09cc
7
+ data.tar.gz: 27d814b14b3ccba2e1e4d25f406e23b5f2272e2f97838c6fc785b46e1359fa0a148f5cf63c4ef05ede8d46cef93a9a29570c066488d4240ef4d94162a8aad9d1
@@ -0,0 +1,22 @@
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
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
4
+ addons:
5
+ code_climate:
6
+ repo_token: bf4b468e5faf5e886f834c94d11ca79664a895a3cda0d9c455cee2db2ca5fc9d
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in repos.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Nicolas McCurdy
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.
@@ -0,0 +1,37 @@
1
+ # Repos
2
+ [![Build Status](https://travis-ci.org/nicolasmccurdy/repos.svg?branch=master)](https://travis-ci.org/nicolasmccurdy/repos)
3
+ [![Dependency Status](https://gemnasium.com/nicolasmccurdy/repos.svg)](https://gemnasium.com/nicolasmccurdy/repos)
4
+ [![Code Climate](https://codeclimate.com/github/nicolasmccurdy/findrepos.png)](https://codeclimate.com/github/nicolasmccurdy/findrepos)
5
+ [![Coverage Status](https://codeclimate.com/github/nicolasmccurdy/findrepos/coverage.png)](https://codeclimate.com/github/nicolasmccurdy/findrepos)
6
+
7
+ A tool for finding git repositories locally.
8
+
9
+ ## Installation
10
+ $ gem install repos
11
+
12
+ ## Usage
13
+ Usage:
14
+ repos list [DIRECTORY]
15
+
16
+ Options:
17
+ -r, [--recursive], [--no-recursive] # finds Git repositories in subdirectories recursively
18
+ -v, [--verbose], [--no-verbose] # shows additional repository information, including the status and list of stashes
19
+ -n, [--names], [--no-names] # only displays paths to repositories
20
+ -f, [--filter=all|clean|dirty] # finds clean repositories only, dirty repositories only, or all repositories
21
+ # Default: all
22
+
23
+ lists all Git repositories in the given directory
24
+ Also aliased to `repos`.
25
+
26
+ ## Example
27
+ $ repos
28
+ clean ./bundler
29
+ clean ./rails
30
+ dirty ./repos
31
+
32
+ ## Contributing
33
+ 1. Fork it ( https://github.com/nicolasmccurdy/repos/fork )
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create a new Pull Request
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rdoc/task'
4
+
5
+ RSpec::Core::RakeTask.new
6
+
7
+ RDoc::Task.new do |rdoc|
8
+ rdoc.rdoc_dir = 'doc'
9
+ rdoc.main = 'README.md'
10
+ rdoc.rdoc_files.include('README.md', 'lib/**/*.rb')
11
+ end
12
+
13
+ task default: :spec
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'repos'
4
+ Repos::CLI.start ARGV
@@ -0,0 +1,46 @@
1
+ require 'repos/version'
2
+ require 'repos/cli'
3
+
4
+ # The main module of repos, which includes its core functionality and more
5
+ # modules for supporting functionality.
6
+ module Repos
7
+ # Lists all Git repository in the current directory. When recursive is true,
8
+ # it also lists Git repositories found in subdirectories.
9
+ #
10
+ # ==== Attributes
11
+ # * +directory+ - A String of the path to search for repositories within. This
12
+ # method will not check to see if the directory itself is a
13
+ # git repository. The path can be absolute or relative.
14
+ # * +filter+ - 'clean' to find clean repositories only, 'dirty' to find dirty
15
+ # repositories only, and anything else to find all repositories (dirty or
16
+ # clean).
17
+ # * +recursive+ - True if Git repositories should be searched for within
18
+ # subdirectories.
19
+ def self.list(directory, filter = 'all', recursive = false)
20
+ pattern = recursive ? '**/.git' : '*/.git'
21
+ repositories = Dir.glob("#{directory}/#{pattern}").sort.map do |git_directory|
22
+ Pathname.new(git_directory).dirname.to_s
23
+ end
24
+ is_clean = proc { |repository| Repos.clean?(repository) }
25
+
26
+ case filter
27
+ when 'clean' then repositories.select(&is_clean)
28
+ when 'dirty' then repositories.reject(&is_clean)
29
+ else repositories
30
+ end
31
+ end
32
+
33
+ # Returns true when the given repository has neigher uncommitted changes nor
34
+ # untracked files. Expects the repository to have at least one commit.
35
+ #
36
+ # ==== Attributes
37
+ # * +repository+ - A String of the path to the repository to check. The path
38
+ # can be absolute or relative.
39
+ def self.clean?(repository)
40
+ Dir.chdir(repository) do
41
+ empty_diff = system('git diff-index --quiet HEAD')
42
+ untracked = `git ls-files --other --directory --exclude-standard` != ''
43
+ empty_diff && !untracked
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,59 @@
1
+ require 'thor'
2
+ require 'pathname'
3
+
4
+ module Repos
5
+ # The command line interface for the repos executable.
6
+ class CLI < Thor
7
+ desc 'list [DIRECTORY]', 'lists all Git repositories in the given directory'
8
+ option :recursive,
9
+ desc: 'finds Git repositories in subdirectories recursively',
10
+ type: :boolean,
11
+ aliases: :'-r'
12
+ option :verbose,
13
+ desc: 'shows additional repository information, including the ' \
14
+ 'status and list of stashes',
15
+ type: :boolean,
16
+ aliases: :'-v'
17
+ option :names,
18
+ desc: 'only displays paths to repositories',
19
+ type: :boolean,
20
+ aliases: :'-n'
21
+ option :filter,
22
+ desc: 'finds clean repositories only, dirty repositories only, or ' \
23
+ 'all repositories',
24
+ banner: 'all|clean|dirty',
25
+ default: 'all',
26
+ type: :string,
27
+ aliases: :'-f'
28
+ def list(directory = '.') # :nodoc:
29
+ Repos.list(directory,
30
+ options[:filter],
31
+ options[:recursive]).each do |repository|
32
+ if options[:names]
33
+ say repository
34
+ else
35
+ say_git_status(Repos.clean?(repository), repository)
36
+ end
37
+
38
+ if options[:verbose]
39
+ Dir.chdir repository do
40
+ system 'git status'
41
+ system 'git stash list'
42
+ puts
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ default_command :list
49
+
50
+ private
51
+
52
+ def say_git_status(clean, message)
53
+ status = clean ? 'clean' : 'dirty'
54
+ color = clean ? :green : :red
55
+ status = set_color status, color, true
56
+ puts "#{status} #{message}"
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,4 @@
1
+ module Repos
2
+ # The version number of the gem.
3
+ VERSION = '0.1.0'
4
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'repos/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'repos'
8
+ spec.version = Repos::VERSION
9
+ spec.authors = ['Nicolas McCurdy']
10
+ spec.email = ['thenickperson@gmail.com']
11
+ spec.summary = 'A tool for finding git repositories locally.'
12
+ spec.homepage = 'https://github.com/nicolasmccurdy/repos'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'thor', '~> 0.19'
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.6'
23
+ spec.add_development_dependency 'rake', '~> 10'
24
+ spec.add_development_dependency 'rspec', '~> 3'
25
+ spec.add_development_dependency 'codeclimate-test-reporter'
26
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Repos::CLI do
4
+ describe '#list' do
5
+ before(:context) { create_repo_tree }
6
+
7
+ after(:context) { FileUtils.rm_r 'repos' }
8
+
9
+ context 'by default' do
10
+ it 'lists all clean and dirty Git repositories in the current ' \
11
+ 'directory' do
12
+ expect { Repos::CLI.start %w(list repos) }.to \
13
+ output("clean repos/a_clean_repo\ndirty repos/a_dirty_repo\n")
14
+ .to_stdout
15
+ end
16
+ end
17
+
18
+ context 'with --recursive' do
19
+ it 'lists all Git repositories in the current directory and all ' \
20
+ 'subdirectories' do
21
+ expect { Repos::CLI.start %w(list repos --recursive) }.to \
22
+ output("clean repos/a_clean_repo\ndirty repos/a_dirty_repo\nclean repos/repo_inside/another_repo\n").to_stdout
23
+ end
24
+ end
25
+
26
+ context 'with --verbose' do
27
+ it 'has tests'
28
+ end
29
+
30
+ context 'with --names' do
31
+ it 'lists all clean and dirty Git repositories in the current ' \
32
+ 'directory' do
33
+ expect { Repos::CLI.start %w(list repos --names) }.to \
34
+ output("repos/a_clean_repo\nrepos/a_dirty_repo\n").to_stdout
35
+ end
36
+ end
37
+
38
+ context 'with --filter' do
39
+ context 'when filter is "clean"' do
40
+ it 'only lists clean repositories' do
41
+ expect { Repos::CLI.start %w(list repos --filter=clean) }.to \
42
+ output("clean repos/a_clean_repo\n").to_stdout
43
+ end
44
+ end
45
+
46
+ context 'when filter is "dirty"' do
47
+ it 'only lists dirty repositories' do
48
+ expect { Repos::CLI.start %w(list repos --filter=dirty) }.to \
49
+ output("dirty repos/a_dirty_repo\n").to_stdout
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '#say_git_status' do
56
+ let(:cli) { Repos::CLI.new }
57
+
58
+ it 'displays a clean repository' do
59
+ expect do
60
+ cli.send(:say_git_status, true, 'hello')
61
+ end.to output("clean hello\n").to_stdout
62
+ end
63
+
64
+ it 'displays a dirty repository' do
65
+ expect do
66
+ cli.send(:say_git_status, false, 'hello')
67
+ end.to output("dirty hello\n").to_stdout
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ describe Repos do
4
+ describe '.VERSION' do
5
+ it 'exists' do
6
+ expect(Repos::VERSION).not_to be nil
7
+ end
8
+ end
9
+
10
+ describe '.clean?' do
11
+ before(:example) { create_repo 'repo' }
12
+
13
+ after(:example) { FileUtils.rm_r 'repo' }
14
+
15
+ context 'when the given repository has an untracked file' do
16
+ it 'returns false' do
17
+ Dir.chdir('repo') { FileUtils.touch 'README' }
18
+ expect(Repos.clean? 'repo').to be false
19
+ end
20
+ end
21
+
22
+ context 'when the given repository has a modified file in the working ' \
23
+ 'tree' do
24
+ it 'returns false' do
25
+ Dir.chdir('repo') { `echo "hello" > file` }
26
+ expect(Repos.clean? 'repo').to be false
27
+ end
28
+ end
29
+
30
+ context 'when the given repository has a modified file in the stage' do
31
+ it 'returns false' do
32
+ Dir.chdir 'repo' do
33
+ `echo "hello" > file`
34
+ `git add file`
35
+ end
36
+ expect(Repos.clean? 'repo').to be false
37
+ end
38
+ end
39
+
40
+ context 'when the given repository has neither uncommitted changes nor ' \
41
+ 'untracked files' do
42
+ it 'returns true' do
43
+ expect(Repos.clean? 'repo').to be true
44
+ end
45
+ end
46
+
47
+ context 'when the given repository has no commits' do
48
+ it 'has tests'
49
+ end
50
+ end
51
+
52
+ describe '.list' do
53
+ before(:context) { create_repo_tree }
54
+
55
+ after(:context) { FileUtils.rm_r 'repos' }
56
+
57
+ context 'by default' do
58
+ it 'lists all clean and dirty Git repositories in the current ' \
59
+ 'directory' do
60
+ expect(Repos.list 'repos').to eq [
61
+ 'repos/a_clean_repo',
62
+ 'repos/a_dirty_repo'
63
+ ]
64
+ end
65
+ end
66
+
67
+ context 'with recursion' do
68
+ it 'lists all Git repositories in the current directory and all ' \
69
+ 'subdirectories' do
70
+ expect(Repos.list('repos', 'all', true)).to eq [
71
+ 'repos/a_clean_repo',
72
+ 'repos/a_dirty_repo',
73
+ 'repos/repo_inside/another_repo'
74
+ ]
75
+ end
76
+ end
77
+
78
+ context 'when filter is "clean"' do
79
+ it 'only lists clean repositories' do
80
+ expect(Repos.list('repos', 'clean')).to eq ['repos/a_clean_repo']
81
+ end
82
+ end
83
+
84
+ context 'when filter is "dirty"' do
85
+ it 'only lists dirty repositories' do
86
+ expect(Repos.list('repos', 'dirty')).to eq ['repos/a_dirty_repo']
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,33 @@
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
5
+ require 'repos'
6
+
7
+ def create_repo(name)
8
+ Dir.mkdir name
9
+ Dir.chdir name do
10
+ `git init`
11
+ `git config user.name "Example"`
12
+ `git config user.email "example@example.com"`
13
+
14
+ FileUtils.touch 'file'
15
+ `git add file`
16
+ `git commit -m "Initial commit."`
17
+ end
18
+ end
19
+
20
+ def create_repo_tree
21
+ Dir.mkdir 'repos'
22
+ Dir.chdir 'repos' do
23
+ create_repo 'a_clean_repo'
24
+
25
+ create_repo 'a_dirty_repo'
26
+ Dir.chdir('a_dirty_repo') { `echo "Hello, world!" > file` }
27
+
28
+ Dir.mkdir 'not_a_repo'
29
+
30
+ Dir.mkdir 'repo_inside'
31
+ Dir.chdir('repo_inside') { create_repo 'another_repo' }
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: repos
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nicolas McCurdy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.19'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: codeclimate-test-reporter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - thenickperson@gmail.com
86
+ executables:
87
+ - repos
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/repos
99
+ - lib/repos.rb
100
+ - lib/repos/cli.rb
101
+ - lib/repos/version.rb
102
+ - repos.gemspec
103
+ - spec/cli_spec.rb
104
+ - spec/repos_spec.rb
105
+ - spec/spec_helper.rb
106
+ homepage: https://github.com/nicolasmccurdy/repos
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.2.2
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: A tool for finding git repositories locally.
130
+ test_files:
131
+ - spec/cli_spec.rb
132
+ - spec/repos_spec.rb
133
+ - spec/spec_helper.rb
134
+ has_rdoc: