utilikilt 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/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ vendor/bundle/
3
+ pkg/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Get Going!
2
+ install the dependencies you need with:
3
+ ```
4
+ bundle install --path vendor/bundle --binstubs
5
+ ```
6
+
7
+ Install pow, your friendly static server)
8
+ ```
9
+ curl get.pow.cx | sh
10
+ ```
11
+
12
+ Use powder to ask pow to serve up the files in the *public* subdirectory:
13
+ ```
14
+ bin/powder link
15
+ ```
16
+
17
+ Fire up **Guard** which will magically generate HTML and CSS whenever you change your HAML and SASS:
18
+ ```
19
+ bin/guard
20
+ ```
21
+
22
+ Open up your content in a web browser:
23
+ ```
24
+ bin/powder open
25
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/uk ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'utilikilt'
4
+ require 'utilikilt/cli'
5
+
6
+ Utilikilt::CLI.start
@@ -0,0 +1,56 @@
1
+ # tricks rubygems into believeing that the extension compiled and worked out.
2
+ # This function lifted straight out of the zerg_support gem https://rubygems.org/gems/zerg_support
3
+ def emulate_extension_install
4
+ extension_name = "utilikilt"
5
+ File.open('Makefile', 'w') { |f| f.write "all:\n\ninstall:\n\n" }
6
+ File.open('make', 'w') do |f|
7
+ f.write '#!/bin/sh'
8
+ f.chmod f.stat.mode | 0111
9
+ end
10
+ File.open(extension_name + '.so', 'w') {}
11
+ File.open(extension_name + '.dll', 'w') {}
12
+ File.open('nmake.bat', 'w') { |f| }
13
+ end
14
+
15
+
16
+ def executable?( exe )
17
+ system "command -v #{exe} >/dev/null 2>&1"
18
+ end
19
+
20
+ def check_prereqs_and_advise
21
+ return nil if executable? 'node'
22
+
23
+ generic_advice = "\nUtilikilt uses node.js to serve up your files, but you don't appear to have it installed.\n"
24
+ if executable? 'brew'
25
+ return [generic_advice,"However it does look like you have homebrew available.","To install node simply run `brew install node`, then try to install the utilikilt gem again."].join("\n")
26
+ elsif `uname` =~ /Darwin/
27
+ return [generic_advice,%Q{The easiest way to install node is using a package manager called homebrew. You can get started with homebrew by visting http://bit.ly/getbrew, or just run the following from the command line:},%Q{/usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"},"",%Q{Once homebrew is installed you can install node.js with a simple `brew install node` from the command line. After that, try installing the utilikilt gem again.}].join("\n")
28
+ else
29
+ return [generic_advice,"Please install node.js and then try to install the utilikilt gem again."].join("\n")
30
+ end
31
+ end
32
+
33
+
34
+ def install_node_package
35
+ puts 'installing utilikilt npm package...'
36
+ system *%w{npm install utilikilt}, {:chdir => "../../"}
37
+ puts '...utilikilt npm package installed'
38
+ end
39
+
40
+ # This is a big ol' hack to run a pre-install script for this gem, by pretending to compile a native extension. See http://blog.costan.us/2008/11/post-install-post-update-scripts-for.html for details.
41
+
42
+ emulate_extension_install()
43
+
44
+ prereq_errors = check_prereqs_and_advise()
45
+ if prereq_errors
46
+ puts "\n\n\n"
47
+ puts "*"*80
48
+ puts prereq_errors
49
+ puts "*"*80
50
+ puts "\n\n\n"
51
+ exit 1
52
+ end
53
+
54
+ install_node_package()
55
+
56
+
data/lib/utilikilt.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "utilikilt/version"
2
+
3
+ module Utilikilt
4
+ DEFAULT_INPUT_DIR_NAME = 'source'
5
+ DEFAULT_OUTPUT_DIR_NAME = 'public'
6
+ end
@@ -0,0 +1,86 @@
1
+ require 'thor'
2
+ require 'utilikilt/scanner'
3
+ require 'utilikilt/watcher'
4
+ require 'utilikilt/node_proxy'
5
+ require 'utilikilt/workspace'
6
+
7
+ module Utilikilt
8
+ class CLI < Thor
9
+
10
+ desc "watch", "watch for changes to source files and automatically create corresponding public files"
11
+ method_option :input_dir, :aliases => '-i', :type => 'string'
12
+ method_option :output_dir, :aliases => '-o', :type => 'string'
13
+ def watch( project_dir = nil )
14
+ opts = normalize_options(project_dir,options)
15
+ start_watcher(opts)
16
+ end
17
+
18
+ desc "build", "rebuild all input files"
19
+ method_option :input_dir, :aliases => '-i', :type => 'string'
20
+ method_option :output_dir, :aliases => '-o', :type => 'string'
21
+ def build( project_dir = nil )
22
+ opts = normalize_options(project_dir,options)
23
+ run_one_off_scan( opts )
24
+ end
25
+
26
+ desc "serve", "Start a little web server host whatever is in your public directory, with live refresh"
27
+ def serve( project_dir = nil )
28
+ opts = normalize_options(project_dir,options)
29
+ start_serve( opts )
30
+ end
31
+
32
+ desc "up", "live-compile the contents of source, and serve it up to your browser with live-refresh"
33
+ method_option :input_dir, :aliases => '-i', :type => 'string'
34
+ method_option :output_dir, :aliases => '-o', :type => 'string'
35
+ def up( project_dir=nil )
36
+ watch_thread = Thread.new{ watch(project_dir) }
37
+ serve_thread = Thread.new{ serve(project_dir) }
38
+
39
+ serve_thread.join # joining on serve rather than watch is arbitrary
40
+ end
41
+
42
+ desc "workspace", "create a new workspace directory"
43
+ def workspace( workspace_name )
44
+ workspace = Workspace.new( Dir.getwd, workspace_name )
45
+ problems = workspace.create_or_report_problems
46
+ if problems
47
+ puts
48
+ puts problems
49
+ exit 1
50
+ end
51
+ end
52
+ private
53
+
54
+ def run_one_off_scan(options)
55
+ scanner = Scanner.new( options )
56
+ scanner.scan
57
+ end
58
+
59
+ def start_watcher(options)
60
+ scanner = Scanner.new( options )
61
+ scanner.scan # do an initial build
62
+ Watcher.watch options['input_dir'] do
63
+ scanner.scan
64
+ end
65
+ end
66
+
67
+ def start_serve(options)
68
+ server = Utilikilt::NodeProxy.new( options['output_dir'] )
69
+ server.launch_server
70
+ end
71
+
72
+
73
+ def normalize_options( project_dir, opts )
74
+ normalized = {}
75
+ %w{input_dir output_dir}.each do |k|
76
+ normalized[k] = File.expand_path( opts[k] ) if opts.has_key?(k)
77
+ end
78
+ normalized['project_dir'] = File.expand_path( project_dir || Dir.getwd )
79
+
80
+ normalized['input_dir'] ||= File.join( normalized['project_dir'], Utilikilt::DEFAULT_INPUT_DIR_NAME )
81
+ normalized['output_dir'] ||= File.join( normalized['project_dir'], Utilikilt::DEFAULT_OUTPUT_DIR_NAME )
82
+
83
+ normalized
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,8 @@
1
+ module Utilikilt
2
+ module Loggable
3
+ def debug
4
+ puts yield if $DEBUG
5
+ end
6
+ end
7
+ end
8
+
@@ -0,0 +1,13 @@
1
+ module Utilikilt
2
+ class NodeProxy
3
+ NODE_DIR = File.join( File.dirname(__FILE__), '..','..', 'node_modules', 'utilikilt' )
4
+
5
+ def initialize( serve_dir )
6
+ @serve_dir = File.expand_path(serve_dir)
7
+ end
8
+
9
+ def launch_server
10
+ system 'node_modules/.bin/coffee', 'lib/uk.coffee', @serve_dir, {:chdir => NODE_DIR}
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,76 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
4
+ require 'utilikilt/loggable'
5
+
6
+ module Utilikilt
7
+ class Scanner
8
+ include Loggable
9
+
10
+ def initialize( opts )
11
+ @input_base = Pathname.new( opts['input_dir'] ).expand_path
12
+ @output_base = Pathname.new( opts['output_dir'] ).expand_path
13
+ @files_processed = 0
14
+ end
15
+
16
+ INPUT_TO_OUTPUT_EXT_MAP = {
17
+ 'md' => 'html',
18
+ 'markdown' => 'html',
19
+ 'haml' => 'html',
20
+ 'sass' => 'css',
21
+ 'scss' => 'css',
22
+ 'coffee' => 'js'
23
+ }
24
+
25
+ TILT_OPTIONS = {:cache => false}
26
+
27
+ def scan
28
+ @files_processed = 0
29
+ input_file_glob = '*.{'+INPUT_TO_OUTPUT_EXT_MAP.keys.join(',')+'}'
30
+ Pathname.glob(File.join( @input_base, "**", input_file_glob )).each do |input|
31
+ debug{"checking #{input}"}
32
+ output = output_for_input(input)
33
+ unless FileUtils.uptodate?( output, [input] )
34
+ filter( input, output )
35
+ end
36
+ end
37
+
38
+ log_files_processed
39
+ end
40
+
41
+ private
42
+
43
+ def log_files_processed
44
+ puts "#{@files_processed} files processed"
45
+ end
46
+
47
+ def filter input, output
48
+ require 'tilt'
49
+
50
+ output.dirname.mkpath
51
+
52
+ print "#{input} => #{output} ... "
53
+ template = Tilt.new( input.to_s, 1, TILT_OPTIONS )
54
+
55
+ output.dirname.mkpath
56
+ output.open('w') do |out_file|
57
+ out_file.write( template.render )
58
+ end
59
+ puts " done"
60
+
61
+ @files_processed += 1
62
+ end
63
+
64
+ def output_for_input input
65
+ relative = input.relative_path_from @input_base
66
+
67
+ # this is a bit fiddly because Pathname defines exts as including the leading dot while our map does not include it
68
+ output_ext = '.'+INPUT_TO_OUTPUT_EXT_MAP[input.extname[1..-1]]
69
+
70
+ raise ArgumentError, "unrecognized input file extension for #{input}" if output_ext.nil?
71
+
72
+ @output_base.join( relative.sub_ext(output_ext) )
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,3 @@
1
+ module Utilikilt
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,20 @@
1
+ require 'rb-fsevent'
2
+
3
+ module Utilikilt
4
+ class Watcher
5
+ def self.watch( dir_to_watch, &handler )
6
+ Watcher.new( dir_to_watch, handler ).start_watching
7
+ end
8
+
9
+ def initialize( dir_to_watch, on_change_handler )
10
+ @fsevent = FSEvent.new
11
+ @fsevent.watch dir_to_watch do |directories|
12
+ on_change_handler.call( directories )
13
+ end
14
+ end
15
+
16
+ def start_watching
17
+ @fsevent.run
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ require 'pathname'
2
+
3
+ module Utilikilt
4
+ class Workspace
5
+ def initialize base_dir, workspace_name
6
+ @workspace_name = workspace_name
7
+ @workspace_dir = Pathname.new(base_dir).join(@workspace_name).expand_path
8
+ end
9
+
10
+ def create_or_report_problems
11
+ if @workspace_dir.directory?
12
+ "There is already a directory called #{@workspace_name}. I don't want to mess with it. Please give me a new workspace name or delete that directory."
13
+ elsif @workspace_dir.exist?
14
+ "There is already a file called #{@workspace_name}, and I can't create a directory with the same name. Please give me a new workspace name or delete that file."
15
+ else
16
+ @workspace_dir.mkdir
17
+ @workspace_dir.join(Utilikilt::DEFAULT_INPUT_DIR_NAME).mkdir
18
+ @workspace_dir.join(Utilikilt::DEFAULT_OUTPUT_DIR_NAME).mkdir
19
+ @workspace_dir.join(Utilikilt::DEFAULT_INPUT_DIR_NAME, 'index.haml').open('w') do |f|
20
+ f.write CANNED_INDEX_HAML
21
+ end
22
+ nil
23
+ end
24
+ end
25
+
26
+
27
+ CANNED_INDEX_HAML = <<EOS
28
+ !!! 5
29
+ %html
30
+ %head
31
+ %title
32
+ Hello, world
33
+ %body
34
+ %p
35
+ Welcome to your new workspace. Edit #{Utilikilt::DEFAULT_INPUT_DIR_NAME}/index.haml to get started.
36
+ EOS
37
+ end
38
+ end
data/utilikilt.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "utilikilt/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "utilikilt"
7
+ s.version = Utilikilt::VERSION
8
+ s.authors = ["Pete Hodgson"]
9
+ s.email = ["github@thepete.net"]
10
+ s.homepage = "http://github.com/moredip/utilikilt"
11
+ s.summary = %q{Seriously simple prototyping}
12
+ s.description = %q{Prototype your UI development using tools like HAML and SASS with your changes showing up in the browser every time you save.}
13
+
14
+ s.rubyforge_project = "utilikilt"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.extensions << 'ext/check_for_node/extconf.rb'
22
+
23
+ s.add_runtime_dependency "thor"
24
+ s.add_runtime_dependency "rb-fsevent"
25
+ s.add_runtime_dependency "haml"
26
+ s.add_runtime_dependency "sass"
27
+ s.add_runtime_dependency "redcarpet"
28
+ s.add_runtime_dependency "tilt"
29
+ s.add_runtime_dependency "powder"
30
+ s.add_runtime_dependency "showoff-io"
31
+
32
+ # specify any dependencies here; for example:
33
+ # s.add_development_dependency "rspec"
34
+ # s.add_runtime_dependency "rest-client"
35
+ end
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/utilikilt/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in utilikilt.gemspec
4
+ gemspec
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: utilikilt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pete Hodgson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-04 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: &70285499891220 !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: *70285499891220
25
+ - !ruby/object:Gem::Dependency
26
+ name: rb-fsevent
27
+ requirement: &70285499890800 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70285499890800
36
+ - !ruby/object:Gem::Dependency
37
+ name: haml
38
+ requirement: &70285499890380 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70285499890380
47
+ - !ruby/object:Gem::Dependency
48
+ name: sass
49
+ requirement: &70285499889780 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70285499889780
58
+ - !ruby/object:Gem::Dependency
59
+ name: redcarpet
60
+ requirement: &70285499889160 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70285499889160
69
+ - !ruby/object:Gem::Dependency
70
+ name: tilt
71
+ requirement: &70285499888560 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *70285499888560
80
+ - !ruby/object:Gem::Dependency
81
+ name: powder
82
+ requirement: &70285499887880 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :runtime
89
+ prerelease: false
90
+ version_requirements: *70285499887880
91
+ - !ruby/object:Gem::Dependency
92
+ name: showoff-io
93
+ requirement: &70285499887200 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: *70285499887200
102
+ description: Prototype your UI development using tools like HAML and SASS with your
103
+ changes showing up in the browser every time you save.
104
+ email:
105
+ - github@thepete.net
106
+ executables:
107
+ - uk
108
+ extensions:
109
+ - ext/check_for_node/extconf.rb
110
+ extra_rdoc_files: []
111
+ files:
112
+ - .gitignore
113
+ - Gemfile
114
+ - README.md
115
+ - Rakefile
116
+ - bin/uk
117
+ - ext/check_for_node/extconf.rb
118
+ - lib/utilikilt.rb
119
+ - lib/utilikilt/cli.rb
120
+ - lib/utilikilt/loggable.rb
121
+ - lib/utilikilt/node_proxy.rb
122
+ - lib/utilikilt/scanner.rb
123
+ - lib/utilikilt/version.rb
124
+ - lib/utilikilt/watcher.rb
125
+ - lib/utilikilt/workspace.rb
126
+ - utilikilt.gemspec
127
+ - utilikilt/.gitignore
128
+ - utilikilt/Gemfile
129
+ homepage: http://github.com/moredip/utilikilt
130
+ licenses: []
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ! '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project: utilikilt
149
+ rubygems_version: 1.8.10
150
+ signing_key:
151
+ specification_version: 3
152
+ summary: Seriously simple prototyping
153
+ test_files: []