slicecraft 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/README.md +25 -0
- data/bin/slicecraft +58 -0
- data/config.yml +7 -0
- data/lib/slicecraft.rb +117 -0
- data/spec/lib/slicecraft_spec.rb +161 -0
- metadata +130 -0
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# SliceCraft
|
2
|
+
|
3
|
+
SliceCraft commands for generating, previewing and delivering a project.
|
4
|
+
|
5
|
+
Download the latest gemfile in the [downloads](https://github.com/80beans/slicecraft/downloads) section, then run `gem install /.[gemfile name]` in your console to install the gem.
|
6
|
+
|
7
|
+
## Commands
|
8
|
+
|
9
|
+
````
|
10
|
+
slicecraft new [projectname]
|
11
|
+
````
|
12
|
+
|
13
|
+
Creates a new project folder with middleman template in your current folder.
|
14
|
+
|
15
|
+
````
|
16
|
+
slicecraft preview
|
17
|
+
````
|
18
|
+
|
19
|
+
Run this in your project folder to create a preview and upload it to the server.
|
20
|
+
|
21
|
+
````
|
22
|
+
slicecraft deliver
|
23
|
+
````
|
24
|
+
|
25
|
+
Run this in your project folder to deliver the project, a zip of the build and source is uploaded to the server.
|
data/bin/slicecraft
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'commander/import'
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/slicecraft')
|
6
|
+
|
7
|
+
program :version, '0.0.1'
|
8
|
+
program :description, "The 80beans SliceCraft gem. Run 'slicecraft new [projectname]' to create a new SliceCraft project."
|
9
|
+
|
10
|
+
command :new do |c|
|
11
|
+
c.syntax = 'slicecraft new [projectname]'
|
12
|
+
c.summary = 'Initialize a new project.'
|
13
|
+
c.description = 'Enter a project name to create a folder with that name and generate the 80beans middleman template.'
|
14
|
+
c.action do |args, options|
|
15
|
+
if args.first
|
16
|
+
c.when_called Slicecraft::Project.create(:directory => args.first)
|
17
|
+
say "Project '#{args.first}' successfully created, have fun slicing!"
|
18
|
+
else
|
19
|
+
say "Error: Enter a projectname (slicecraft new [projectname])"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
command :preview do |c|
|
25
|
+
c.syntax = 'slicecraft preview'
|
26
|
+
c.summary = 'Ships the project to the preview server'
|
27
|
+
c.description = 'When in a folder containing a middleman project run this to sync a preview to the server.'
|
28
|
+
c.option '--url', String, 'Instead of building the preview this only shows the preview url'
|
29
|
+
c.action do |args, options|
|
30
|
+
if options.url
|
31
|
+
say "Preview url: #{Slicecraft::Preview.new(:directory => Dir.pwd).result_url}"
|
32
|
+
else
|
33
|
+
c.when_called Slicecraft::Project.build
|
34
|
+
preview = Slicecraft::Preview.new(:directory => Dir.pwd)
|
35
|
+
preview.process
|
36
|
+
say "Shipped to: #{preview.result_url}"
|
37
|
+
say "Pages:"
|
38
|
+
preview.result_urls.each{ |r| say r }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
command :deliver do |c|
|
44
|
+
c.syntax = 'slicecraft deliver'
|
45
|
+
c.summary = 'Delivers a project zip'
|
46
|
+
c.description = 'When in a folder containing a middleman project run this to deliver a project zip containing the build and source to the server.'
|
47
|
+
c.option '--url', String, 'Instead of delivering the zip this only shows the zip url'
|
48
|
+
c.action do |args, options|
|
49
|
+
if options.url
|
50
|
+
say "Zip url: #{Slicecraft::Delivery.new(:directory => Dir.pwd).result_url}"
|
51
|
+
else
|
52
|
+
c.when_called Slicecraft::Project.build
|
53
|
+
delivery = Slicecraft::Delivery.new(:directory => Dir.pwd)
|
54
|
+
delivery.process
|
55
|
+
say "Zipped to: #{delivery.result_url}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/config.yml
ADDED
data/lib/slicecraft.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'net/scp'
|
2
|
+
require 'yaml'
|
3
|
+
require 'zip/zip'
|
4
|
+
|
5
|
+
module Slicecraft
|
6
|
+
|
7
|
+
class Project
|
8
|
+
|
9
|
+
def self.create(options)
|
10
|
+
@location = options[:directory]
|
11
|
+
|
12
|
+
system "git clone #{self.template_repo} #{@location}"
|
13
|
+
FileUtils.rm_rf "#{@location}/.git"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.build
|
17
|
+
result = system "middleman build"
|
18
|
+
raise 'Middleman could not build' unless result
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.template_repo
|
22
|
+
YAML.load_file(File.expand_path(File.join(File.dirname(__FILE__), '../config.yml')))['template_repo']
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class Syncer
|
28
|
+
attr_accessor :path
|
29
|
+
attr_accessor :settings
|
30
|
+
|
31
|
+
def initialize(options)
|
32
|
+
@path = options[:directory]
|
33
|
+
end
|
34
|
+
|
35
|
+
def hashed_path
|
36
|
+
"#{project_name}_#{Digest::SHA1.hexdigest('12RThh' + project_name)}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def result_url
|
40
|
+
"#{settings['result_url']}/#{hashed_path}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def project_name
|
44
|
+
@path.split('/').last
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_path
|
48
|
+
"#{@path}/build/"
|
49
|
+
end
|
50
|
+
|
51
|
+
def settings
|
52
|
+
@settings ||= YAML.load_file(File.expand_path(File.join(File.dirname(__FILE__), '../config.yml')))['server']
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
class Preview < Syncer
|
59
|
+
|
60
|
+
def result_urls
|
61
|
+
results = Dir.entries(build_path).select{ |file| file.end_with?('.html') }.map{ |r| "#{result_url}/#{r}" }
|
62
|
+
FileUtils.rm_rf build_path if File.exists? build_path
|
63
|
+
results
|
64
|
+
end
|
65
|
+
|
66
|
+
def process
|
67
|
+
system "rsync -ave ssh #{build_path} #{settings['user']}@#{settings['url']}:#{"#{settings['preview_path']}#{hashed_path}"}"
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
class Delivery < Syncer
|
73
|
+
|
74
|
+
def process
|
75
|
+
zip
|
76
|
+
sync
|
77
|
+
end
|
78
|
+
|
79
|
+
def zip
|
80
|
+
if File.exists?('zip/source.zip')
|
81
|
+
File.delete('zip/source.zip')
|
82
|
+
else
|
83
|
+
FileUtils.mkdir('zip') unless File.exists?('zip')
|
84
|
+
end
|
85
|
+
Zip::ZipFile.open(File.join(zip_path, 'source.zip'), Zip::ZipFile::CREATE) do |zipfile|
|
86
|
+
add_folder_to_zipfile(zipfile, 'source')
|
87
|
+
add_folder_to_zipfile(zipfile, 'build')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_folder_to_zipfile(zipfile, folder)
|
92
|
+
Dir["#{path}/#{folder}/**/**"].each do |file|
|
93
|
+
zipfile.add(file.sub(path+'/',''),file)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def zip_path
|
98
|
+
"#{@path}/zip/"
|
99
|
+
end
|
100
|
+
|
101
|
+
def result_url
|
102
|
+
super + '/source.zip'
|
103
|
+
end
|
104
|
+
|
105
|
+
def hashed_path
|
106
|
+
super + '/zip'
|
107
|
+
end
|
108
|
+
|
109
|
+
def sync
|
110
|
+
system "rsync -ave ssh #{zip_path} #{settings['user']}@#{settings['url']}:#{"#{settings['preview_path']}#{hashed_path}"}"
|
111
|
+
FileUtils.rm_rf zip_path if File.exists? zip_path
|
112
|
+
FileUtils.rm_rf build_path if File.exists? build_path
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../lib/slicecraft')
|
3
|
+
|
4
|
+
describe Slicecraft::Project do
|
5
|
+
|
6
|
+
context ".create" do
|
7
|
+
|
8
|
+
it "should create a project" do
|
9
|
+
Slicecraft::Project.should_receive(:system).with("git clone git@github.com:80beans/slicecraft_template.git /slice_this")
|
10
|
+
FileUtils.should_receive(:rm_rf).with("/slice_this/.git")
|
11
|
+
|
12
|
+
Slicecraft::Project.create(:directory => "/slice_this")
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
context ".build" do
|
18
|
+
|
19
|
+
it "should build a project" do
|
20
|
+
Slicecraft::Project.should_receive(:system).with("middleman build").and_return(true)
|
21
|
+
|
22
|
+
Slicecraft::Project.build
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Slicecraft::Syncer do
|
30
|
+
|
31
|
+
let(:syncer) { Slicecraft::Syncer.new(:directory => '/slice_this') }
|
32
|
+
|
33
|
+
context "#settings" do
|
34
|
+
|
35
|
+
it "should have settings" do
|
36
|
+
syncer.settings.should == {
|
37
|
+
"url" => "slicecraft.nl",
|
38
|
+
"user" => "slicecraft",
|
39
|
+
"preview_path" => "/home/slicecraft/previews/",
|
40
|
+
"result_url" => "http://preview.slicecraft.nl"
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
context "#project_name" do
|
47
|
+
|
48
|
+
it "project_name should be current folder name" do
|
49
|
+
syncer.project_name.should == 'slice_this'
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with longer path" do
|
53
|
+
|
54
|
+
let(:syncer) { Slicecraft::Syncer.new(:directory => '/this/path/is/long/slice_this') }
|
55
|
+
|
56
|
+
it "project_name should be current folder name" do
|
57
|
+
syncer.project_name.should == 'slice_this'
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
context "#hashed_path" do
|
65
|
+
|
66
|
+
it "should return a path with an id hash in it" do
|
67
|
+
syncer.hashed_path.should == 'slice_this_240999fa70d7f05b158bd1170ff932ac0503bea2'
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
context "#result_url" do
|
73
|
+
|
74
|
+
it "should return the correct result_url" do
|
75
|
+
syncer.result_url.should == "http://preview.slicecraft.nl/slice_this_240999fa70d7f05b158bd1170ff932ac0503bea2"
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
describe Slicecraft::Preview do
|
83
|
+
|
84
|
+
let(:preview) { Slicecraft::Preview.new(:directory => '/slice_this') }
|
85
|
+
|
86
|
+
context "#build_path" do
|
87
|
+
|
88
|
+
it "should return the build path" do
|
89
|
+
preview.build_path.should == '/slice_this/build/'
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
context "#process" do
|
95
|
+
|
96
|
+
it "should process the preview" do
|
97
|
+
preview.should_receive(:system).
|
98
|
+
with("rsync -ave ssh /slice_this/build/ slicecraft@slicecraft.nl:/home/slicecraft/previews/slice_this_240999fa70d7f05b158bd1170ff932ac0503bea2")
|
99
|
+
|
100
|
+
preview.process
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
describe Slicecraft::Delivery do
|
108
|
+
|
109
|
+
let(:delivery) { Slicecraft::Delivery.new(:directory => '/slice_this') }
|
110
|
+
|
111
|
+
context "#zip_path" do
|
112
|
+
|
113
|
+
it "should return the zip path" do
|
114
|
+
delivery.zip_path.should == '/slice_this/zip/'
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
context "#sync" do
|
120
|
+
|
121
|
+
it "should sync the zip" do
|
122
|
+
delivery.should_receive(:system).
|
123
|
+
with("rsync -ave ssh /slice_this/zip/ slicecraft@slicecraft.nl:/home/slicecraft/previews/slice_this_240999fa70d7f05b158bd1170ff932ac0503bea2/zip")
|
124
|
+
|
125
|
+
delivery.sync
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
context "#zip" do
|
131
|
+
|
132
|
+
it "should create zip folder and file" do
|
133
|
+
Zip::ZipFile.should_receive('open')
|
134
|
+
FileUtils.should_receive('mkdir').with('zip')
|
135
|
+
|
136
|
+
delivery.zip
|
137
|
+
end
|
138
|
+
|
139
|
+
context "with existing zip file" do
|
140
|
+
|
141
|
+
before do
|
142
|
+
FileUtils.mkdir('zip')
|
143
|
+
FileUtils.touch('zip/source.zip')
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should delete the zip folder and file when a zip file exists" do
|
147
|
+
Zip::ZipFile.should_receive('open')
|
148
|
+
File.should_receive('delete').with('zip/source.zip')
|
149
|
+
|
150
|
+
delivery.zip
|
151
|
+
end
|
152
|
+
|
153
|
+
after do
|
154
|
+
FileUtils.rm_rf('zip')
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slicecraft
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ron Cadier
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: commander
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 4.1.2
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 4.1.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: middleman
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.0.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.0.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rubyzip
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.9.9
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.9
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: net-scp
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.0.4
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.0.4
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: A commandline tool specific for the SliceCraft project flow
|
95
|
+
email: ron@80beans.com
|
96
|
+
executables:
|
97
|
+
- slicecraft
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- lib/slicecraft.rb
|
102
|
+
- spec/lib/slicecraft_spec.rb
|
103
|
+
- bin/slicecraft
|
104
|
+
- README.md
|
105
|
+
- config.yml
|
106
|
+
homepage: http://80beans.com
|
107
|
+
licenses: []
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ! '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 1.8.19
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: Internal tool for SliceCraft
|
130
|
+
test_files: []
|