gistdoit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ece0f942669210dc40e8fbaf2db709335256de73
4
+ data.tar.gz: f9a48589427c881d5ae161baf4053c44ef253c2e
5
+ SHA512:
6
+ metadata.gz: 4af73a7269ac649058686d9b24991e9c5f86abf41eaabe2ba0fdc8c7349cb4f8710876d0863a70d651f5d2239610c68d605cb67ff9c071c61ad8a681bd8b5187
7
+ data.tar.gz: 483a301c478082c87e50b2ab32bd0fbf125d50b126655a05e2da2bd0c0ec8137daab4b0c3e8072ae221494b655c5f8a5609080ae798a3dfe9b6c908d79c20806
@@ -0,0 +1,5 @@
1
+ config.yml
2
+ TODO_before_committing
3
+ *.gem
4
+ sketch.md
5
+ playground/*
@@ -0,0 +1,51 @@
1
+ This simple Ruby utility takes a file on your local machine and turns it into a gist on Github.
2
+
3
+ I could have used gems to simplify the development process, but I'm not sure how much code that would have actually saved me writing, and it would have undoubtedly added a layer of complexity in terms of understanding the codebase, so I decided to use only libraries which are built in to Ruby itself.
4
+
5
+ ### Getting started
6
+
7
+ `gem install gistdoit`
8
+
9
+ ### Usage
10
+
11
+ To create a new gist, you simply type `gistdoit` along with the relative file path for the file you want to make a gist out of
12
+
13
+ ```
14
+ // PWD is /Users/AwesomeUser/Dev/Projects
15
+
16
+ gistdoit cool_project_file.rb
17
+ ```
18
+
19
+ If you want to edit a file that is currently on Github, then you can pass the `patch` flag
20
+
21
+ ```
22
+ // PWD is /Users/AwesomeUser/Dev/Projects
23
+
24
+ gistdoit patch cool_project_file.rb
25
+ ```
26
+
27
+ If you like to update your gists remotely on Github, then we recommend that you first make sure that your local gist is up to date with the remote version
28
+
29
+ ```
30
+ // PWD is /Users/AwesomeUser/Dev/Projects
31
+
32
+ gistdoit pull cool_project_file.rb
33
+
34
+ // Gistdoit needs permission to update the file
35
+ Password: ********
36
+
37
+ The file was successfully updated!
38
+ ```
39
+
40
+ At the moment, Gistdoit only recognizes files which were added to gist.github via Gistdoit.
41
+
42
+ ### Internals
43
+
44
+ Gistdoit keeps a record of the full file paths for gists you've uploaded to Github via Gistdoit along with the slug for that file, and a SHA of the file itself. This allows Gistdoit to quickly check for changes in the file without having to parse it.
45
+
46
+ ### Things I would like to add in the future
47
+
48
+ - Allowing the user to select whether they would like a gist to be either secret or public.
49
+ - Listing all gists which the option of limited to a certain number of most recent.
50
+ - Editing a particular gist after selecting it by name.
51
+ - Show the diff of what was changed when files are updated
@@ -0,0 +1,7 @@
1
+ task :test do
2
+ Dir.glob('./test/*_test.rb').each do |test_file|
3
+ require test_file
4
+ end
5
+ end
6
+
7
+ task :default => :test
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
4
+ require 'gistdoit'
5
+
6
+ GistDoIt::CLI.start(*ARGV)
7
+
@@ -0,0 +1 @@
1
+ puts 'hello'
@@ -0,0 +1,18 @@
1
+ $:.unshift(File.expand_path("../lib", __FILE__))
2
+ require 'gistdoit/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "gistdoit"
6
+ s.version = "0.0.0"
7
+ s.date = "2015-08-28"
8
+ s.summary = "File to Gist converter"
9
+ s.description = "An easy way to convert your files to Gists all within the terminal"
10
+ s.authors = ["Liam Brady"]
11
+ s.email = "liamseanbrady+gems@gmail.com"
12
+ s.executables = %w[gistdoit]
13
+ s.files = `git ls-files`.split("\n").reject { |file_name| file_name == 'sketch.md' }
14
+ s.test_files = `git ls-files -- test/*`.split("\n")
15
+ s.require_paths = %w[lib]
16
+ s.version = GistDoIt::VERSION
17
+ s.homepage = "http://github.com/liamseanbrady/gistdoit"
18
+ end
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'gistdoit/github/client'
3
+ require 'gistdoit/net_http_adapter'
4
+ require 'gistdoit/github/user_config'
5
+ require 'gistdoit/gist'
6
+ require 'gistdoit/cli'
@@ -0,0 +1,68 @@
1
+ require 'json'
2
+
3
+ module GistDoIt
4
+ class CLI
5
+ def self.start(*args)
6
+ new.start(args.first)
7
+ end
8
+
9
+ def start(relative_file_path)
10
+ base_file_name = File.basename(relative_file_path)
11
+ file_contents = get_file_contents(relative_file_path)
12
+ description = get_file_description
13
+ create_gist(base_file_name, file_contents, description)
14
+ end
15
+
16
+ def create_gist(base_file_name, file_contents, description)
17
+ gist = Gist.new(name: base_file_name, content: file_contents, summary: description)
18
+ client = Github::Client.new
19
+ response = client.create_gist(gist)
20
+ parsed_response = JSON.parse(response)
21
+ client.github_username = parsed_response['owner']['login'] unless client.has_github_username?
22
+ show_url(parsed_response['html_url'])
23
+ end
24
+
25
+ def show_url(url)
26
+ in_blank_terminal do
27
+ puts "The link is: #{url}"
28
+ end
29
+ end
30
+
31
+ def get_file_contents(relative_file_path)
32
+ path = Dir.pwd
33
+ File.read("#{path}/#{relative_file_path}")
34
+ end
35
+
36
+ def base_file_name(path)
37
+ File.basename(path)
38
+ end
39
+
40
+ def get_file_description
41
+ in_blank_terminal do
42
+ puts "Please describe your file..."
43
+ description = $stdin.gets.chomp
44
+ end
45
+ end
46
+
47
+ def in_blank_terminal
48
+ system 'clear'
49
+ yield
50
+ end
51
+
52
+ def get_token
53
+ in_blank_terminal do
54
+ config_path = File.expand_path('~') + '/.gistdoit'
55
+ if !File.exist?(config_path)
56
+ in_blank_terminal do
57
+ puts "Please enter your token:"
58
+ token = $stdin.gets.chomp
59
+ end
60
+ result = File.open(config_path, 'w') do |file|
61
+ config_data = { 'token' => token }
62
+ file << YAML.dump(config_data)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,45 @@
1
+ require 'yaml'
2
+ require 'gistdoit/github/user_config'
3
+
4
+ module GistDoIt
5
+ class Gist
6
+ def initialize(name: nil, content: nil, summary: nil, user_config: Github::UserConfig.new)
7
+ @name = name
8
+ @content = content
9
+ @summary = summary
10
+ @config = user_config
11
+ end
12
+
13
+ def github_username
14
+ @config.username
15
+ end
16
+
17
+ def content=(file_contents)
18
+ @content = file_contents
19
+ end
20
+
21
+ def content
22
+ @content
23
+ end
24
+
25
+ def summary
26
+ @summary
27
+ end
28
+
29
+ def summary=(text)
30
+ @summary = text
31
+ end
32
+
33
+ def name
34
+ @name
35
+ end
36
+
37
+ def name=(text)
38
+ @name = text
39
+ end
40
+
41
+ def to_json
42
+ { "description" => "#{summary}", "public" => false, "files" => { "#{name}" => { "content" => "#{content}" } } }.to_json
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ require 'json'
2
+ require 'yaml'
3
+ require_relative '../net_http_adapter'
4
+ require_relative './user_config'
5
+
6
+ module Github
7
+ class Client
8
+ def initialize(config = UserConfig.new, network = GistDoIt::NetHTTPAdapter.new)
9
+ @config = config
10
+ @network = network
11
+ end
12
+
13
+ def create_gist(gist)
14
+ @data = gist.to_json
15
+ uri = URI("https://api.github.com/gists")
16
+ @response = @network.post_with_token(token, uri, @data)
17
+ end
18
+
19
+ def has_github_username?
20
+ @config.has_github_username?
21
+ end
22
+
23
+ def github_username=(username)
24
+ @config.set_github_username(username)
25
+ end
26
+
27
+ def response
28
+ @response
29
+ end
30
+
31
+ def token
32
+ @config.token
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ require 'yaml'
2
+
3
+ module Github
4
+ class UserConfig
5
+ # Do we actually need an instance here. Do we require state at any point?
6
+ def initialize(file_path = File.expand_path('~') + '/.gistdoit')
7
+ @file_path = file_path
8
+ end
9
+
10
+ def set_github_username(username)
11
+ File.open(@file_path, 'a') do |file|
12
+ file << YAML.dump({ 'github_username' => username })
13
+ end
14
+ end
15
+
16
+ def has_github_username?
17
+ YAML.load(File.readlines(@file_path).select { |line| !line.include?('---') }.join).key?('github_username')
18
+ end
19
+
20
+ def all
21
+ file = File.read(@file_path)
22
+ YAML.load(file)
23
+ end
24
+
25
+ def [](key)
26
+ all[key]
27
+ end
28
+
29
+ def method_missing(symbol, *args)
30
+ all[symbol.to_s]
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ require 'net/http'
2
+
3
+ module GistDoIt
4
+ class NetHTTPAdapter
5
+ def post_with_token(token, uri, data)
6
+ request = Net::HTTP::Post.new(uri.to_s)
7
+ add_headers_to_request!(request, {"content-type" => "application/json", "Authorization" => "token #{token}"})
8
+ add_body_to_request!(request, data)
9
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
10
+ @response = http.request(request).body
11
+ end
12
+
13
+ @response
14
+ end
15
+
16
+ private
17
+
18
+ def add_headers_to_request!(request, headers)
19
+ headers.each do |header_name, header_value|
20
+ request[header_name] = header_value
21
+ end
22
+ end
23
+
24
+ def add_body_to_request!(request, data)
25
+ request.body = data
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module GistDoIt
2
+ VERSION = '0.0.1'
3
+ end
File without changes
@@ -0,0 +1,68 @@
1
+ require 'minitest/autorun'
2
+ require_relative './test_helper'
3
+ require 'gistdoit/github/client'
4
+
5
+ module Github
6
+ class ClientTest < Minitest::Test
7
+ def setup
8
+ @gist_data = Struct.new(:gist_data) {
9
+ def username
10
+ 'liamseanbrady'
11
+ end
12
+
13
+ def summary
14
+ 'This is a cool gist'
15
+ end
16
+
17
+ def name
18
+ 'file.rb'
19
+ end
20
+
21
+ def content
22
+ 'def new_test; end'
23
+ end
24
+ }.new
25
+ end
26
+
27
+ def teardown
28
+ @gist_data = nil
29
+ end
30
+
31
+ def test_client_gets_response_from_service
32
+ fixture_path = File.expand_path('../fixtures/create_gist_response', __FILE__)
33
+ response = File.read(fixture_path)
34
+
35
+ user_config = Struct.new(:user_config) {
36
+ def token
37
+ 'ab12345'
38
+ end
39
+ }.new
40
+
41
+ test_scope = self
42
+
43
+ network_adapter = Struct.new(:network_adapter) {
44
+ def post_with_token(token, uri, data)
45
+ fixture_path = File.expand_path('../fixtures/create_gist_response', __FILE__)
46
+ File.read(fixture_path)
47
+ end
48
+ }.new
49
+
50
+ client = Client.new(user_config, network_adapter)
51
+ client.create_gist(@gist_data)
52
+
53
+ assert_equal(response, client.response)
54
+ end
55
+
56
+ def test_token
57
+ user_config = Struct.new(:user_config) {
58
+ def token
59
+ 'ab12345'
60
+ end
61
+ }.new
62
+
63
+ client = Client.new(user_config)
64
+
65
+ assert_equal('ab12345', client.token)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+
3
+ class CommandLineTest < Minitest::Test
4
+ end
@@ -0,0 +1,80 @@
1
+ {
2
+ "url": "https://api.github.com/gists/e0e1a3cddec61ee89289",
3
+ "forks_url": "https://api.github.com/gists/e0e1a3cddec61ee89289/forks",
4
+ "commits_url": "https://api.github.com/gists/e0e1a3cddec61ee89289/commits",
5
+ "id": "e0e1a3cddec61ee89289",
6
+ "git_pull_url": "https://gist.github.com/e0e1a3cddec61ee89289.git",
7
+ "git_push_url": "https://gist.github.com/e0e1a3cddec61ee89289.git",
8
+ "html_url": "https://gist.github.com/e0e1a3cddec61ee89289",
9
+ "files": {
10
+ "file1.txt": {
11
+ "filename": "file1.txt",
12
+ "type": "text/plain",
13
+ "language": "Text",
14
+ "raw_url": "https://gist.githubusercontent.com/liamseanbrady/e0e1a3cddec61ee89289/raw/043a3b46337b46164a5626816c2984b48be968ea/file1.txt",
15
+ "size": 4,
16
+ "truncated": false,
17
+ "content": "Demo"
18
+ }
19
+ },
20
+ "public": false,
21
+ "created_at": "2015-08-24T12:12:50Z",
22
+ "updated_at": "2015-08-24T12:12:50Z",
23
+ "description": "Created via API",
24
+ "comments": 0,
25
+ "user": null,
26
+ "comments_url": "https://api.github.com/gists/e0e1a3cddec61ee89289/comments",
27
+ "owner": {
28
+ "login": "liamseanbrady",
29
+ "id": 8338057,
30
+ "avatar_url": "https://avatars.githubusercontent.com/u/8338057?v=3",
31
+ "gravatar_id": "",
32
+ "url": "https://api.github.com/users/liamseanbrady",
33
+ "html_url": "https://github.com/liamseanbrady",
34
+ "followers_url": "https://api.github.com/users/liamseanbrady/followers",
35
+ "following_url": "https://api.github.com/users/liamseanbrady/following{/other_user}",
36
+ "gists_url": "https://api.github.com/users/liamseanbrady/gists{/gist_id}",
37
+ "starred_url": "https://api.github.com/users/liamseanbrady/starred{/owner}{/repo}",
38
+ "subscriptions_url": "https://api.github.com/users/liamseanbrady/subscriptions",
39
+ "organizations_url": "https://api.github.com/users/liamseanbrady/orgs",
40
+ "repos_url": "https://api.github.com/users/liamseanbrady/repos",
41
+ "events_url": "https://api.github.com/users/liamseanbrady/events{/privacy}",
42
+ "received_events_url": "https://api.github.com/users/liamseanbrady/received_events",
43
+ "type": "User",
44
+ "site_admin": false
45
+ },
46
+ "forks": [
47
+
48
+ ],
49
+ "history": [
50
+ {
51
+ "user": {
52
+ "login": "liamseanbrady",
53
+ "id": 8338057,
54
+ "avatar_url": "https://avatars.githubusercontent.com/u/8338057?v=3",
55
+ "gravatar_id": "",
56
+ "url": "https://api.github.com/users/liamseanbrady",
57
+ "html_url": "https://github.com/liamseanbrady",
58
+ "followers_url": "https://api.github.com/users/liamseanbrady/followers",
59
+ "following_url": "https://api.github.com/users/liamseanbrady/following{/other_user}",
60
+ "gists_url": "https://api.github.com/users/liamseanbrady/gists{/gist_id}",
61
+ "starred_url": "https://api.github.com/users/liamseanbrady/starred{/owner}{/repo}",
62
+ "subscriptions_url": "https://api.github.com/users/liamseanbrady/subscriptions",
63
+ "organizations_url": "https://api.github.com/users/liamseanbrady/orgs",
64
+ "repos_url": "https://api.github.com/users/liamseanbrady/repos",
65
+ "events_url": "https://api.github.com/users/liamseanbrady/events{/privacy}",
66
+ "received_events_url": "https://api.github.com/users/liamseanbrady/received_events",
67
+ "type": "User",
68
+ "site_admin": false
69
+ },
70
+ "version": "3439bbd04f75067672425b9f51a11170c072aaf6",
71
+ "committed_at": "2015-08-24T12:12:50Z",
72
+ "change_status": {
73
+ "total": 1,
74
+ "additions": 1,
75
+ "deletions": 0
76
+ },
77
+ "url": "https://api.github.com/gists/e0e1a3cddec61ee89289/3439bbd04f75067672425b9f51a11170c072aaf6"
78
+ }
79
+ ]
80
+ }
@@ -0,0 +1,54 @@
1
+ require 'minitest/autorun'
2
+ require_relative './test_helper'
3
+ require 'gistdoit/gist'
4
+
5
+ class GistTests < Minitest::Test
6
+ def test_gist_reads_username_from_config_file
7
+ user_config = Struct.new(:user_config) {
8
+ def username
9
+ 'liamseanbrady'
10
+ end
11
+ }.new
12
+
13
+ gist = GistDoIt::Gist.new(user_config: user_config)
14
+
15
+ assert_equal('liamseanbrady', gist.github_username)
16
+ end
17
+
18
+ def test_gist_has_a_summary
19
+ user_config = Struct.new(:user_config) {
20
+ def username
21
+ 'liamseanbrady'
22
+ end
23
+ }.new
24
+
25
+ gist = GistDoIt::Gist.new(user_config: user_config, summary: 'A good summary')
26
+
27
+ assert_equal('A good summary', gist.summary)
28
+ end
29
+
30
+
31
+ def test_gist_has_a_name
32
+ user_config = Struct.new(:user_config) {
33
+ def username
34
+ 'liamseanbrady'
35
+ end
36
+ }.new
37
+
38
+ gist = GistDoIt::Gist.new(user_config: user_config, name: 'my_gist.rb')
39
+
40
+ assert_equal('my_gist.rb', gist.name)
41
+ end
42
+
43
+ def test_gist_has_content
44
+ user_config = Struct.new(:user_config) {
45
+ def username
46
+ 'liamseanbrady'
47
+ end
48
+ }.new
49
+
50
+ gist = GistDoIt::Gist.new(user_config: user_config, content: 'def new_method; end')
51
+
52
+ assert_equal('def new_method; end', gist.content)
53
+ end
54
+ end
@@ -0,0 +1 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
@@ -0,0 +1,39 @@
1
+ require 'minitest/autorun'
2
+ require_relative './test_helper'
3
+ require 'gistdoit/github/user_config'
4
+
5
+ module Github
6
+ class ConfigTest < Minitest::Test
7
+ def test_parses_yaml_from_file
8
+ config_file_path = File.expand_path('../fixtures/config.yml', __FILE__)
9
+ user_config = UserConfig.new(config_file_path)
10
+ config_data = { 'username' => 'liamseanbrady', 'token' => 'ab12345' }
11
+
12
+ assert_equal(config_data, user_config.all)
13
+ end
14
+
15
+ def test_returns_value_if_key_exists
16
+ config_file_path = File.expand_path('../fixtures/config.yml', __FILE__)
17
+ user_config = UserConfig.new(config_file_path)
18
+ config_data = { 'username' => 'liamseanbrady', 'token' => 'ab12345' }
19
+
20
+ assert_equal('ab12345', user_config['token'])
21
+ end
22
+
23
+ def test_returns_nil_if_no_method_exists_for_a_key
24
+ config_file_path = File.expand_path('../fixtures/config.yml', __FILE__)
25
+ user_config = UserConfig.new(config_file_path)
26
+ config_data = { 'username' => 'liamseanbrady', 'token' => 'ab12345' }
27
+
28
+ assert_equal(nil, user_config.method_that_does_not_exist)
29
+ end
30
+
31
+ def test_returns_correct_value_if_method_exists_for_a_key
32
+ config_file_path = File.expand_path('../fixtures/config.yml', __FILE__)
33
+ user_config = UserConfig.new(config_file_path)
34
+ config_data = { 'username' => 'liamseanbrady', 'token' => 'ab12345' }
35
+
36
+ assert_equal('liamseanbrady', user_config.username)
37
+ end
38
+ end
39
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gistdoit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Liam Brady
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: An easy way to convert your files to Gists all within the terminal
14
+ email: liamseanbrady+gems@gmail.com
15
+ executables:
16
+ - gistdoit
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - README.md
22
+ - Rakefile
23
+ - bin/gistdoit
24
+ - content.rb
25
+ - gistdoit.gemspec
26
+ - lib/gistdoit.rb
27
+ - lib/gistdoit/cli.rb
28
+ - lib/gistdoit/gist.rb
29
+ - lib/gistdoit/github/client.rb
30
+ - lib/gistdoit/github/user_config.rb
31
+ - lib/gistdoit/net_http_adapter.rb
32
+ - lib/gistdoit/version.rb
33
+ - test/cli_test.rb
34
+ - test/client_test.rb
35
+ - test/command_line_test.rb
36
+ - test/fixtures/create_gist_response
37
+ - test/gist_test.rb
38
+ - test/test_helper.rb
39
+ - test/user_config_test.rb
40
+ homepage: http://github.com/liamseanbrady/gistdoit
41
+ licenses: []
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.2.2
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: File to Gist converter
63
+ test_files:
64
+ - test/cli_test.rb
65
+ - test/client_test.rb
66
+ - test/command_line_test.rb
67
+ - test/fixtures/create_gist_response
68
+ - test/gist_test.rb
69
+ - test/test_helper.rb
70
+ - test/user_config_test.rb