projectionist 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1295fd4b627a53451bf020b7e3f3976ec2d40d53
4
+ data.tar.gz: db51bff9c54b334573a9308ed9c4b3528330114c
5
+ SHA512:
6
+ metadata.gz: f787705951e31e8f2b1945c75d29ce079caf82f11e0649f2e5b299783fd9b601d0147ee1dd513e1945fc9653b420c54fe0c799b22c951aec5e7975d272f3ba75
7
+ data.tar.gz: 520ef649f80267f4500e5ee779c1b82628b2d87ce07b6cb88779ecf9242d95ea0189560c3de289410fc0ece413fb42c53329400a35e0ae6a906fa2b1c0a62b20
data/.gitignore ADDED
@@ -0,0 +1,23 @@
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
23
+ spec/fixtures/**/*
data/.projections.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "lib/**/*.rb": {
3
+ "type": "lib"
4
+ }
5
+ }
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format Fivemat
2
+ --color
3
+ --order random
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Griffin Smith
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,39 @@
1
+ [![Build Status](https://travis-ci.org/glittershark/projectionist.svg?branch=master)](https://travis-ci.org/glittershark/projectionist)
2
+ [![Code Climate](https://codeclimate.com/github/glittershark/projectionist.png)](https://codeclimate.com/github/glittershark/projectionist)
3
+ [![Dependency Status](https://gemnasium.com/glittershark/projectionist.svg)](https://gemnasium.com/glittershark/projectionist)
4
+
5
+ # Projectionist
6
+
7
+ Command-line interface to the [.projections.json](https://github.com/tpope/vim-projectionist) format - WIP
8
+
9
+ ## Installation
10
+
11
+ $ gem install projectionist
12
+
13
+ ## Usage
14
+
15
+ For ease of typing, the executable file for projectionist is `prj`.
16
+
17
+ Given a `.projections.json` file in the root of your project with the following structure:
18
+
19
+ ```
20
+ {
21
+ "lib/**/*.rb": {
22
+ "type": "lib"
23
+ }
24
+ }
25
+ ```
26
+
27
+ The command to edit `lib/whatever/test.rb` would be:
28
+
29
+ $ prj edit lib test
30
+
31
+
32
+ ## Contributing
33
+
34
+ 1. [Fork it](https://github.com/glittershark/projectionist/fork)
35
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
36
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
37
+ 4. Push to the branch (`git push origin my-new-feature`)
38
+ 5. Create a new Pull Request
39
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/prj ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'projectionist/cli'
4
+
5
+ Projector::CLI.start(ARGV)
@@ -0,0 +1,6 @@
1
+ require 'projectionist/version'
2
+ require 'projectionist/projections'
3
+ require 'projectionist/cli'
4
+
5
+ module Projectionist
6
+ end
@@ -0,0 +1,26 @@
1
+ require 'projectionist'
2
+ require 'thor'
3
+
4
+ module Projectionist
5
+ class CLI < Thor
6
+ attr_accessor :projections
7
+
8
+ def initialize(*)
9
+ @projections = Projectionist::Projections.new
10
+ super
11
+ end
12
+
13
+ desc 'edit <type> <file>', 'Edit the file for <type> named <file>'
14
+ option :editor
15
+ def edit(type, file)
16
+ editor = options[:editor] || ENV['EDITOR'] || `which vim`
17
+ file = @projections.file_for type, file
18
+ exec editor, file
19
+ end
20
+
21
+ desc 'list <type>', 'List all files for <type>'
22
+ def list(type)
23
+ puts @projections.files_for(type).join("\n")
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,71 @@
1
+ require 'json'
2
+
3
+ module Projectionist
4
+ class Projections
5
+ attr_reader :types
6
+ attr_reader :json_file_existed
7
+
8
+ def initialize
9
+ @types = {}
10
+ load_file
11
+ end
12
+
13
+ def load_file(path = nil)
14
+ @json = get_json path
15
+ @json.each do |glob, options|
16
+ next unless options.key? 'type'
17
+ @types[options['type']] = options.merge('glob' => glob)
18
+ end
19
+ end
20
+
21
+ def type?(type)
22
+ @types.key?(type)
23
+ end
24
+
25
+ def file_for(type, name)
26
+ return nil unless type? type
27
+
28
+ Dir.chdir @basedir
29
+ glob = build_glob(@types[type]['glob'], name)
30
+ file = Dir.glob(glob)[0]
31
+ File.expand_path(file.nil? ? glob : file)
32
+ end
33
+
34
+ def files_for(type)
35
+ return [] unless type? type
36
+ Dir.glob(@types[type]['glob']).map { |p| File.expand_path p }
37
+ end
38
+
39
+ private
40
+
41
+ def get_json(path)
42
+ if path.nil?
43
+ path = projections_path
44
+ if path.nil?
45
+ @json_file_existed = false
46
+ return {}
47
+ end
48
+ end
49
+ @json_file_existed = true
50
+ File.open(path, 'r') { |f| JSON.parse(f.read) }
51
+ end
52
+
53
+ def projections_path
54
+ path = File.expand_path './.projections.json'
55
+ until File.exist? path
56
+ return nil if [false, '/'].include?(File.dirname path)
57
+ path = File.expand_path('../../.projections.json', path)
58
+ end
59
+ @basedir = File.dirname path
60
+ path
61
+ end
62
+
63
+ def build_glob(glob, file)
64
+ # Split the passed file by `/`, then replace all globs that use `*` or
65
+ # `**` with components of the passed file, in order
66
+ file_components = file.split('/')
67
+ glob_components = glob.split(/\*+/)
68
+ glob_components.zip(file_components).flatten.compact.join('')
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ module Projectionist
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'projectionist/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'projectionist'
8
+ spec.version = Projectionist::VERSION
9
+ spec.authors = ['Griffin Smith']
10
+ spec.email = ['wildgriffin45@gmail.com']
11
+ spec.summary = 'Command line interface to the .projections.json format'
12
+ spec.description = <<-EOF
13
+ Projectionist allows you to quickly edit files in a project from the command
14
+ line, using the projections.json format
15
+ EOF
16
+ spec.homepage = 'http://github.com/glittershark/projectionist'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0")
20
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.6'
25
+ spec.add_development_dependency 'rake', '~> 10.3'
26
+ spec.add_development_dependency 'rspec', '~> 3.0'
27
+ spec.add_development_dependency 'fivemat', '~> 1.3'
28
+
29
+ spec.add_runtime_dependency 'thor', '~> 0.19.1', '>= 0.19'
30
+ end
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'helper'
2
+
3
+ describe Projectionist::CLI do
4
+ before do
5
+ @cli = Projectionist::CLI.new
6
+ @old_stderr = $stderr
7
+ $stderr = StringIO.new
8
+ @old_stdout = $stdout
9
+ $stdout = StringIO.new
10
+ end
11
+
12
+ after do
13
+ $stderr = @old_stderr
14
+ $stdout = @old_stdout
15
+ end
16
+
17
+ describe '#edit' do
18
+ before do
19
+ @cli.edit
20
+ end
21
+ end
22
+ end
data/spec/helper.rb ADDED
@@ -0,0 +1,39 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'projectionist'
4
+ require 'json'
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+
8
+ RSpec.configure do |config|
9
+ config.before(:suite) { $tmpdir = Dir.mktmpdir }
10
+ config.after(:suite) { FileUtils.remove_entry_secure $tmpdir }
11
+
12
+ config.expect_with :rspec do |c|
13
+ c.syntax = :expect
14
+ end
15
+ end
16
+
17
+ def fixture_folder
18
+ $tmpdir
19
+ end
20
+
21
+ def fixture_file
22
+ File.join(fixture_folder, '.projections.json')
23
+ end
24
+
25
+ def read_fixtures
26
+ File.open(fixture_file, 'r') { |f| JSON.parse(f.read) }
27
+ end
28
+
29
+ def write_fixtures(hash)
30
+ File.open(fixture_file, 'w') { |f| f.write(hash.to_json) }
31
+ end
32
+
33
+ def delete_fixtures
34
+ File.delete fixture_file if File.exist? fixture_file
35
+ end
36
+
37
+ def empty_fixtures
38
+ FileUtils.rm_rf Dir.glob("#{fixture_folder}/*", File::FNM_DOTMATCH)
39
+ end
@@ -0,0 +1,167 @@
1
+ require 'helper'
2
+
3
+ describe Projectionist::Projections do
4
+ before do
5
+ @original_dir = Dir.pwd
6
+ write_fixtures('*/*' => { 'type' => 'test' })
7
+ Dir.mkdir fixture_folder unless Dir.exist? fixture_folder
8
+ Dir.chdir fixture_folder
9
+ @projections = Projectionist::Projections.new
10
+ end
11
+
12
+ after { Dir.chdir @original_dir }
13
+
14
+ it 'exists' do
15
+ expect(@projections).not_to be nil
16
+ end
17
+
18
+ describe '.types' do
19
+ before do
20
+ @projections.load_file fixture_file
21
+ end
22
+
23
+ it 'loads the list of types' do
24
+ expect(@projections.types.keys).to eq ['test']
25
+ end
26
+
27
+ it 'has a method to check if a given type exists' do
28
+ expect(@projections.type? 'test').to be true
29
+ expect(@projections.type? 'toast').to be false
30
+ end
31
+
32
+ it 'sets a flag that the file existed' do
33
+ expect(@projections.json_file_existed).to be true
34
+ end
35
+ end
36
+
37
+ describe '#load_file' do
38
+ context 'when in a child directory' do
39
+ before do
40
+ write_fixtures('*/*' => { 'type' => 'test' })
41
+ dir = File.join(fixture_folder, 'otherdir')
42
+ Dir.mkdir dir unless Dir.exist? dir
43
+ Dir.chdir dir
44
+ @projections = Projectionist::Projections.new
45
+ @projections.load_file
46
+ end
47
+
48
+ it 'still loads the file' do
49
+ expect(@projections.types.keys).to eq ['test']
50
+ end
51
+
52
+ it 'still sets a flag that the file existed' do
53
+ expect(@projections.json_file_existed).to be true
54
+ end
55
+ end
56
+
57
+ context 'without a config file' do
58
+ before do
59
+ Dir.chdir fixture_folder
60
+ delete_fixtures
61
+ @projections = Projectionist::Projections.new
62
+ @projections.load_file
63
+ end
64
+
65
+ it "sets a flag that the file didn't exist" do
66
+ expect(@projections.json_file_existed).to be false
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '#files_for' do
72
+ let(:test_dir) { File.join(fixture_folder, 'test') }
73
+ let(:test_files) { (1..10).map { |n| File.join(test_dir, "test_#{n}.rb") } }
74
+
75
+ before do
76
+ write_fixtures('test/test_*.rb' => { 'type' => 'test' })
77
+ Dir.mkdir(test_dir) unless Dir.exist? test_dir
78
+
79
+ test_files.each { |f| File.open(f, 'w') }
80
+
81
+ # make bad test files as well
82
+ 5.times do |n|
83
+ file = File.join(test_dir, "bad_#{n}.rb")
84
+ File.open(file, 'w')
85
+ end
86
+
87
+ @projections.load_file
88
+ end
89
+
90
+ context 'with a valid type' do
91
+ it 'matches the correct files' do
92
+ expect(@projections.files_for 'test').to match_array(test_files)
93
+ end
94
+ end
95
+
96
+ context 'without a valid type' do
97
+ it 'returns an empty array' do
98
+ expect(@projections.files_for 'toast').to eq []
99
+ end
100
+ end
101
+ end
102
+
103
+ describe '#file_for' do
104
+ context 'with simple globs' do
105
+ let(:test_dir) { File.join(fixture_folder, 'test') }
106
+ let(:test_file) { File.join(test_dir, 'file.rb') }
107
+ before do
108
+ write_fixtures('test/*.rb' => { 'type' => 'test' })
109
+ Dir.mkdir(test_dir) unless Dir.exist? test_dir
110
+ File.open(test_file, 'w')
111
+ Dir.chdir fixture_folder
112
+ @projections.load_file
113
+ end
114
+
115
+ context 'with a valid type' do
116
+ subject { @projections.file_for('test', 'file') }
117
+ it { is_expected.to eq test_file }
118
+ end
119
+
120
+ context 'without a valid type' do
121
+ subject { @projections.file_for('toast', 'file') }
122
+ it { is_expected.to be_nil }
123
+ end
124
+
125
+ context "with a file that doesn't exist" do
126
+ subject { @projections.file_for('test', 'nonexistent') }
127
+ it { is_expected.to eq File.join(test_dir, 'nonexistent.rb') }
128
+ end
129
+
130
+ context 'with other files in the directory' do
131
+ let(:other_test_file) { File.join(test_dir, 'abc.rb') }
132
+ before do
133
+ File.open(other_test_file, 'w')
134
+ end
135
+
136
+ it 'matches the other file' do
137
+ expect(@projections.file_for('test', 'abc')).to eq other_test_file
138
+ end
139
+
140
+ it 'matches the old file' do
141
+ expect(@projections.file_for('test', 'file')).to eq test_file
142
+ end
143
+ end
144
+
145
+ context 'in a child directory' do
146
+ before { Dir.chdir test_dir }
147
+ subject { @projections.file_for('test', 'file') }
148
+ it { is_expected.to eq test_file }
149
+ end
150
+ end
151
+
152
+ context 'with multi-level globs' do
153
+ let(:test_dir) { File.join(fixture_folder, 'test', 'foobar') }
154
+ let(:test_file) { File.join(test_dir, 'test_file.rb') }
155
+ before do
156
+ write_fixtures('test/**/test_*.rb' => { 'type' => 'test' })
157
+ FileUtils.mkdir_p test_dir unless Dir.exist? test_dir
158
+ File.open(test_file, 'w')
159
+ Dir.chdir fixture_folder
160
+ @projections.load_file
161
+ end
162
+
163
+ subject { @projections.file_for 'test', 'foobar/file' }
164
+ it { is_expected.to eq test_file }
165
+ end
166
+ end
167
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: projectionist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Griffin Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fivemat
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: thor
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.19.1
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0.19'
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: 0.19.1
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0.19'
89
+ description: |2
90
+ Projectionist allows you to quickly edit files in a project from the command
91
+ line, using the projections.json format
92
+ email:
93
+ - wildgriffin45@gmail.com
94
+ executables:
95
+ - prj
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - ".gitignore"
100
+ - ".projections.json"
101
+ - ".rspec"
102
+ - ".travis.yml"
103
+ - Gemfile
104
+ - LICENSE.txt
105
+ - README.md
106
+ - Rakefile
107
+ - bin/prj
108
+ - lib/projectionist.rb
109
+ - lib/projectionist/cli.rb
110
+ - lib/projectionist/projections.rb
111
+ - lib/projectionist/version.rb
112
+ - projectionist.gemspec
113
+ - spec/cli_spec.rb
114
+ - spec/helper.rb
115
+ - spec/projections_spec.rb
116
+ homepage: http://github.com/glittershark/projectionist
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.2.2
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Command line interface to the .projections.json format
140
+ test_files:
141
+ - spec/cli_spec.rb
142
+ - spec/helper.rb
143
+ - spec/projections_spec.rb