github_cli 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile.lock +1 -1
  3. data/Rakefile +4 -1
  4. data/github_cli.gemspec +3 -1
  5. data/lib/github_cli/dsl.rb +7 -3
  6. data/lib/github_cli/thor_ext.rb +1 -3
  7. data/lib/github_cli/vendor/thor/actions/create_file.rb +105 -0
  8. data/lib/github_cli/vendor/thor/actions/create_link.rb +57 -0
  9. data/lib/github_cli/vendor/thor/actions/directory.rb +98 -0
  10. data/lib/github_cli/vendor/thor/actions/empty_directory.rb +153 -0
  11. data/lib/github_cli/vendor/thor/actions/file_manipulation.rb +308 -0
  12. data/lib/github_cli/vendor/thor/actions/inject_into_file.rb +109 -0
  13. data/lib/github_cli/vendor/thor/actions.rb +318 -0
  14. data/lib/github_cli/vendor/thor/base.rb +641 -0
  15. data/lib/github_cli/vendor/thor/core_ext/dir_escape.rb +0 -0
  16. data/lib/github_cli/vendor/thor/core_ext/file_binary_read.rb +9 -0
  17. data/lib/github_cli/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  18. data/lib/github_cli/vendor/thor/core_ext/ordered_hash.rb +100 -0
  19. data/lib/github_cli/vendor/thor/empty.txt +0 -0
  20. data/lib/github_cli/vendor/thor/error.rb +35 -0
  21. data/lib/github_cli/vendor/thor/group.rb +285 -0
  22. data/lib/github_cli/vendor/thor/invocation.rb +170 -0
  23. data/lib/github_cli/vendor/thor/parser/argument.rb +74 -0
  24. data/lib/github_cli/vendor/thor/parser/arguments.rb +171 -0
  25. data/lib/github_cli/vendor/thor/parser/option.rb +121 -0
  26. data/lib/github_cli/vendor/thor/parser/options.rb +178 -0
  27. data/lib/github_cli/vendor/thor/parser.rb +4 -0
  28. data/lib/github_cli/vendor/thor/rake_compat.rb +71 -0
  29. data/lib/github_cli/vendor/thor/runner.rb +321 -0
  30. data/lib/github_cli/vendor/thor/shell/basic.rb +389 -0
  31. data/lib/github_cli/vendor/thor/shell/color.rb +144 -0
  32. data/lib/github_cli/vendor/thor/shell/html.rb +123 -0
  33. data/lib/github_cli/vendor/thor/shell.rb +88 -0
  34. data/lib/github_cli/vendor/thor/task.rb +132 -0
  35. data/lib/github_cli/vendor/thor/util.rb +266 -0
  36. data/lib/github_cli/vendor/thor/version.rb +3 -0
  37. data/lib/github_cli/vendor/thor.rb +379 -0
  38. data/lib/github_cli/vendor.rb +7 -5
  39. data/lib/github_cli/version.rb +3 -1
  40. metadata +45 -22
  41. data/bin/ghc +0 -2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ 0.5.1 (September 16, 2012)
2
+
3
+ * Fix bug - failure to load vendored dependencies.
4
+ * Remove *ghc* executable.
5
+
1
6
  0.5.0 (August 17, 2012) - IMPORTANT!!!
2
7
 
3
8
  * Change editor settings to seek first local config before system properties.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- github_cli (0.5.0)
4
+ github_cli (0.5.1)
5
5
  github_api (~> 0.6)
6
6
 
7
7
  GEM
data/Rakefile CHANGED
@@ -49,7 +49,10 @@ end
49
49
  namespace :vendor do
50
50
  desc "Build"
51
51
  task :build => :clean do
52
- sh "git clone git://github.com/wycats/thor.git lib/github_cli/vendor/thor"
52
+ sh "git clone git://github.com/wycats/thor.git lib/github_cli/vendor/tmp"
53
+ sh "mkdir lib/github_cli/vendor/thor"
54
+ sh "mv lib/github_cli/vendor/tmp/lib/* lib/github_cli/vendor/"
55
+ rm_rf "lib/github_cli/vendor/tmp"
53
56
  end
54
57
 
55
58
  task :clean do
data/github_cli.gemspec CHANGED
@@ -8,8 +8,10 @@ Gem::Specification.new do |gem|
8
8
  gem.summary = %q{github_cli is a set of tools that provide full command line access to GitHub API v3}
9
9
  gem.homepage = "http://github.com/peter-murach/github_cli"
10
10
 
11
+ man_files = Dir.glob("lib/github_cli/man/**/*")
12
+ vendor_files = Dir.glob("lib/github_cli/vendor/**/*")
11
13
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
- gem.files = `git ls-files`.split("\n") + Dir.glob("lib/github_cli/man/**/*")
14
+ gem.files = `git ls-files`.split("\n") + man_files + vendor_files
13
15
  gem.test_files = `git ls-files -- {spec,features}/*`.split("\n")
14
16
  gem.name = "github_cli"
15
17
  gem.require_paths = ["lib"]
@@ -6,6 +6,7 @@ module GithubCLI
6
6
  @@error_block = nil
7
7
 
8
8
  # Defines a program name.
9
+ #
9
10
  def program_name(name=nil)
10
11
  if name
11
12
  @@program_name = name
@@ -13,9 +14,12 @@ module GithubCLI
13
14
  @@program_name
14
15
  end
15
16
 
16
- # Defines behaviour on error.
17
- def on_error(&block)
18
- @@error_block = block
17
+ # Defines behaviour on error to emit consistent type.
18
+ #
19
+ def on_error
20
+ yield
21
+ rescue Exception => error
22
+ raise GithubCLI::GithubCLIError, "Rescued: #{error}"
19
23
  end
20
24
 
21
25
  def before(&block)
@@ -1,6 +1,4 @@
1
- $:.unshift File.expand_path('../vendor/thor', __FILE__)
2
- require 'thor'
3
- require 'github_cli'
1
+ # encoding: utf-8
4
2
 
5
3
  class Thor
6
4
  include Thor::Base
@@ -0,0 +1,105 @@
1
+ require 'thor/actions/empty_directory'
2
+
3
+ class Thor
4
+ module Actions
5
+
6
+ # Create a new file relative to the destination root with the given data,
7
+ # which is the return value of a block or a data string.
8
+ #
9
+ # ==== Parameters
10
+ # destination<String>:: the relative path to the destination root.
11
+ # data<String|NilClass>:: the data to append to the file.
12
+ # config<Hash>:: give :verbose => false to not log the status.
13
+ #
14
+ # ==== Examples
15
+ #
16
+ # create_file "lib/fun_party.rb" do
17
+ # hostname = ask("What is the virtual hostname I should use?")
18
+ # "vhost.name = #{hostname}"
19
+ # end
20
+ #
21
+ # create_file "config/apache.conf", "your apache config"
22
+ #
23
+ def create_file(destination, *args, &block)
24
+ config = args.last.is_a?(Hash) ? args.pop : {}
25
+ data = args.first
26
+ action CreateFile.new(self, destination, block || data.to_s, config)
27
+ end
28
+ alias :add_file :create_file
29
+
30
+ # CreateFile is a subset of Template, which instead of rendering a file with
31
+ # ERB, it gets the content from the user.
32
+ #
33
+ class CreateFile < EmptyDirectory #:nodoc:
34
+ attr_reader :data
35
+
36
+ def initialize(base, destination, data, config={})
37
+ @data = data
38
+ super(base, destination, config)
39
+ end
40
+
41
+ # Checks if the content of the file at the destination is identical to the rendered result.
42
+ #
43
+ # ==== Returns
44
+ # Boolean:: true if it is identical, false otherwise.
45
+ #
46
+ def identical?
47
+ exists? && File.binread(destination) == render
48
+ end
49
+
50
+ # Holds the content to be added to the file.
51
+ #
52
+ def render
53
+ @render ||= if data.is_a?(Proc)
54
+ data.call
55
+ else
56
+ data
57
+ end
58
+ end
59
+
60
+ def invoke!
61
+ invoke_with_conflict_check do
62
+ FileUtils.mkdir_p(File.dirname(destination))
63
+ File.open(destination, 'wb') { |f| f.write render }
64
+ end
65
+ given_destination
66
+ end
67
+
68
+ protected
69
+
70
+ # Now on conflict we check if the file is identical or not.
71
+ #
72
+ def on_conflict_behavior(&block)
73
+ if identical?
74
+ say_status :identical, :blue
75
+ else
76
+ options = base.options.merge(config)
77
+ force_or_skip_or_conflict(options[:force], options[:skip], &block)
78
+ end
79
+ end
80
+
81
+ # If force is true, run the action, otherwise check if it's not being
82
+ # skipped. If both are false, show the file_collision menu, if the menu
83
+ # returns true, force it, otherwise skip.
84
+ #
85
+ def force_or_skip_or_conflict(force, skip, &block)
86
+ if force
87
+ say_status :force, :yellow
88
+ block.call unless pretend?
89
+ elsif skip
90
+ say_status :skip, :yellow
91
+ else
92
+ say_status :conflict, :red
93
+ force_or_skip_or_conflict(force_on_collision?, true, &block)
94
+ end
95
+ end
96
+
97
+ # Shows the file collision menu to the user and gets the result.
98
+ #
99
+ def force_on_collision?
100
+ base.shell.file_collision(destination){ render }
101
+ end
102
+
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,57 @@
1
+ require 'thor/actions/create_file'
2
+
3
+ class Thor
4
+ module Actions
5
+
6
+ # Create a new file relative to the destination root from the given source.
7
+ #
8
+ # ==== Parameters
9
+ # destination<String>:: the relative path to the destination root.
10
+ # source<String|NilClass>:: the relative path to the source root.
11
+ # config<Hash>:: give :verbose => false to not log the status.
12
+ # :: give :symbolic => false for hard link.
13
+ #
14
+ # ==== Examples
15
+ #
16
+ # create_link "config/apache.conf", "/etc/apache.conf"
17
+ #
18
+ def create_link(destination, *args, &block)
19
+ config = args.last.is_a?(Hash) ? args.pop : {}
20
+ source = args.first
21
+ action CreateLink.new(self, destination, source, config)
22
+ end
23
+ alias :add_link :create_link
24
+
25
+ # CreateLink is a subset of CreateFile, which instead of taking a block of
26
+ # data, just takes a source string from the user.
27
+ #
28
+ class CreateLink < CreateFile #:nodoc:
29
+ attr_reader :data
30
+
31
+ # Checks if the content of the file at the destination is identical to the rendered result.
32
+ #
33
+ # ==== Returns
34
+ # Boolean:: true if it is identical, false otherwise.
35
+ #
36
+ def identical?
37
+ exists? && File.identical?(render, destination)
38
+ end
39
+
40
+ def invoke!
41
+ invoke_with_conflict_check do
42
+ FileUtils.mkdir_p(File.dirname(destination))
43
+ # Create a symlink by default
44
+ config[:symbolic] = true if config[:symbolic].nil?
45
+ File.unlink(destination) if exists?
46
+ if config[:symbolic]
47
+ File.symlink(render, destination)
48
+ else
49
+ File.link(render, destination)
50
+ end
51
+ end
52
+ given_destination
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,98 @@
1
+ require 'thor/actions/empty_directory'
2
+
3
+ class Thor
4
+ module Actions
5
+ # Copies recursively the files from source directory to root directory.
6
+ # If any of the files finishes with .tt, it's considered to be a template
7
+ # and is placed in the destination without the extension .tt. If any
8
+ # empty directory is found, it's copied and all .empty_directory files are
9
+ # ignored. If any file name is wrapped within % signs, the text within
10
+ # the % signs will be executed as a method and replaced with the returned
11
+ # value. Let's suppose a doc directory with the following files:
12
+ #
13
+ # doc/
14
+ # components/.empty_directory
15
+ # README
16
+ # rdoc.rb.tt
17
+ # %app_name%.rb
18
+ #
19
+ # When invoked as:
20
+ #
21
+ # directory "doc"
22
+ #
23
+ # It will create a doc directory in the destination with the following
24
+ # files (assuming that the `app_name` method returns the value "blog"):
25
+ #
26
+ # doc/
27
+ # components/
28
+ # README
29
+ # rdoc.rb
30
+ # blog.rb
31
+ #
32
+ # <b>Encoded path note:</b> Since Thor internals use Object#respond_to? to check if it can
33
+ # expand %something%, this `something` should be a public method in the class calling
34
+ # #directory. If a method is private, Thor stack raises PrivateMethodEncodedError.
35
+ #
36
+ # ==== Parameters
37
+ # source<String>:: the relative path to the source root.
38
+ # destination<String>:: the relative path to the destination root.
39
+ # config<Hash>:: give :verbose => false to not log the status.
40
+ # If :recursive => false, does not look for paths recursively.
41
+ #
42
+ # ==== Examples
43
+ #
44
+ # directory "doc"
45
+ # directory "doc", "docs", :recursive => false
46
+ #
47
+ def directory(source, *args, &block)
48
+ config = args.last.is_a?(Hash) ? args.pop : {}
49
+ destination = args.first || source
50
+ action Directory.new(self, source, destination || source, config, &block)
51
+ end
52
+
53
+ class Directory < EmptyDirectory #:nodoc:
54
+ attr_reader :source
55
+
56
+ def initialize(base, source, destination=nil, config={}, &block)
57
+ @source = File.expand_path(base.find_in_source_paths(source.to_s))
58
+ @block = block
59
+ super(base, destination, { :recursive => true }.merge(config))
60
+ end
61
+
62
+ def invoke!
63
+ base.empty_directory given_destination, config
64
+ execute!
65
+ end
66
+
67
+ def revoke!
68
+ execute!
69
+ end
70
+
71
+ protected
72
+
73
+ def execute!
74
+ lookup = Util.escape_globs(source)
75
+ lookup = config[:recursive] ? File.join(lookup, '**') : lookup
76
+ lookup = File.join(lookup, '{*,.[a-z]*}')
77
+
78
+ Dir[lookup].sort.each do |file_source|
79
+ next if File.directory?(file_source)
80
+ file_destination = File.join(given_destination, file_source.gsub(source, '.'))
81
+ file_destination.gsub!('/./', '/')
82
+
83
+ case file_source
84
+ when /\.empty_directory$/
85
+ dirname = File.dirname(file_destination).gsub(/\/\.$/, '')
86
+ next if dirname == given_destination
87
+ base.empty_directory(dirname, config)
88
+ when /\.tt$/
89
+ destination = base.template(file_source, file_destination[0..-4], config, &@block)
90
+ else
91
+ destination = base.copy_file(file_source, file_destination, config, &@block)
92
+ end
93
+ end
94
+ end
95
+
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,153 @@
1
+ class Thor
2
+ module Actions
3
+
4
+ # Creates an empty directory.
5
+ #
6
+ # ==== Parameters
7
+ # destination<String>:: the relative path to the destination root.
8
+ # config<Hash>:: give :verbose => false to not log the status.
9
+ #
10
+ # ==== Examples
11
+ #
12
+ # empty_directory "doc"
13
+ #
14
+ def empty_directory(destination, config={})
15
+ action EmptyDirectory.new(self, destination, config)
16
+ end
17
+
18
+ # Class which holds create directory logic. This is the base class for
19
+ # other actions like create_file and directory.
20
+ #
21
+ # This implementation is based in Templater actions, created by Jonas Nicklas
22
+ # and Michael S. Klishin under MIT LICENSE.
23
+ #
24
+ class EmptyDirectory #:nodoc:
25
+ attr_reader :base, :destination, :given_destination, :relative_destination, :config
26
+
27
+ # Initializes given the source and destination.
28
+ #
29
+ # ==== Parameters
30
+ # base<Thor::Base>:: A Thor::Base instance
31
+ # source<String>:: Relative path to the source of this file
32
+ # destination<String>:: Relative path to the destination of this file
33
+ # config<Hash>:: give :verbose => false to not log the status.
34
+ #
35
+ def initialize(base, destination, config={})
36
+ @base, @config = base, { :verbose => true }.merge(config)
37
+ self.destination = destination
38
+ end
39
+
40
+ # Checks if the destination file already exists.
41
+ #
42
+ # ==== Returns
43
+ # Boolean:: true if the file exists, false otherwise.
44
+ #
45
+ def exists?
46
+ ::File.exists?(destination)
47
+ end
48
+
49
+ def invoke!
50
+ invoke_with_conflict_check do
51
+ ::FileUtils.mkdir_p(destination)
52
+ end
53
+ end
54
+
55
+ def revoke!
56
+ say_status :remove, :red
57
+ ::FileUtils.rm_rf(destination) if !pretend? && exists?
58
+ given_destination
59
+ end
60
+
61
+ protected
62
+
63
+ # Shortcut for pretend.
64
+ #
65
+ def pretend?
66
+ base.options[:pretend]
67
+ end
68
+
69
+ # Sets the absolute destination value from a relative destination value.
70
+ # It also stores the given and relative destination. Let's suppose our
71
+ # script is being executed on "dest", it sets the destination root to
72
+ # "dest". The destination, given_destination and relative_destination
73
+ # are related in the following way:
74
+ #
75
+ # inside "bar" do
76
+ # empty_directory "baz"
77
+ # end
78
+ #
79
+ # destination #=> dest/bar/baz
80
+ # relative_destination #=> bar/baz
81
+ # given_destination #=> baz
82
+ #
83
+ def destination=(destination)
84
+ if destination
85
+ @given_destination = convert_encoded_instructions(destination.to_s)
86
+ @destination = ::File.expand_path(@given_destination, base.destination_root)
87
+ @relative_destination = base.relative_to_original_destination_root(@destination)
88
+ end
89
+ end
90
+
91
+ # Filenames in the encoded form are converted. If you have a file:
92
+ #
93
+ # %file_name%.rb
94
+ #
95
+ # It calls #file_name from the base and replaces %-string with the
96
+ # return value (should be String) of #file_name:
97
+ #
98
+ # user.rb
99
+ #
100
+ # The method referenced by %-string SHOULD be public. Otherwise you
101
+ # get the exception with the corresponding error message.
102
+ #
103
+ def convert_encoded_instructions(filename)
104
+ filename.gsub(/%(.*?)%/) do |initial_string|
105
+ call_public_method($1.strip) or initial_string
106
+ end
107
+ end
108
+
109
+ # Calls `base`'s public method `sym`.
110
+ # Returns:: result of `base.sym` or `nil` if `sym` wasn't found in
111
+ # `base`
112
+ # Raises:: Thor::PrivateMethodEncodedError if `sym` references
113
+ # a private method.
114
+ def call_public_method(sym)
115
+ if base.respond_to?(sym)
116
+ base.send(sym)
117
+ elsif base.respond_to?(sym, true)
118
+ raise Thor::PrivateMethodEncodedError,
119
+ "Method #{base.class}##{sym} should be public, not private"
120
+ else
121
+ nil
122
+ end
123
+ end
124
+
125
+ # Receives a hash of options and just execute the block if some
126
+ # conditions are met.
127
+ #
128
+ def invoke_with_conflict_check(&block)
129
+ if exists?
130
+ on_conflict_behavior(&block)
131
+ else
132
+ say_status :create, :green
133
+ block.call unless pretend?
134
+ end
135
+
136
+ destination
137
+ end
138
+
139
+ # What to do when the destination file already exists.
140
+ #
141
+ def on_conflict_behavior(&block)
142
+ say_status :exist, :blue
143
+ end
144
+
145
+ # Shortcut to say_status shell method.
146
+ #
147
+ def say_status(status, color)
148
+ base.shell.say_status status, relative_destination, color if config[:verbose]
149
+ end
150
+
151
+ end
152
+ end
153
+ end