jist 0.9.2 → 1.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.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ .rvmrc
2
+ Gemfile.lock
3
+
4
+ # OS X
5
+ .DS_Store
6
+ .yardoc
7
+ doc
8
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format progress
3
+ -r ./spec/spec_helper.rb
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE.MIT ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Conrad Irwin <conrad.irwin@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,164 @@
1
+ Jist is a gem that allows you to publish a [gist](https://gist.github.com) from Ruby.
2
+
3
+ # Installation
4
+
5
+ As with all ruby gems, you can install Jist (assuming you have ruby and rubygems) with:
6
+
7
+ ```shell
8
+ $ gem install jist
9
+ ```
10
+
11
+ If you want to use the library in your application, and you're using Bundler. Add the
12
+ following to your Gemfile.
13
+
14
+ ```ruby
15
+ source :rubygems
16
+ gem 'jist'
17
+ ```
18
+
19
+ # Command
20
+
21
+ The jist gem provides a `jist` command that you can use from your terminal to
22
+ upload content to https://gist.github.com/.
23
+
24
+ It's easy to use. To upload the contents of `a.rb` just:
25
+
26
+ ```shell
27
+ $ jist a.rb
28
+ https://gist.github.com/0d07bc98c139810a4075
29
+ ```
30
+
31
+ By default it reads from STDIN, and you can set a filename with `-f`.
32
+
33
+ ```shell
34
+ $ jist -f test.rb <a.rb
35
+ https://gist.github.com/7db51bb5f4f35c480fc8
36
+ ```
37
+
38
+ Alternatively, you can just paste from the clipboard:
39
+
40
+ ```shell
41
+ $ jist -P
42
+ https://gist.github.com/6a330a11a0db8e52a6ee
43
+ ```
44
+
45
+ Use `-p` to make the gist public and `-d` to add a description.
46
+ ```shell
47
+ $ jist -p -d "Random rbx bug" a.rb
48
+ https://gist.github.com/2977722
49
+ ```
50
+
51
+ You can update existing gists with `-u`:
52
+
53
+ ```shell
54
+ $ jist lib/jist.rb bin/jist -u 42f2c239d2eb57299408
55
+ https://gist.github.com/42f2c239d2eb57299408
56
+ ```
57
+
58
+ If you'd like to copy the resulting URL to your clipboard, use `-c`.
59
+
60
+ ```shell
61
+ $ jist -c <a.rb
62
+ https://gist.github.com/7db51bb5f4f35c480fc8
63
+ ```
64
+
65
+ And you can just ask jist to open a browser window directly with `-o`.
66
+
67
+ ```shell
68
+ $ jist -o <a.rb
69
+ https://gist.github.com/7db51bb5f4f35c480fc8
70
+ ```
71
+
72
+ See `jist --help` for more detail.
73
+
74
+ ## Login
75
+
76
+ If you want to associate your gists with your github account, you need to login
77
+ with jist. It doesn't store your username and password, it just uses them to get
78
+ an OAuth2 token (with the "gist" permission).
79
+
80
+ ```shell
81
+ jist --login
82
+ Obtaining OAuth2 access_token from github.
83
+ Github username: ConradIrwin
84
+ Github password:
85
+ Success! https://github.com/settings/applications
86
+ ```
87
+
88
+ This token is stored in `~/.jist` and used for all future gisting. If you need to
89
+ you can revoke it from https://github.com/settings/applications, or just delete the
90
+ file.
91
+
92
+ After you've done this, you can still upload gists anonymously with `-a`.
93
+
94
+ ```shell
95
+ jist -a a.rb
96
+ https://gist.github.com/6bf7ec379fc9119b1f15
97
+ ```
98
+
99
+ # Library
100
+
101
+ You can also use Jist as a library from inside your ruby code:
102
+
103
+ ```ruby
104
+ Jist.gist("Look.at(:my => 'awesome').code")
105
+ ```
106
+
107
+ If you need more advanced features you can also pass:
108
+
109
+ * `:access_token` to authenticate using OAuth2 (default is `File.read("~/.jist")).
110
+ * `:filename` to change the syntax highlighting (default is `a.rb`).
111
+ * `:public` if you want your gist to have a guessable url.
112
+ * `:description` to add a description to your gist.
113
+ * `:update` to update an existing gist (can be a URL or an id).
114
+ * `:anonymous` to submit an anonymous gist (default is false).
115
+ * `:copy` to copy the resulting URL to the clipboard (default is false).
116
+ * `:open` to open the resulting URL in a browser (default is false).
117
+
118
+ NOTE: The access_token must have the "gist" scope.
119
+
120
+ If you want to upload multiple files in the same gist, you can:
121
+
122
+ ```ruby
123
+ Jist.multi_gist("a.rb" => "Foo.bar", "a.py" => "Foo.bar")
124
+ ```
125
+
126
+ If you'd rather use jist's builtin access_token, then you can force the user to
127
+ obtain one by calling:
128
+
129
+ ```ruby
130
+ Jist.login!
131
+ ```
132
+
133
+ This will take them through the process of obtaining an OAuth2 token, and storing it
134
+ in `~/.jist`, where it can later be read by `Jist.gist`
135
+
136
+ Configuration
137
+ =============
138
+
139
+ If you'd like `-o` or `-c` to be the default when you use the jist executable, add an
140
+ alias to your `~/.bashrc` (or equivalent). For example:
141
+
142
+ ```ruby
143
+ alias jist='jist -c'
144
+ ```
145
+
146
+ If you'd prefer jist to open a different browser, then you can export the BROWSER
147
+ environment variable:
148
+
149
+ ```ruby
150
+ export BROWSER=google-chrome
151
+ ```
152
+
153
+ If clipboard or browser integration don't work on your platform, please file a bug or
154
+ (more ideally) a pull request.
155
+
156
+ If you need to use an HTTP proxy to access the internet, export the `HTTP_PROXY` or
157
+ `http_proxy` environment variable and jist will use it.
158
+
159
+ Meta-fu
160
+ =======
161
+
162
+ I wrote this because the `gist` gem is out of action, and has been for many months.
163
+
164
+ It's licensed under the MIT license, and bug-reports, and pull requests are welcome.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ task :default => :test
2
+
3
+ desc 'run the tests' # that's non-DRY
4
+ task :test do
5
+ sh 'rspec spec'
6
+ end
data/bin/jist CHANGED
@@ -13,9 +13,6 @@ opts = OptionParser.new do |opts|
13
13
  opts.banner = <<-EOS
14
14
  Jist (v#{Jist::VERSION}) lets you upload to https://gist.github.com/
15
15
 
16
- Usage: #{executable_name} [-p] [-d DESC] [-t TOKEN|-a] [-u URL] [-f NAME]* [FILE]*
17
- #{executable_name} --login
18
-
19
16
  The content to be uploaded can be passed as a list of files, if none are
20
17
  specified STDIN will be read. The default filename for STDIN is "a.rb", and all
21
18
  filenames can be overridden by repeating the "-f" flag. The most useful reason
@@ -32,10 +29,17 @@ Anonymous gists are not associated with your GitHub account, they can be created
32
29
  with "-a" even after you have used "jist --login". If you already have an access
33
30
  token with the "gist" scope, you can pass that with "-t".
34
31
 
32
+ To copy the resulting URL to your clipboard you can use the -c option, or to just
33
+ open it directly in your browser, use -o. You can add `alias jist='jist -c'` to
34
+ your shell's rc file to configure this behaviour by default.
35
+
35
36
  Instead of creating a new jist, you can update an existing one by passing its ID
36
37
  or URL with "-u". For this to work, you must be logged in, and have created the
37
38
  original gist with the same GitHub account.
38
39
 
40
+ Usage: #{executable_name} [-o|-c] [-p] [-d DESC] [-t TOKEN|-a] [-u URL] [-P] [-f NAME]* FILE*
41
+ #{executable_name} --login
42
+
39
43
  EOS
40
44
 
41
45
  opts.on("--login", "Authenticate jist on this computer.") do
@@ -68,6 +72,18 @@ original gist with the same GitHub account.
68
72
  options[:access_token] = token
69
73
  end
70
74
 
75
+ opts.on("-c", "--copy", "Copy the resulting URL to the clipboard") do
76
+ options[:copy] = true
77
+ end
78
+
79
+ opts.on("-o", "--open", "Open the resulting URL in a browser") do
80
+ options[:open] = true
81
+ end
82
+
83
+ opts.on("-P", "--paste", "Paste from the clipboard to jist") do
84
+ options[:paste] = true
85
+ end
86
+
71
87
  opts.on_tail("-h","--help", "Show this message.") do
72
88
  puts opts
73
89
  exit
@@ -82,7 +98,9 @@ end
82
98
  opts.parse!
83
99
 
84
100
  begin
85
- if ARGV.size == 0
101
+ if options[:paste]
102
+ puts Jist.gist(Jist.paste, options)['html_url']
103
+ elsif ARGV.size == 0
86
104
  $stderr.puts "(type a gist. <ctrl-c> to cancel, <ctrl-d> when done)" if $stdin.tty?
87
105
  puts Jist.gist(ARGF.read, options)['html_url']
88
106
  else
data/jist.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ require './lib/jist'
2
+ Gem::Specification.new do |s|
3
+ s.name = 'jist'
4
+ s.version = Jist::VERSION
5
+ s.summary = 'Just allows you to upload gists'
6
+ s.description = 'Provides a single function (Jist.gist) that uploads a gist.'
7
+ s.homepage = 'https://github.com/ConradIrwin/jist'
8
+ s.email = 'conrad.irwin@gmail.com'
9
+ s.authors = ['Conrad Irwin']
10
+ s.license = 'MIT'
11
+ s.files = `git ls-files`.split("\n")
12
+ s.require_paths = ["lib"]
13
+
14
+ s.executables << 'jist'
15
+
16
+ s.add_dependency 'json'
17
+ %w(rake rspec).each do |gem|
18
+ s.add_development_dependency gem
19
+ end
20
+ end
data/lib/jist.rb CHANGED
@@ -4,13 +4,21 @@ require 'json'
4
4
 
5
5
  # It just gists.
6
6
  module Jist
7
+ extend self
7
8
 
8
- VERSION = '0.9.2'
9
+ VERSION = '1.1.0'
10
+
11
+ # A list of clipboard commands with copy and paste support.
12
+ CLIPBOARD_COMMANDS = {
13
+ 'xclip' => 'xclip -o',
14
+ 'xsel' => 'xsel -o',
15
+ 'pbcopy' => 'pbpaste',
16
+ 'putclip' => 'getclip'
17
+ }
9
18
 
10
19
  # Exception tag for errors raised while gisting.
11
20
  module Error; end
12
21
 
13
- module_function
14
22
  # Upload a gist to https://gist.github.com
15
23
  #
16
24
  # @param [String] content the code you'd like to gist
@@ -22,6 +30,8 @@ module Jist
22
30
  # @option options [Boolean] :anonymous (false) is this gist anonymous
23
31
  # @option options [String] :access_token (`File.read("~/.jist")`) The OAuth2 access token.
24
32
  # @option options [String] :update the URL or id of a gist to update
33
+ # @option options [Boolean] :copy (false) Copy resulting URL to clipboard, if successful.
34
+ # @option options [Boolean] :open (false) Open the resulting URL in a browser.
25
35
  #
26
36
  # @return [Hash] the decoded JSON response from the server
27
37
  # @raise [Jist::Error] if something went wrong
@@ -42,6 +52,8 @@ module Jist
42
52
  # @option options [Boolean] :anonymous (false) is this gist anonymous
43
53
  # @option options [String] :access_token (`File.read("~/.jist")`) The OAuth2 access token.
44
54
  # @option options [String] :update the URL or id of a gist to update
55
+ # @option options [Boolean] :copy (false) Copy resulting URL to clipboard, if successful.
56
+ # @option options [Boolean] :open (false) Open the resulting URL in a browser.
45
57
  #
46
58
  # @return [Hash] the decoded JSON response from the server
47
59
  # @raise [Jist::Error] if something went wrong
@@ -79,7 +91,7 @@ module Jist
79
91
  begin
80
92
  response = http(request)
81
93
  if Net::HTTPSuccess === response
82
- JSON.parse(response.body)
94
+ on_success(response.body, options)
83
95
  else
84
96
  raise "Got #{response.class} from gist: #{response.body}"
85
97
  end
@@ -136,20 +148,105 @@ module Jist
136
148
  raise e.extend Error
137
149
  end
138
150
 
139
- # Run an HTTP operation against api.github.com
151
+ # Return HTTP connection
140
152
  #
141
- # @param [Net::HTTPRequest] request
142
- # @return [Net::HTTPResponse]
143
- def http(request)
144
- connection = Net::HTTP.new("api.github.com", 443)
153
+ # @return [Net::HTTP]
154
+ def http_connection
155
+ env = ENV['http_proxy'] || ENV['HTTP_PROXY']
156
+ connection = if env
157
+ uri = URI(env)
158
+ proxy_host, proxy_port = uri.host, uri.port
159
+ Net::HTTP::Proxy(proxy_host, proxy_port).new("api.github.com", 443)
160
+ else
161
+ Net::HTTP.new("api.github.com", 443)
162
+ end
145
163
  connection.use_ssl = true
146
164
  connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
147
165
  connection.open_timeout = 10
148
166
  connection.read_timeout = 10
149
- connection.start do |http|
167
+ connection
168
+ end
169
+
170
+ # Run an HTTP operation against api.github.com
171
+ #
172
+ # @param [Net::HTTPRequest] request
173
+ # @return [Net::HTTPResponse]
174
+ def http(request)
175
+ http_connection().start do |http|
150
176
  http.request request
151
177
  end
152
178
  rescue Timeout::Error
153
179
  raise "Could not connect to https://api.github.com/"
154
180
  end
181
+
182
+ # Called after an HTTP response to gist to perform post-processing.
183
+ #
184
+ # @param [String] body the HTTP-200 response
185
+ # @param [Hash] options any options
186
+ # @option options [Boolean] :copy copy the URL to the clipboard
187
+ # @return [Hash] the parsed JSON response from the server
188
+ def on_success(body, options={})
189
+ json = JSON.parse(body)
190
+
191
+ Jist.copy(json['html_url']) if options[:copy]
192
+ Jist.open(json['html_url']) if options[:open]
193
+
194
+ json
195
+ end
196
+
197
+ # Copy a string to the clipboard.
198
+ #
199
+ # @param [String] content
200
+ # @raise [RuntimeError] if no clipboard integration could be found
201
+ #
202
+ # This method was heavily inspired by defunkt's Gist#copy,
203
+ # @see https://github.com/defunkt/gist/blob/bca9b29/lib/gist.rb#L178
204
+ def copy(content)
205
+ IO.popen(clipboard_command(:copy), 'r+') { |clip| clip.print content }
206
+ raise "Copying to clipboard failed" unless paste == content
207
+ end
208
+
209
+ # Get a string from the clipboard.
210
+ #
211
+ # @param [String] content
212
+ # @raise [RuntimeError] if no clipboard integration could be found
213
+ def paste
214
+ `#{clipboard_command(:paste)}`
215
+ end
216
+
217
+ # Get the command to use for the clipboard action.
218
+ #
219
+ # @param [Symbol] action either :copy or :paste
220
+ # @return [String] the command to run
221
+ # @raise [RuntimeError] if no clipboard integration could be found
222
+ def clipboard_command(action)
223
+ command = CLIPBOARD_COMMANDS.keys.detect do |cmd|
224
+ system("type #{cmd} >/dev/null 2>&1")
225
+ end
226
+ raise "Could not find copy command, tried: #{CLIPBOARD_COMMANDS}" unless command
227
+ action == :copy ? command : CLIPBOARD_COMMANDS[command]
228
+ end
229
+
230
+ # Open a URL in a browser.
231
+ #
232
+ # @param [String] url
233
+ # @raise [RuntimeError] if no browser integration could be found
234
+ #
235
+ # This method was heavily inspired by defunkt's Gist#open,
236
+ # @see https://github.com/defunkt/gist/blob/bca9b29/lib/gist.rb#L157
237
+ def open(url)
238
+ command = if ENV['BROWSER']
239
+ ENV['BROWSER']
240
+ elsif RUBY_PLATFORM =~ /darwin/
241
+ 'open'
242
+ elsif RUBY_PLATFORM =~ /linux/
243
+ 'sensible-browser'
244
+ elsif ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw|wince/i
245
+ 'start ""'
246
+ else
247
+ raise "Could not work out how to use a browser."
248
+ end
249
+
250
+ `#{command} #{url}`
251
+ end
155
252
  end
@@ -0,0 +1,34 @@
1
+ describe '...' do
2
+ before do
3
+ @saved_path = ENV['PATH']
4
+ @bobo_url = 'http://example.com'
5
+ end
6
+
7
+ after do
8
+ ENV['PATH'] = @saved_path
9
+ end
10
+
11
+ def ask_for_copy
12
+ Jist.on_success({'html_url' => @bobo_url}.to_json, :copy => true )
13
+ end
14
+ def jist_but_dont_ask_for_copy
15
+ Jist.on_success({'html_url' => 'http://example.com/'}.to_json)
16
+ end
17
+
18
+ it 'should try to copy the url when the clipboard option is passed' do
19
+ Jist.should_receive(:copy).with(@bobo_url)
20
+ ask_for_copy
21
+ end
22
+
23
+ it "should not copy when not asked to" do
24
+ Jist.should_not_receive(:copy).with(@bobo_url)
25
+ jist_but_dont_ask_for_copy
26
+ end
27
+
28
+ it "should raise an error if no copying mechanisms are available" do
29
+ ENV['PATH'] = ''
30
+ lambda{
31
+ ask_for_copy
32
+ }.should raise_error(/Could not find copy command/)
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ describe '...' do
2
+ before do
3
+ @saved_env = ENV['HTTP_PROXY']
4
+ end
5
+
6
+ after do
7
+ ENV['HTTP_PROXY'] = @saved_env
8
+ end
9
+
10
+ it "should be Net::HTTP when $HTTP_PROXY wasn't set" do
11
+ ENV['HTTP_PROXY'] = ''
12
+ Jist.http_connection().should be_an_instance_of(Net::HTTP)
13
+ end
14
+
15
+ it "should be Net::HTTP::Proxy when $HTTP_PROXY was set" do
16
+ ENV['HTTP_PROXY'] = 'http://proxy.example.com:8080'
17
+ Jist.http_connection().should_not be_an_instance_of(Net::HTTP)
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper.rb"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+ end
12
+
13
+ require_relative '../lib/jist'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-24 00:00:00.000000000 Z
12
+ date: 2012-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -27,6 +27,38 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
30
62
  description: Provides a single function (Jist.gist) that uploads a gist.
31
63
  email: conrad.irwin@gmail.com
32
64
  executables:
@@ -34,10 +66,21 @@ executables:
34
66
  extensions: []
35
67
  extra_rdoc_files: []
36
68
  files:
37
- - lib/jist.rb
69
+ - .gitignore
70
+ - .rspec
71
+ - Gemfile
72
+ - LICENSE.MIT
73
+ - README.md
74
+ - Rakefile
38
75
  - bin/jist
76
+ - jist.gemspec
77
+ - lib/jist.rb
78
+ - spec/clipboard_spec.rb
79
+ - spec/proxy_spec.rb
80
+ - spec/spec_helper.rb
39
81
  homepage: https://github.com/ConradIrwin/jist
40
- licenses: []
82
+ licenses:
83
+ - MIT
41
84
  post_install_message:
42
85
  rdoc_options: []
43
86
  require_paths: