potatochop 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .DS_Store
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "2.1.0"
4
+ - "1.9.3"
5
+ script: bundle exec rspec spec
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ## 0.0.2
2
+ * [Add command line arguments so Potatochop can be configured at start time](https://github.com/VersaHQ/potatochop/pull/2/commits)
3
+ * [Add an interface to Github so files can be served from a GH repo](https://github.com/VersaHQ/potatochop/commit/611b448973f53f6f38d889683e0e879d45b3ff2e)
4
+ * Loads of file re-organization
5
+
6
+ ## 0.0.1
7
+ * Initial release
data/README.md CHANGED
@@ -1,20 +1,14 @@
1
1
  # Potatochop
2
+ _A simple server for HAML & SASS mock ups_
2
3
 
3
- Impetus: [Because F$%k Photoshop](http://2012.jsconf.eu/speaker/2012/08/29/because-f-k-photoshop.html)
4
+ [![Build Status](https://travis-ci.org/VersaHQ/potatochop.svg?branch=master)](https://travis-ci.org/VersaHQ/potatochop)
5
+ [![Gem Version](https://badge.fury.io/rb/potatochop.svg)](http://badge.fury.io/rb/potatochop)
4
6
 
5
- ## Installation
6
-
7
- Install Potatochop as a gem in the usual ways:
8
-
9
- Add this line to your application's Gemfile:
10
-
11
- gem 'potatochop'
7
+ [VersaHQ blog post on Potatochop](http://blog.versahq.com/post/82290792427/potatochop)
12
8
 
13
- And then execute:
14
-
15
- $ bundle
9
+ ## Installation
16
10
 
17
- Or install it yourself as:
11
+ Install Potatochop as a gem in the usual way:
18
12
 
19
13
  $ gem install potatochop
20
14
 
@@ -26,17 +20,62 @@ To use Potatochop, you also need a folder where you keep your mock ups. Ideally
26
20
  Once the Potatochop gem is installed, cd into your comps directory and run `potatochop`.
27
21
 
28
22
  ```
29
- $ cd comps_repo
23
+ $ cd ~/mock_ups # or wherever you keep your mock_ups
30
24
  $ potatochop
31
25
  ```
26
+ or pass in the path to your mock ups folder with the `--mockups` flag
32
27
 
33
- This will start up the Potatochop server on port 4567. By default, Potatochop will serve files in the same heirarchy as the mock ups folder.
28
+ ```
29
+ $ potatochop --mockups ~/mock_ups
30
+ ```
31
+
32
+ This will start up the Potatochop server on port 4567. By default, Potatochop will serve files in the same hierarchy as the mock ups folder.
33
+
34
+ For example, if you start Potatochop in a folder with a file called `new_homepage.html.haml` you can see it in your browser at `http://localhost:4567/new_homepage.html`
34
35
 
35
36
  ## The Mock Ups folder
36
37
 
37
38
  For lack of a better name, the folder where you store your haml, sass, js, etc. files is called the mock ups folder.
38
39
 
39
- With the default configuration, Potatochop processes and serves any haml or sass file in this folder. Html & javascript files are served directly.
40
+ Out of the box, Potatochop processes and serves any haml or sass file in this folder. Vanilla HTML & JavaScript files are served directly. For example, your mock ups folder could be organized like this:
41
+
42
+ ```
43
+ ~/mock_ups
44
+ about.html
45
+ faq.html.haml
46
+ index.html.haml
47
+ css/
48
+ about.css
49
+ faq.css.scss
50
+ index.css.scss
51
+ js/
52
+ interactions.js
53
+ ```
54
+
55
+ **ProTip:** There is an example mock ups folder in the [spec/fake_mockups](https://github.com/VersaHQ/potatochop/tree/master/spec/fake_mockups) folder (it's used by our automated tests).
56
+
57
+ When you want to include stylesheets in your haml/html pages, refer to them only by their `.css` extension. Using the above folder layout:
58
+
59
+ ```
60
+ # index.html.haml
61
+ %link{ rel: 'stylesheet', href: 'css/index.css' }
62
+ ```
63
+ ## Serving files from a GitHub repo
64
+ Let's say you have a repository on GitHub where you keep your mockups (i.e [https://github.com/mertonium/potatochop_comps](https://github.com/mertonium/potatochop_comps)).
65
+
66
+ You can serve this repo by passing `potatochop` the `--interface` flag along with the repo path:
67
+
68
+ ```
69
+ # Serve files from a public repository on GitHub
70
+ $ potatochop --interface github --repo mertonium/potatochop_comps
71
+ ```
72
+ If your mock ups folder is in a private repo, you must also pass `potatochop` the `--token` flag, along with a [personal access token](https://github.com/settings/tokens/new):
73
+
74
+ ```
75
+ # Serve files from a private repository on GitHub
76
+ $ potatochop --interface github --repo mertonium/potatochop_comps_private --token=GITHUB_ACCESS_TOKEN
77
+ ```
78
+
40
79
 
41
80
  ## Contributing
42
81
 
data/bin/potatochop CHANGED
@@ -2,5 +2,4 @@
2
2
 
3
3
  require 'potatochop'
4
4
 
5
- wd = ARGV[0] || '.'
6
- Potatochop::Web.run!(:working_dir => wd)
5
+ Potatochop.start_up(ARGV)
@@ -0,0 +1,43 @@
1
+ require 'optparse'
2
+
3
+ module Potatochop
4
+ class CliParser
5
+ def self.parse(args)
6
+ options = {
7
+ :interface => nil,
8
+ :interface_class => Potatochop::FileSystemInterface,
9
+ :mockups_path => '.',
10
+ :gh_options => {}
11
+ }
12
+
13
+ opts = OptionParser.new do |opts|
14
+ opts.banner = "Usage: potatochop [options]"
15
+
16
+ opts.separator ""
17
+ opts.separator "Specific options:"
18
+
19
+ opts.on("-i", "--interface [INTERFACE]", "How to find the files to serve (possible options are 'local' and 'github')") do |interface|
20
+ if interface == 'github'
21
+ options[:interface_class] = Potatochop::GithubInterface
22
+ end
23
+ end
24
+
25
+ opts.on("-d", "--mockups [PATH]", "Path to the mockups folder you want to serve") do |wd|
26
+ options[:mockups_path] = wd
27
+ end
28
+
29
+ opts.on("--repo [GITHUB REPOSITORY]", "username/reponame on GitHub") do |repo|
30
+ options[:mockups_path] = repo
31
+ end
32
+
33
+ opts.on("--token [GITHUB ACCESS TOKEN]", "GitHub access token (needed to access private repositories)") do |token|
34
+ options[:gh_options][:access_token] = token
35
+ end
36
+ end
37
+
38
+ opts.parse!(args)
39
+ options[:interface] = options[:interface_class].send(:new, options[:mockups_path], options[:gh_options])
40
+ options
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ module Potatochop
2
+ class FileSystemInterface
3
+ attr_reader :source
4
+
5
+ def initialize(source, options = {})
6
+ @source = source
7
+ end
8
+
9
+ def exists?(file_name)
10
+ file_path = File.join(@source, file_name)
11
+ File.exists? file_path
12
+ end
13
+
14
+ def read(file_name)
15
+ file_path = File.join(@source, file_name)
16
+ File.read(file_path)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ module Potatochop
2
+ class GithubInterface
3
+ attr_reader :source
4
+
5
+ def initialize(repo, gh_options = {})
6
+ @source = repo
7
+ @gh_client = Octokit::Client.new access_token: gh_options[:access_token]
8
+ end
9
+
10
+ def exists?(file_name)
11
+ begin
12
+ @gh_client.contents(@source, path: file_name, accept: 'application/vnd.github.raw')
13
+ true
14
+ rescue Octokit::NotFound
15
+ false
16
+ end
17
+ end
18
+
19
+ def read(file_name)
20
+ @gh_client.contents(@source, path: file_name, accept: 'application/vnd.github.raw')
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module Potatochop
2
+ class Spud
3
+ def initialize(interface)
4
+ @interface = interface
5
+ end
6
+
7
+ def get_file(file_name)
8
+ @interface.exists?(file_name) ? @interface.read(file_name) : nil
9
+ end
10
+
11
+ def get_html(file_name)
12
+ if @interface.exists?("#{file_name}.html") # Static html first
13
+ @interface.read("#{file_name}.html")
14
+ elsif @interface.exists?("#{file_name}.html.haml") # Haml next
15
+ Haml::Engine.new(@interface.read("#{file_name}.html.haml")).render
16
+ end
17
+ end
18
+
19
+ def get_css(file_name)
20
+ if @interface.exists?("#{file_name}.css") # Static css
21
+ @interface.read("#{file_name}.css")
22
+ elsif @interface.exists?("#{file_name}.css.scss") # Sass css
23
+ Sass::Engine.new(@interface.read("#{file_name}.css.scss"), :syntax => :scss).render
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Potatochop
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,36 @@
1
+ require 'sinatra/base'
2
+
3
+ module Potatochop
4
+ class Web < Sinatra::Base
5
+ get '/*.html' do
6
+ return_str = settings.tater.get_html(params[:splat][0])
7
+ return_str.nil? ? 404 : return_str
8
+ end
9
+
10
+ get '/*.css' do
11
+ return_str = settings.tater.get_css(params[:splat][0])
12
+ content_type 'text/css', :charset => 'utf-8'
13
+ return_str.nil? ? 404 : return_str
14
+ end
15
+
16
+ get %r{/(.*).(png|jpg|jpeg|gif)} do
17
+ image_file = settings.tater.get_file("#{params[:captures][0]}.#{params[:captures][1]}")
18
+ if image_file.nil?
19
+ 404
20
+ else
21
+ content_type "image/#{params[:captures].last}"
22
+ image_file
23
+ end
24
+ end
25
+
26
+ get '/*.js' do
27
+ js_file = settings.tater.get_file("#{params[:splat][0]}.js")
28
+ if js_file.nil?
29
+ 404
30
+ else
31
+ content_type "application/javascript", :charset => 'utf-8'
32
+ js_file
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/potatochop.rb CHANGED
@@ -1,52 +1,16 @@
1
1
  require 'potatochop/version'
2
- require 'sinatra/base'
2
+ require 'potatochop/spud'
3
+ require 'potatochop/file_system_interface'
4
+ require 'potatochop/github_interface'
5
+ require 'potatochop/cli_parser'
6
+ require 'potatochop/web'
3
7
  require 'haml'
4
8
  require 'sass'
9
+ require 'octokit'
5
10
 
6
11
  module Potatochop
7
- class Web < Sinatra::Base
8
- get '/*.html' do
9
- file_path = File.join(settings.working_dir, "#{params[:splat][0]}.html")
10
- # Static html first
11
- if File.exists? file_path
12
- send_file file_path
13
- # Haml next
14
- elsif File.exists? file_path + ".haml"
15
- Haml::Engine.new(File.read("#{file_path}.haml")).render
16
- else
17
- 404
18
- end
19
- end
20
-
21
- get '/*.css' do
22
- file_path = File.join(settings.working_dir, "#{params[:splat][0]}.css")
23
- if File.exists? file_path
24
- content_type 'text/css', :charset => 'utf-8'
25
- send_file file_path
26
- elsif File.exists? file_path + '.scss'
27
- content_type 'text/css', :charset => 'utf-8'
28
- Sass::Engine.new(File.read("#{file_path}.scss"), :syntax => :scss).render
29
- else
30
- 404
31
- end
32
- end
33
-
34
- get %r{/(.*).(png|jpg|jpeg|gif)} do
35
- file_path = File.join(settings.working_dir, "#{params[:captures][0]}.#{params[:captures][1]}")
36
- if File.exists? file_path
37
- send_file file_path
38
- else
39
- 404
40
- end
41
- end
42
-
43
- get '/*.js' do
44
- file_path = File.join(settings.working_dir, "#{params[:splat][0]}.js")
45
- if File.exists? file_path
46
- send_file file_path
47
- else
48
- 404
49
- end
50
- end
12
+ def self.start_up(args)
13
+ options = Potatochop::CliParser.parse(args)
14
+ Potatochop::Web.run!(:tater => Potatochop::Spud.new(options[:interface]))
51
15
  end
52
16
  end
data/potatochop.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
20
20
  gem.add_runtime_dependency 'thin'
21
21
  gem.add_runtime_dependency 'haml'
22
22
  gem.add_runtime_dependency 'sass'
23
+ gem.add_runtime_dependency 'octokit'
23
24
  gem.add_development_dependency 'rspec'
24
25
  gem.add_development_dependency 'rake'
25
26
  gem.add_development_dependency 'simplecov'
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,33 @@
1
+ require 'helper'
2
+
3
+ describe Potatochop::FileSystemInterface do
4
+ describe '#new' do
5
+ it 'creates a new FileSystemInterface object with the proper source' do
6
+ fs = Potatochop::FileSystemInterface.new('spec/fake_mockups')
7
+ fs.source.should == "spec/fake_mockups"
8
+ end
9
+ end
10
+ describe '#exists?' do
11
+ it 'returns true if the given file exists' do
12
+ fs = Potatochop::FileSystemInterface.new('spec/fake_mockups')
13
+ fs.exists?('foo.html.haml').should be_true
14
+ end
15
+
16
+ it 'returns false if the given file does not exist' do
17
+ fs = Potatochop::FileSystemInterface.new('spec/fake_mockups')
18
+ fs.exists?('not_real.html').should be_false
19
+ end
20
+ end
21
+
22
+ describe '#read' do
23
+ it 'returns the content of the given files' do
24
+ fs = Potatochop::FileSystemInterface.new('spec/fake_mockups')
25
+ fs.read('foo.html.haml').should == File.read('spec/fake_mockups/foo.html.haml')
26
+ end
27
+
28
+ it 'returns false if the given file does not exist' do
29
+ fs = Potatochop::FileSystemInterface.new('spec/fake_mockups')
30
+ expect { fs.read('not_real.html') }.to raise_error
31
+ end
32
+ end
33
+ end
@@ -6,7 +6,7 @@ end
6
6
 
7
7
  describe 'Potatochop' do
8
8
  describe 'Web' do
9
- app.set('working_dir','/Users/mertonium/Code/potatochop/spec/fake_site')
9
+ app.set(:tater => Potatochop::Spud.new(Potatochop::FileSystemInterface.new('spec/fake_mockups')))
10
10
  include Rack::Test::Methods
11
11
 
12
12
  it 'returns an error when a haml page does not exist' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: potatochop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-03 00:00:00.000000000 Z
12
+ date: 2014-04-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
@@ -75,6 +75,22 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: octokit
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
78
94
  - !ruby/object:Gem::Dependency
79
95
  name: rspec
80
96
  requirement: !ruby/object:Gem::Requirement
@@ -149,20 +165,28 @@ extra_rdoc_files: []
149
165
  files:
150
166
  - .gitignore
151
167
  - .rspec
168
+ - .travis.yml
169
+ - CHANGELOG.md
152
170
  - Gemfile
153
171
  - LICENSE.txt
154
172
  - README.md
155
173
  - Rakefile
156
174
  - bin/potatochop
157
175
  - lib/potatochop.rb
176
+ - lib/potatochop/cli_parser.rb
177
+ - lib/potatochop/file_system_interface.rb
178
+ - lib/potatochop/github_interface.rb
179
+ - lib/potatochop/spud.rb
158
180
  - lib/potatochop/version.rb
181
+ - lib/potatochop/web.rb
159
182
  - potatochop.gemspec
160
- - spec/fake_site/bar.html
161
- - spec/fake_site/css/bar.css
162
- - spec/fake_site/css/foo.css.scss
163
- - spec/fake_site/foo.html.haml
164
- - spec/fake_site/img/potatochop_cs4_box.png
165
- - spec/fake_site/js/bar.js
183
+ - spec/fake_mockups/bar.html
184
+ - spec/fake_mockups/css/bar.css
185
+ - spec/fake_mockups/css/foo.css.scss
186
+ - spec/fake_mockups/foo.html.haml
187
+ - spec/fake_mockups/img/potatochop_cs4_box.png
188
+ - spec/fake_mockups/js/bar.js
189
+ - spec/file_system_interface_spec.rb
166
190
  - spec/helper.rb
167
191
  - spec/potatochop_spec.rb
168
192
  homepage: https://github.com/VersaHQ/potatochop
@@ -191,11 +215,12 @@ specification_version: 3
191
215
  summary: Potatochop is a simple server that compiles and serves up HAML and SASS files.
192
216
  The goal is to reduce friction between designers and devs in a Rails project.
193
217
  test_files:
194
- - spec/fake_site/bar.html
195
- - spec/fake_site/css/bar.css
196
- - spec/fake_site/css/foo.css.scss
197
- - spec/fake_site/foo.html.haml
198
- - spec/fake_site/img/potatochop_cs4_box.png
199
- - spec/fake_site/js/bar.js
218
+ - spec/fake_mockups/bar.html
219
+ - spec/fake_mockups/css/bar.css
220
+ - spec/fake_mockups/css/foo.css.scss
221
+ - spec/fake_mockups/foo.html.haml
222
+ - spec/fake_mockups/img/potatochop_cs4_box.png
223
+ - spec/fake_mockups/js/bar.js
224
+ - spec/file_system_interface_spec.rb
200
225
  - spec/helper.rb
201
226
  - spec/potatochop_spec.rb