potatochop 0.0.1 → 0.0.2

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/.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