shard 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.
- data/bin/shard +9 -0
- data/lib/shard.rb +13 -0
- data/lib/shard/cli.rb +72 -0
- data/lib/shard/gist.rb +78 -0
- data/lib/shard/kernel.rb +7 -0
- data/lib/shard/lister.rb +60 -0
- data/lib/shard/loader.rb +115 -0
- data/lib/shard/saver.rb +85 -0
- data/lib/shard/shard_directory.rb +45 -0
- data/lib/shard/shard_record.rb +29 -0
- metadata +74 -0
data/bin/shard
ADDED
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
|
data/lib/shard/kernel.rb
ADDED
data/lib/shard/lister.rb
ADDED
@@ -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
|
data/lib/shard/loader.rb
ADDED
@@ -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
|
data/lib/shard/saver.rb
ADDED
@@ -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: []
|