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 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: []