shard 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/shard ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift 'lib'
4
+
5
+ require 'thor'
6
+ require 'shard'
7
+ require 'shard/cli'
8
+
9
+ Shard::CLI.start(ARGV)
data/lib/shard.rb ADDED
@@ -0,0 +1,13 @@
1
+ class Shard
2
+ class << self
3
+ attr_accessor :current_loader
4
+ end
5
+ end
6
+
7
+ require 'shard/shard_directory'
8
+ require 'shard/loader'
9
+ require 'shard/saver'
10
+ require 'shard/lister'
11
+ require 'shard/gist'
12
+ require 'shard/shard_record'
13
+ require 'shard/kernel'
data/lib/shard/cli.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'thor'
2
+
3
+ class Shard::CLI < Thor
4
+
5
+ ########
6
+ # #
7
+ # List #
8
+ # #
9
+ ########
10
+
11
+ desc "list USERNAME", "List all shards for Github user USERNAME"
12
+
13
+ def list(username)
14
+ lister = Shard::Lister.new(username)
15
+
16
+ if lister.shards.any?
17
+ puts "Shards for Github user #{ username }:"
18
+ puts
19
+
20
+ lister.shard_names.each do |name|
21
+ shard = lister.shards[name]
22
+ puts "#{ name }:"
23
+ puts " Description | #{ shard.description }"
24
+ puts " URL | #{ shard.url }"
25
+ puts
26
+ end
27
+ else
28
+ puts "Github user #{ username } does not have any shards."
29
+ puts "Shards are gists that have a file named shard.rb or <foo>.shard.rb"
30
+ end
31
+ end
32
+
33
+ ########
34
+ # #
35
+ # Exec #
36
+ # #
37
+ ########
38
+
39
+ desc "exec USERNAME/SHARD", "Runs the shard named SHARD for Github user USERNAME"
40
+
41
+ def exec(shard_line)
42
+ Shard::Loader.load shard_line
43
+ end
44
+
45
+ #########
46
+ # #
47
+ # Fetch #
48
+ # #
49
+ #########
50
+
51
+ desc "fetch USERNAME/SHARD", "Downloads the shard named SHARD for Github user USERNAME"
52
+
53
+ def fetch(shard_line)
54
+ username, shard = shard_line.split '/'
55
+ shard = Shard::ShardRecord.new(username, shard, 'HEAD')
56
+
57
+ Shard::Saver.save(shard, verbose: true)
58
+ end
59
+
60
+ ########
61
+ # #
62
+ # Test #
63
+ # #
64
+ ########
65
+
66
+ desc "test USERNAME/SHARD", "Runs the tests for shard named SHARD for Github user USERNAME"
67
+
68
+ def test(shard_line)
69
+ Shard::Loader.test shard_line
70
+ end
71
+
72
+ end
data/lib/shard/gist.rb ADDED
@@ -0,0 +1,78 @@
1
+ require 'yaml'
2
+
3
+ class Shard
4
+
5
+ class Gist
6
+
7
+ ################
8
+ # #
9
+ # Declarations #
10
+ # #
11
+ ################
12
+
13
+ SHARD_FILENAME = /(?:^(\w+)\.)?shard\.rb$/
14
+
15
+ ###############
16
+ # #
17
+ # Constructor #
18
+ # #
19
+ ###############
20
+
21
+ def initialize(gist_hash)
22
+ @gist_hash = gist_hash
23
+ end
24
+
25
+ ####################
26
+ # #
27
+ # Instance Methods #
28
+ # #
29
+ ####################
30
+
31
+ def all_files
32
+ files.values
33
+ end
34
+
35
+ def description
36
+ @gist_hash.description
37
+ end
38
+
39
+ def id
40
+ @gist_hash.id
41
+ end
42
+
43
+ def name
44
+ match = shard_file.filename.match(SHARD_FILENAME)
45
+
46
+ match[1] || id
47
+ end
48
+
49
+ def ruby_files
50
+ files.select { |filename| filename =~ /\.rb$/ }.values
51
+ end
52
+
53
+ def shard_file
54
+ files.select { |filename| filename =~ SHARD_FILENAME }.values.first
55
+ end
56
+
57
+ def url
58
+ @gist_hash.html_url
59
+ end
60
+
61
+ def username
62
+ @gist_hash.user.login
63
+ end
64
+
65
+ def valid_shard?
66
+ ! shard_file.nil?
67
+ end
68
+
69
+ private
70
+
71
+ def files
72
+ @gist_hash.files
73
+ end
74
+
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,7 @@
1
+ module Kernel
2
+
3
+ def shard(shard_line)
4
+ Shard::Loader.load(shard_line)
5
+ end
6
+
7
+ end
@@ -0,0 +1,60 @@
1
+ require 'octokit'
2
+
3
+ class Shard
4
+
5
+ class Lister
6
+
7
+ ################
8
+ # #
9
+ # Declarations #
10
+ # #
11
+ ################
12
+
13
+ attr_reader :username
14
+
15
+ ###############
16
+ # #
17
+ # Constructor #
18
+ # #
19
+ ###############
20
+
21
+ def initialize(username)
22
+ @username = username
23
+ end
24
+
25
+ ####################
26
+ # #
27
+ # Instance Methods #
28
+ # #
29
+ ####################
30
+
31
+ def gists
32
+ @gists ||= fetch_gists.map { |gist| Gist.new(gist) }
33
+ end
34
+
35
+ def shards
36
+ @shards ||= Hash.new.tap do |hash|
37
+ valid = gists.select { |gist| gist.valid_shard? }
38
+ valid.each do |shard|
39
+ hash[shard.name] = shard
40
+ end
41
+ end
42
+ end
43
+
44
+ def shard_names
45
+ shards.keys.sort
46
+ end
47
+
48
+ private
49
+
50
+ def fetch_gists
51
+ Octokit.gists username
52
+ end
53
+
54
+ def gist_by_id(id)
55
+ gists.detect { |gist| gist.id == id.to_s }
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,115 @@
1
+ class Shard
2
+
3
+ class Loader
4
+
5
+ ################
6
+ # #
7
+ # Declarations #
8
+ # #
9
+ ################
10
+
11
+ include ShardDirectory
12
+
13
+ attr_reader :shard
14
+
15
+ SHARD_LINE_REGEX = %r{([a-zA-Z0-9_-]+)/(\w+)(?::(\w+))?}
16
+
17
+ ###############
18
+ # #
19
+ # Constructor #
20
+ # #
21
+ ###############
22
+
23
+ def initialize(shard_line)
24
+ parse_shard_line(shard_line)
25
+ end
26
+
27
+ #################
28
+ # #
29
+ # Class Methods #
30
+ # #
31
+ #################
32
+
33
+ def self.load(shard_line)
34
+ new(shard_line).load
35
+ end
36
+
37
+ def self.test(shard_line)
38
+ new(shard_line).test
39
+ end
40
+
41
+ ####################
42
+ # #
43
+ # Instance Methods #
44
+ # #
45
+ ####################
46
+
47
+ def load
48
+ ensure_shard_saved
49
+
50
+ Shard.current_loader, previous_loader = self, Shard.current_loader
51
+ require shard_file_path
52
+ Shard.current_loader = previous_loader
53
+ end
54
+
55
+ def load_file(filename)
56
+ path = filename ? ruby_file_path(filename) : shard_file_path
57
+ require path
58
+ end
59
+
60
+ def test
61
+ ensure_shard_saved
62
+
63
+ Shard.current_loader, previous_loader = self, Shard.current_loader
64
+ require *shard_test_paths
65
+ Shard.current_loader = previous_loader
66
+ end
67
+
68
+ private
69
+
70
+ def already_loaded?
71
+ shard_dir_exists?(shard.username, shard.name, shard.version)
72
+ end
73
+
74
+ def ensure_shard_saved
75
+ unless already_loaded?
76
+ Shard::Saver.save shard
77
+ end
78
+ end
79
+
80
+ def parse_shard_line(shard_line)
81
+ if match = shard_line.match(SHARD_LINE_REGEX)
82
+ username = match[1]
83
+ name = match[2]
84
+ version = parse_version match[3]
85
+
86
+ @shard = Shard::ShardRecord.new(username, name, version)
87
+ end
88
+ end
89
+
90
+ def parse_version(raw_version)
91
+ raw_version || 'HEAD'
92
+ end
93
+
94
+ def ruby_file_path(filename)
95
+ file_path(shard.username, shard.name, shard.version, filename)
96
+ end
97
+
98
+ def shard_file_path
99
+ path = file_path(shard.username, shard.name, shard.version, '*shard.rb')
100
+ Dir[ path ].first
101
+ end
102
+
103
+ def shard_test_paths
104
+ test_path = file_path(shard.username, shard.name, shard.version, '*_test.rb')
105
+ test_files = Dir[ test_path ]
106
+
107
+ spec_path = file_path(shard.username, shard.name, shard.version, '*_spec.rb')
108
+ spec_files = Dir[ spec_path ]
109
+
110
+ test_files + spec_files
111
+ end
112
+
113
+ end
114
+
115
+ end
@@ -0,0 +1,85 @@
1
+ class Shard
2
+
3
+ class Saver
4
+
5
+ ################
6
+ # #
7
+ # Declarations #
8
+ # #
9
+ ################
10
+
11
+ include ShardDirectory
12
+
13
+ attr_reader :shard, :gist, :full_gist, :options
14
+
15
+ ###############
16
+ # #
17
+ # Constructor #
18
+ # #
19
+ ###############
20
+
21
+ def initialize(shard, options = {})
22
+ @shard = shard
23
+ @options = options
24
+ end
25
+
26
+ #################
27
+ # #
28
+ # Class Methods #
29
+ # #
30
+ #################
31
+
32
+ def self.save(shard, options = {})
33
+ new(shard, options).save!
34
+ end
35
+
36
+ ####################
37
+ # #
38
+ # Instance Methods #
39
+ # #
40
+ ####################
41
+
42
+ def save!
43
+ create_shard_dir(shard.username, shard.name, shard.version)
44
+ fetch_shard_contents
45
+
46
+ gist.all_files.each do |file|
47
+ write_file(file)
48
+ end
49
+
50
+ if options[:verbose]
51
+ puts "VERSION #{ version(8) }..."
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def fetch_shard_contents
58
+ lister = Shard::Lister.new(shard.username)
59
+ @gist = lister.shards[shard.name]
60
+ @full_gist = Octokit.gist gist.id
61
+ end
62
+
63
+ def file_contents(filename)
64
+ full_gist.files[filename].content
65
+ end
66
+
67
+ def write_file(file)
68
+ path = file_path(shard.username, shard.name, shard.version, file.filename)
69
+ contents = file_contents(file.filename)
70
+
71
+ if options[:verbose]
72
+ puts "Saving #{ file.filename }"
73
+ end
74
+
75
+ File.write path, contents
76
+ end
77
+
78
+ def version(length)
79
+ full_version = full_gist.history.first.version
80
+ full_version[0...length]
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,45 @@
1
+ class Shard
2
+
3
+ module ShardDirectory
4
+
5
+ ##################
6
+ # #
7
+ # Module Methods #
8
+ # #
9
+ ##################
10
+
11
+ def create_root
12
+ unless Dir.exists?(path)
13
+ Dir.mkdir(path)
14
+ end
15
+ end
16
+
17
+ def create_shard_dir(username, shard, version)
18
+ dir = directory(username, shard, version)
19
+
20
+ unless shard_dir_exists?(username, shard, version)
21
+ FileUtils.mkpath(dir)
22
+ end
23
+ end
24
+
25
+ def shard_dir_exists?(username, shard, version)
26
+ dir = directory(username, shard, version)
27
+
28
+ Dir.exists?(dir)
29
+ end
30
+
31
+ def directory(username, shard, version)
32
+ File.join(path, username, shard, version)
33
+ end
34
+
35
+ def path
36
+ File.join(Dir.home, '.shard')
37
+ end
38
+
39
+ def file_path(username, shard, version, filename)
40
+ File.join( directory(username, shard, version), filename )
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,29 @@
1
+ class Shard::ShardRecord
2
+
3
+ ################
4
+ # #
5
+ # Declarations #
6
+ # #
7
+ ################
8
+
9
+ attr_reader :username, :name, :version
10
+
11
+ ###############
12
+ # #
13
+ # Constructor #
14
+ # #
15
+ ###############
16
+
17
+ def initialize(username, name, version = "HEAD")
18
+ @username = username
19
+ @name = name
20
+ @version = version
21
+ end
22
+
23
+ ####################
24
+ # #
25
+ # Instance Methods #
26
+ # #
27
+ ####################
28
+
29
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mark Josef
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: &70120253751200 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70120253751200
25
+ description: ! 'Shard is a light-weight code loading-and-running-and-sharing tool,
26
+ built on top of http://gist.github.com.
27
+
28
+
29
+ You can load the shard''s code using a Kernel#shard method, and can load, run, and
30
+ test a shard directly from the command line.
31
+
32
+ '
33
+ email: mcphage@gmail.com
34
+ executables:
35
+ - shard
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - lib/shard.rb
40
+ - lib/shard/cli.rb
41
+ - lib/shard/gist.rb
42
+ - lib/shard/kernel.rb
43
+ - lib/shard/lister.rb
44
+ - lib/shard/loader.rb
45
+ - lib/shard/saver.rb
46
+ - lib/shard/shard_directory.rb
47
+ - lib/shard/shard_record.rb
48
+ - bin/shard
49
+ homepage: https://github.com/mark/shard
50
+ licenses:
51
+ - MIT
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.9.3
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.10
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Very lightweight ruby package manager built on gist.
74
+ test_files: []