├── .gitignore ├── CHANGELOG.md ├── Gemfile ├── LICENSE ├── Rakefile ├── Readme.md ├── bin └── powder ├── lib ├── powder.rb └── powder │ └── version.rb ├── man ├── powder.1 ├── powder.1.html └── powder.1.ronn └── powder.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | tmp 6 | .rvmrc 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### 0.4.0 / 2017-12-10 ### 2 | 3 | * 1 minor change 4 | 5 | * Updates powder to open domains as `.test` instead of `.dev` [commit](https://github.com/powder-rb/powder/commit/6fd673d429a407f67a91738316a641135bbd974b) [discussion](https://github.com/powder-rb/powder/issues/134) 6 | 7 | ### 0.3.3 / 2017-11-01 ### 8 | 9 | * 2 minor changes 10 | 11 | * Allows opening with the `--path` argument [commit](https://github.com/powder-rb/powder/commit/925e312e30a2ef6a00b67012be028cd943ee11f2) 12 | * Adds license info to the gemspec 13 | 14 | ### 0.3.2 / 2017-06-14 ### 15 | 16 | * 4 minor changes 17 | 18 | * Fixes shortcut aliases 19 | ([commit 1](https://github.com/powder-rb/powder/commit/7bcf04319b913c842d5c027d4c538e495c997e71) [commit 2](https://github.com/powder-rb/powder/commit/5df9781cbd848287412be3f9c50bcf7f67781795)) 20 | * Updates Gemfile to use https 21 | * Uses better shebang to get currently active ruby 22 | * Corrects homepage link in gemspec 23 | ([all in this commit](https://github.com/powder-rb/powder/commit/82fbf49d219a8b02ce5c5041a2b0f7af1521c84a)) 24 | 25 | ### 0.3.1 / 2017-06-13 ### 26 | 27 | * 1 minor change 28 | 29 | * Fixes the message `Expected string default value for '--browser'` that was 30 | output when using `powder open` 31 | ([commit](https://github.com/powder-rb/powder/commit/b8bf956f64c2451d8abafc7480f17a15050aa6d3)) 32 | 33 | ### 0.3.0 / 2014-10-29 ### 34 | 35 | * 1 minor change 36 | 37 | * Support for OS X Yosemite. Powder reflects the changes in Pow. 38 | Pow no longer uses the ipfw firewall, which was deprecated in OS X 10.9 39 | and removed in 10.10. 40 | 41 | ### 0.2.2 / 2014-10-22 ### 42 | 43 | * 1 minor change 44 | 45 | * Clean exit from log commands 46 | ([commit](https://github.com/rodreegez/powder/commit/dd99b30352ddb7acb78918c02d42794fabbc6355)) 47 | 48 | ### 0.2.1 / 2014-02-06 ### 49 | 50 | * 3 minor changes 51 | 52 | * Expands the 'Pow is not installed' message 53 | ([commit](https://github.com/rodreegez/powder/commit/64b2e63e54b3cf0e2c49332a38929c6050b03088)) 54 | 55 | * Fixes Readme typo 56 | ([commit](https://github.com/rodreegez/powder/commit/2d5decd0cc2d5af1d4f4fac606a385aa318f68fb)) 57 | 58 | * Updates gist URLs 59 | ([commit](https://github.com/rodreegez/powder/commit/96af4fae93bd35a47a6cf0baa99f85aa739d0835)) 60 | 61 | ### 0.2.0 / 2013-03-12 ### 62 | 63 | * 7 minor changes 64 | 65 | * fix debug command: rdebug connection errors 66 | ([commit](https://github.com/Rodreegez/powder/commit/3ea0a1bc68bd9517e5673cc64d8bf25f41a5e2de)) 67 | 68 | * fix debug command: prepend newline to rdebug.rb require 69 | ([commit](https://github.com/Rodreegez/powder/commit/cd2e72524c3d91fcddc9b4a5b5420757c959f411)) 70 | 71 | * adds 2 aliases: powder up(start) & powder down(stop) 72 | ([commit](https://github.com/Rodreegez/powder/commit/54cdee5f6f2832d118995f28f28f4a03048c2ae6)) 73 | 74 | * adds open command 75 | ([commit](https://github.com/Rodreegez/powder/commit/542df46b2fc08b1784280bac0de02d7e662c35c3)) 76 | 77 | * Fixed 'powder list' to display proxy ports. 78 | ([commit](https://github.com/Rodreegez/powder/commit/804b78b844b73c2349a151e6df7f534a7d98c379)) 79 | 80 | * Pow config and status tasks to use localhost:20559 81 | ([commit](https://github.com/Rodreegez/powder/commit/a2395157e30863af9d8d856a6dbb97b851d445b4)) 82 | 83 | * Manage Pow environment with powder 84 | ([commit](https://github.com/Rodreegez/powder/commit/5b60045127dc72c1fb3b663a97eb4f5e238d4042)) 85 | 86 | ### 0.1.8 / 2012-06-09 ### 87 | 88 | * 5 minor changes 89 | 90 | * Added support for opening app with appname.x.x.x.x.xip.io 91 | ([commit](https://github.com/Rodreegez/powder/commit/8d2b5641cc79d238edf19350fc74fdac1ad3221d)) 92 | 93 | * Support port mapping in pow 0.4 94 | ([commit](https://github.com/Rodreegez/powder/commit/d079999fd9b08237835c1c4b373067ad87b19cc3)) 95 | 96 | * add respawn command 97 | ([commit](https://github.com/rodreegez/powder/commit/e7da3776233d1062335dd5e5d7ee15a3a9e7de0a)) 98 | 99 | * Fix typo in message for generating basic config.ru in legacy apps 100 | ([commit](https://github.com/rodreegez/powder/commit/2dd3de86d41d0df2b2b1444e9f6526916360fca5)) 101 | 102 | * add a man page 103 | ([commit](https://github.com/rodreegez/powder/commit/64e6a0cc38184a8ac0dc80d95947d185f2bdd432)) 104 | 105 | ### 0.1.7 / 2011-11-02 ### 106 | 107 | * 1 minor change 108 | 109 | * adds proper support for alt names 110 | ([commit](https://github.com/Rodreegez/powder/commit/4b850b1dbb446f7d0c3a643d4cc7be99eebd417b)) 111 | * adds not_restarts command 112 | ([commit](https://github.com/Rodreegez/powder/commit/9371ccdf822a83db7f1fded365d01bd2c613aed3)) 113 | * adds always_restart command 114 | ([commit](https://github.com/Rodreegez/powder/commit/45bd64180930353ef6c45626ccae150091374828)) 115 | * pow down properly unloads pow processes 116 | ([commit](https://github.com/Rodreegez/powder/commit/a6373e73c746587eb1ae23aaa1a26fe331274e6d)) 117 | * adds host/unhost for dealing with no network 118 | ([commit](https://github.com/Rodreegez/powder/commit/547c3d1e2fbc155fea3c162a373fed017a739107)) 119 | * Don't break config/status when pow is down 120 | ([commit](https://github.com/Rodreegez/powder/commit/c3aa98943c51079e2e8a1dc0a983efe76e2964c7)) 121 | 122 | ### 0.1.5 / 2011-06-30 ### 123 | 124 | * 4 minor changes 125 | 126 | * Expand path to ~/.powconfig before reading it 127 | ([commit](https://github.com/Rodreegez/powder/commit/58ec48e4f369ea72e76c15900e7ec8f0c6b0bbf1)) 128 | * Fix generating config.ru 129 | ([commit](https://github.com/Rodreegez/powder/commit/f65d3f1f897a36d18ea3ea54fa39627c8d5fcee6)) 130 | * Add config and status commands 131 | ([commit](https://github.com/Rodreegez/powder/commit/9f7ec926a9b502d2fe546c9f1b1d396477a3cae4)) 132 | 133 | ### 0.1.4 / 2011-05-26 ### 134 | 135 | * 2 minor change 136 | 137 | * Fixes log command: the pow log (~/Library/Logs/Pow/apps/app-name.log) is 138 | only created as the name of the directory, regardless of the name of the 139 | symlink added in .pow (issue 23) 140 | ([commit](https://github.com/Rodreegez/powder/commit/12fe024cc6768439d1555d61d770f660bfaf2d15)) 141 | * Supports Radiant apps (issue 21) 142 | ([commit](https://github.com/Rodreegez/powder/commit/5854f32ca0b1106fefad8eb6b7a0e7d2c91e67d3)) 143 | 144 | ### 0.1.3 / 2011-05-20 ### 145 | 146 | * 2 minor changes 147 | 148 | * add up and down commands 149 | ([commit](https://github.com/Rodreegez/powder/commit/e8775c166da40fad16d55df0022a61fd5d5af69b)) 150 | * add applog command 151 | ([commit](https://github.com/Rodreegez/powder/commit/36d8e04aea2eac618611eaffe78ce8eb55eccc51)) 152 | 153 | ### 0.1.2 / 2011-04-14 ### 154 | 155 | * 6 minor changes 156 | 157 | * add log command 158 | ([commit](https://github.com/Rodreegez/powder/commit/140ef1fef456e3cbe266a2df61b03f3e9c403aeb)) 159 | * fix error when calling remove on a pow that does not exist 160 | ([commit](https://github.com/Rodreegez/powder/commit/948f7251153afaab7c881b312b094d9843919dcb)) 161 | * properly recognise rails 2 apps and display note accordingly 162 | ([commit](https://github.com/Rodreegez/powder/commit/0445eb652ec824a7f84d12567539a7c2515341a2)) 163 | * bump dependency on Thor 164 | ([commit](https://github.com/Rodreegez/powder/commit/493a8f84c27b94fcd24dc84168a47a7c399a9ba1)) 165 | * improve how we determin home dir 166 | ([commit](https://github.com/Rodreegez/powder/commit/b2e70ca790420a06c21a7f4fc466c167c65fb173)) 167 | * adds version command 168 | ([commit](https://github.com/Rodreegez/powder/commit/3bb995e2ce5ee2f62735b681b2c15418438f2df4)) 169 | 170 | ### 0.1.1 / 2011-04-11 ### 171 | 172 | * 1 minor change 173 | 174 | * We won't try reading ~/.powconfig if it doesn't exist 175 | 176 | ### 0.1.0 / 2011-04-11 ### 177 | 178 | * 1 Major change 179 | 180 | * The command has changed from pow to powder to allow pow to use the command 181 | ([issue](https://github.com/Rodreegez/powder/issues/5)) 182 | 183 | * 1 minor change 184 | 185 | * open and link now honour domains specified in .powconfig 186 | 187 | ### 0.0.4 / 2011-04-08 ### 188 | 189 | * Early release with link, list, restart, remove, open, install and uninstall commands 190 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org/" 2 | 3 | # Specify your gem's dependencies in powder.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Adam Rogers and Phil Nash 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | powder manages [pow](http://pow.cx/) 2 | 3 | # Install # 4 | 5 | gem install powder 6 | 7 | # Usage # 8 | 9 | 10 | ### Linking apps in Pow ### 11 | 12 | powder will attempt to read .powder, which names a default symlink for the current project 13 | 14 | $ powder [-h|help] 15 | => Display usage information 16 | # Lists name and brief descriptions of the tasks available 17 | 18 | $ powder link 19 | => Link the current dir to ~/.pow/ 20 | 21 | $ powder link [bacon] 22 | => Link the current dir to ~/.pow/bacon 23 | => Create .powder, contents bacon 24 | 25 | $ powder link [bacon] --no-create 26 | => Link the current dir to ~/.pow/bacon 27 | 28 | $ powder link [bacon] --force 29 | => Remove the current pow symlink, and .powder 30 | => Link the current dir to ~/.pow/bacon 31 | => Create .powder, contents bacon 32 | 33 | # For both forms of link, if the current directory doesn't 34 | # look like an app that can be powed it will offer to download 35 | # a basic config.ru for Rails 2 36 | 37 | $ powder default 38 | => Link the current dir to ~/.pow/default 39 | # Serve this directory for all unhandled domains 40 | 41 | $ powder unlink 42 | => Unlink current_dir or the symlink defined in .powder 43 | 44 | $ powder unlink bacon 45 | => Unlink bacon 46 | 47 | $ powder cleanup 48 | => remove all invalid symbolic links 49 | 50 | ### Working with Pow ### 51 | 52 | $ powder applog 53 | => tail the log of the current app 54 | 55 | $ powder config 56 | => Get Pow's current configuration information 57 | 58 | $ powder list 59 | => List all the current apps linked in ~/.pow 60 | # aliased as powder -l 61 | 62 | $ powder log 63 | => Tails the pow log. 64 | # Not the application log, but the pow log, available at 65 | # ~/Library/Logs/Pow/apps/#{app-directory}.log 66 | 67 | $ powder debug 68 | => Opens a debug shell with your application environment 69 | 70 | $ powder open 71 | => Opens the pow link in a browser 72 | # aliased as powder -o 73 | 74 | $ powder open --xip 75 | => Opens the xip.io link in a browser 76 | # aliased as powder -o -x 77 | 78 | $ powder open [bacon] 79 | => Opens http://bacon.test in a browser 80 | # if you have set up alternative top level domains in .powconfig, 81 | # then the first listed domain will be opened. 82 | 83 | $ powder open --browser Safari 84 | => Opens the pow link in a specific browser (in this case, Safari) 85 | # Also aliased as -b 86 | 87 | $ powder open -b 'Google Chrome' 88 | => Opens the pow link with browsers with more than one word 89 | 90 | # Should also works with all the other 'open' options: 91 | $ powder open bacon -b Safari 92 | $ powder open --xip -b Firefox 93 | $ powder -o -x -b 'Google Chrome' 94 | 95 | $ powder open [--path|-p] home 96 | => Opens the pow link with a path appended, e.g. http://bacon.test/home 97 | 98 | $ powder restart 99 | => Restart the current app 100 | # aliased as powder -r 101 | 102 | $ powder always_restart 103 | => Always restart the current app 104 | # aliased as powder -a 105 | 106 | $ powder no_restarts 107 | => don't do any automatic restarting of the current app 108 | 109 | $ powder status 110 | => Get Pow's current status information 111 | 112 | $ powder version 113 | => Returns the current powder version 114 | # aliased as powder -v 115 | 116 | $ powder env 117 | => Displays your current custom pow environment variables 118 | # Pow reads environment varialbles from .powenv 119 | 120 | $ powder env_reset 121 | => Deletes your .powenv, removing all custom environment variables. 122 | 123 | $ powder env BACON chunky 124 | => Pass an arbitrary environment variable to pow, eg, ENV["BACON"] = "chunky" 125 | # Remove an ENV by passing in no value, eg: powder env BACON 126 | # If you already have a .gitignore, the newly created .powenv will also be ignored automatically. 127 | 128 | $ powder [production|development|test] 129 | => Run your Rails app as Production 130 | # aliased as powder [prod|dev] 131 | # This is a wrapper for powder env RAILS_ENV ... 132 | 133 | 134 | ### Install and uninstall Pow ### 135 | 136 | $ powder install 137 | => Installs pow server 138 | # (I know, "curl get.pow.cx | sh" isn't hard, but this is _even_ easier) 139 | 140 | $ powder uninstall 141 | => Uninstalls pow server 142 | 143 | $ powder update 144 | => Updates pow server 145 | # Really this is just an alias to powder install, but it feels more natural 146 | # this way. 147 | 148 | ### Enable and Disable Pow ### 149 | 150 | $ powder up 151 | => Enable Pow 152 | # aliased as powder start 153 | 154 | $ powder down 155 | => Disable Pow 156 | # aliased as powder stop 157 | 158 | # Contributors # 159 | 160 | Built by [rodreegez](https://github.com/Rodreegez) and [philnash](https://github.com/philnash). 161 | 162 | Massive thanks to all our great 163 | [contributors](https://github.com/Rodreegez/powder/contributors) 164 | 165 | # Related tools # 166 | 167 | * [Powser](https://github.com/phil-monroe/powser) - Powder for your browser! 168 | 169 | ## Copyright ## 170 | 171 | Copyright (c) 2011 Adam Rogers and Phil Nash. See LICENSE for details. 172 | 173 | Lovingly supported by [Mint Digital](http://mintdigital.com) 174 | -------------------------------------------------------------------------------- /bin/powder: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'thor' 5 | require 'fileutils' 6 | require 'net/https' 7 | require 'powder' 8 | require 'powder/version' 9 | 10 | module Powder 11 | class CLI < Thor 12 | include Thor::Actions 13 | include Powder 14 | default_task :help 15 | 16 | map '-r' => 'restart' 17 | map '-a' => 'always_restart' 18 | map '-l' => 'list' 19 | map '-L' => 'link' 20 | map '-d' => 'default' 21 | map '-o' => 'open' 22 | map '-v' => 'version' 23 | 24 | MAC_OS_X_VERSION_REGEXP = /^(?\d+)\.(?\d+)/ 25 | MAC_OS_X_MINOR_VERSION = begin 26 | version_string = %x{sw_vers -productVersion}.strip 27 | version_string.match(MAC_OS_X_VERSION_REGEXP)[:minor_version].to_i 28 | end 29 | 30 | POWDER_CONFIG = ".powder" 31 | POW_ENV = ".powenv" 32 | POW_PATH = "#{ENV['HOME']}/.pow" 33 | POW_CONFIG = "#{ENV['HOME']}/.powconfig" 34 | POW_DAEMON_PLIST_PATH="#{ENV['HOME']}/Library/LaunchAgents/cx.pow.powd.plist" 35 | POW_FIREWALL_PLIST_PATH = "/Library/LaunchDaemons/cx.pow.firewall.plist" 36 | 37 | desc "env", "Pass an arbitrary environment variable to pow" 38 | def env(key = nil, value = nil) 39 | if key.nil? 40 | show_env 41 | else 42 | value.nil? ? remove_env(key) : create_or_update_env(key, value) 43 | end 44 | end 45 | 46 | desc "env_reset", "Remove all custom environment variables" 47 | def env_reset 48 | %x{rm .powenv && touch .powenv} if powenv_exists? 49 | end 50 | 51 | desc "test", "Run pow with RAILS_ENV=test" 52 | def test 53 | env("RAILS_ENV", "test") 54 | end 55 | 56 | desc "development", "Run pow with RAILS_ENV=development" 57 | def development 58 | env("RAILS_ENV", "development") 59 | end 60 | 61 | desc "dev", "An alias to development" 62 | alias :dev :development 63 | 64 | desc "production", "Run pow with RAILS_ENV=production" 65 | def production 66 | env("RAILS_ENV", "production") 67 | end 68 | 69 | desc "prod", "An alias to production" 70 | alias :prod :production 71 | 72 | desc "up", "Enable pow" 73 | def up 74 | if MAC_OS_X_MINOR_VERSION >= 10 75 | start_on_yosemite 76 | else 77 | start_on_mavericks 78 | end 79 | say "Pow has been started." 80 | end 81 | 82 | desc "start", "An alias to up" 83 | alias :start :up 84 | 85 | desc "down", "Disable pow" 86 | def down 87 | if File.exists? POW_FIREWALL_PLIST_PATH 88 | if not %x{sudo launchctl list | grep cx.pow.firewall}.empty? 89 | %x{sudo launchctl unload #{POW_FIREWALL_PLIST_PATH} 2>/dev/null} 90 | end 91 | end 92 | 93 | if File.exists? POW_DAEMON_PLIST_PATH 94 | %x{launchctl unload #{POW_DAEMON_PLIST_PATH} 2>/dev/null} 95 | end 96 | 97 | if MAC_OS_X_MINOR_VERSION >= 10 98 | stop_on_yosemite 99 | else 100 | stop_on_mavericks 101 | end 102 | 103 | say "Pow has been stopped." 104 | end 105 | 106 | desc "stop", "An alias to down" 107 | alias :stop :down 108 | 109 | desc "link", "Link a pow" 110 | method_option :force, :type => :boolean, :default => false, :aliases => '-f', :desc => "remove the old configuration, overwrite .powder" 111 | method_option :"no-config", :type => :boolean, :default => false, :aliases => '-n', :desc => "do not write a .powder file" 112 | def link(name=nil) 113 | return unless is_powable? 114 | if File.symlink?(POW_PATH) 115 | current_path = %x{pwd}.chomp 116 | if name 117 | write_pow_config(name) 118 | else 119 | name = get_pow_name 120 | end 121 | symlink_path = "#{POW_PATH}/#{name}" 122 | FileUtils.rm_f(symlink_path) if options[:force] 123 | FileUtils.ln_s(current_path, symlink_path) unless File.exists?(symlink_path) 124 | say "Your application is now available at http://#{name}.#{domain}/" 125 | else 126 | say "Pow is not installed. That is, the ${HOME}/.pow symlink does not exist." 127 | end 128 | end 129 | 130 | desc "default", "Set this app as default" 131 | def default(name=nil) 132 | return unless is_powable? 133 | current_path = %x{pwd}.chomp 134 | name ||= get_pow_name 135 | symlink_path = "#{POW_PATH}/default" 136 | FileUtils.rm_f symlink_path if File.exists?(symlink_path) 137 | FileUtils.ln_sf(current_path, symlink_path) 138 | say "Your application(#{name}) is now default at http://localhost/" 139 | end 140 | 141 | desc "un_default", "remove current default app" 142 | def un_default(name=nil) 143 | name ||= get_pow_name 144 | symlink_path = "#{POW_PATH}/default" 145 | FileUtils.rm_f symlink_path if File.exists?(symlink_path) 146 | end 147 | 148 | desc "restart", "Restart current pow" 149 | def restart 150 | return unless is_powable? 151 | FileUtils.mkdir_p('tmp') 152 | %x{touch tmp/restart.txt} 153 | end 154 | 155 | desc "always_restart", "Always restart current pow" 156 | def always_restart 157 | return unless is_powable? 158 | FileUtils.mkdir_p('tmp') 159 | %x{touch tmp/always_restart.txt} 160 | end 161 | 162 | desc "no_restarts", "Reset this app's restart settings" 163 | def no_restarts 164 | return unless is_powable? 165 | FileUtils.rm_f Dir.glob('tmp/*restart.txt') 166 | end 167 | 168 | desc "respawn", "Restart the pow process" 169 | def respawn 170 | %x{launchctl stop cx.pow.powd} 171 | end 172 | 173 | desc "list", "List current pows" 174 | def list 175 | pows = Dir[POW_PATH + "/*"].map do |link_or_port| 176 | realpath_or_port = get_app_origin(link_or_port) 177 | app_is_current = (realpath_or_port == Dir.pwd) ? '*' : ' ' 178 | [app_is_current, File.basename(link_or_port), realpath_or_port.gsub(ENV['HOME'], '~')] 179 | end 180 | print_table(pows) 181 | end 182 | 183 | desc "open", "Open a pow in the browser" 184 | method_option :browser, :type => :string, :default => nil, :aliases => '-b', :desc => 'browser to open with' 185 | method_option :xip, :type => :boolean, :default => false, :aliases => '-x', :desc => "open xip.io instead of .domain" 186 | method_option :path, :type => :string, :default => '', :aliases => '-p', :desc => 'path to open' 187 | def open(name=nil) 188 | browser = options.browser? ? "-a \'#{options.browser}\'" : nil 189 | path = options.path.start_with?('/') ? options.path : '/' + options.path 190 | if options.xip? 191 | local_ip = '0.0.0.0' 192 | begin 193 | orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily 194 | UDPSocket.open do |s| 195 | s.connect '64.233.187.99', 1 196 | local_ip = s.addr.last.to_s 197 | end 198 | ensure 199 | Socket.do_not_reverse_lookup = orig 200 | end 201 | %x{open #{browser} http://#{name || get_pow_name}.#{local_ip}.xip.io#{path}} 202 | else 203 | %x{open #{browser} http://#{name || get_pow_name}.#{domain}#{path}} 204 | end 205 | end 206 | 207 | desc "unlink", "Unlink a pow app" 208 | method_option :delete, :type => :boolean, :default => false, :aliases => '-e', :desc => "delete .powder" 209 | def unlink(name=nil) 210 | return unless is_powable? 211 | FileUtils.rm_f POW_PATH + '/' + (name || get_pow_name) 212 | say "Successfully removed #{(name || get_pow_name)}" 213 | if options[:delete] 214 | FileUtils.rm_f POWDER_CONFIG 215 | say "Successfully removed #{POWDER_CONFIG}" 216 | end 217 | end 218 | 219 | desc "remove", "An alias to Unlink (deprecated)" 220 | alias :remove :unlink 221 | 222 | desc "cleanup", "Clean up invalid symbolic link" 223 | def cleanup 224 | Dir[POW_PATH + "/*"].map do |symlink| 225 | begin 226 | FileUtils.rm(symlink) unless File.exists?(File.readlink(symlink)) 227 | rescue 228 | # Not all platforms support File.readlink, thus throwing exceptions. 229 | # Unfortunately we can't decide then if a symlink is invalid. 230 | end 231 | end 232 | end 233 | 234 | desc "install", "Installs or updates pow" 235 | def install 236 | %x{curl get.pow.cx | sh} 237 | end 238 | 239 | desc "update", "An alias to install" 240 | alias :update :install 241 | 242 | desc "log", "Tails the Pow log" 243 | def log 244 | path_to_log_file = "#{ENV['HOME']}/Library/Logs/Pow/apps/#{current_dir_name}.log" 245 | if File.exist? path_to_log_file 246 | begin 247 | system "tail -f #{path_to_log_file}" 248 | rescue Interrupt 249 | say "\nExiting log..." 250 | exit 130 251 | end 252 | else 253 | say "There is no Pow log file, have you set this application up yet?" 254 | end 255 | end 256 | 257 | desc "applog", "Tails in current app" 258 | def applog(env="development") 259 | begin 260 | system "tail -f log/#{env}.log" if is_powable? 261 | rescue Interrupt 262 | say "\nExiting log..." 263 | exit 130 264 | end 265 | end 266 | 267 | desc "uninstall", "Uninstalls pow" 268 | def uninstall 269 | %x{curl get.pow.cx/uninstall.sh | sh} 270 | end 271 | 272 | desc "debug", "Open a debug session" 273 | def debug 274 | check_rdebug_initializer 275 | # Connect to remote rdebug session 276 | require 'ruby-debug' 277 | Debugger.settings[:autoeval] = true 278 | Debugger.settings[:autolist] = 1 279 | Debugger.settings[:reload_source_on_change] = true 280 | connected = false 281 | start = Time.now.to_i 282 | while !connected && (Time.now.to_i - start) < 15 283 | begin 284 | Debugger.start_client && connected = true 285 | rescue 286 | next 287 | end 288 | end 289 | say "Tried to connect for 15 seconds. Is the server ready for a debugger connection?" unless connected 290 | end 291 | 292 | desc "version", "Shows the version" 293 | def version 294 | say "powder #{Powder::VERSION}" 295 | end 296 | 297 | desc "host", "Updates hosts file to map pow domains to 127.0.0.1" 298 | def host 299 | hosts_file_path = "/etc/hosts" 300 | pow_domain_records = Dir[POW_PATH + "/*"].map { |a| "127.0.0.1\t#{File.basename(a)}.#{domain}\t#powder" } 301 | hosts_file = File.read("/etc/hosts").split("\n").delete_if {|row| row =~ /.+(#powder)/} 302 | first_loopback_index = hosts_file.index {|i| i =~ /^(127.0.0.1).+/} 303 | hosts_file = hosts_file.insert(first_loopback_index + 1, pow_domain_records) 304 | File.open("#{ENV['HOME']}/hosts-powder", "w") do 305 | |file| file.puts hosts_file.join("\n") 306 | end 307 | %x{cp #{hosts_file_path} #{ENV['HOME']}/hosts-powder.bak} 308 | %x{sudo mv #{ENV['HOME']}/hosts-powder #{hosts_file_path}} 309 | %x{dscacheutil -flushcache} 310 | say "Domains added to hosts file, old host file is saved at #{ENV['HOME']}/hosts-powder.bak" 311 | end 312 | 313 | desc "unhost", "Removes pow domains from hostfile" 314 | def unhost 315 | hosts_file_path = "/etc/hosts" 316 | hosts_file = File.read("/etc/hosts").split("\n").delete_if {|row| row =~ /.+(#powder)/} 317 | File.open("#{ENV['HOME']}/hosts-powder", "w") do 318 | |file| file.puts hosts_file.join("\n") 319 | end 320 | %x{cp #{hosts_file_path} #{ENV['HOME']}/hosts-powder.bak} 321 | %x{sudo mv #{ENV['HOME']}/hosts-powder #{hosts_file_path}} 322 | %x{dscacheutil -flushcache} 323 | say "Domains removed from hosts file, old host file is saved at #{ENV['HOME']}/hosts-powder.bak" 324 | end 325 | 326 | desc "config", "Shows current pow configuration" 327 | def config 328 | http_port = ":" + configured_pow_http_port.to_s 329 | results = %x{curl --silent -H host:pow 127.0.0.1#{http_port}/config.json}.gsub(':','=>') 330 | return say("Error: Cannot get Pow config. Pow may be down. Try 'powder up' first.") if results.empty? || !(results =~ /^\{/) 331 | json = eval results 332 | json.each do |k,v| 333 | case v 334 | when String, Numeric 335 | say "#{k.ljust(12,' ')} #{v}" 336 | when Array 337 | say "#{k.ljust(12,' ')} #{v.join ', '}\n" 338 | end 339 | end 340 | end 341 | 342 | desc "status", "Shows current pow status" 343 | def status 344 | http_port = ":" + configured_pow_http_port.to_s 345 | results = %x{curl --silent -H host:pow 127.0.0.1#{http_port}/status.json}.gsub(':','=>') 346 | return say("Error: Cannot get Pow status. Pow may be down. Try 'powder up' first.") if results.empty? || !(results =~ /^\{/) 347 | json = eval results 348 | json.each {|k,v| say "#{k.ljust(12, ' ')} #{v}"} 349 | end 350 | 351 | desc "portmap PORT", "Map a port to an app" 352 | method_option :name, :type => :string, :aliases => '-n', :desc => 'name of the port map' 353 | method_option :force, :type => :boolean, :default => false, :aliases => '-f', :desc => "remove the old configuration, overwrite .powder" 354 | def portmap(port) 355 | if File.symlink?(POW_PATH) 356 | name = options.name ? options.name : get_pow_name 357 | app_path = "#{POW_PATH}/#{name}" 358 | FileUtils.rm_f(app_path) if options[:force] 359 | File.open(app_path, 'w') do |file| 360 | file.write(port) 361 | end 362 | say "Your application is now available at http://#{name}.#{domain}/" 363 | else 364 | say "Pow is not installed." 365 | end 366 | 367 | end 368 | 369 | desc "env_rvm", "Create or add rvm env to .powenv" 370 | def env_rvm 371 | if File.exists?(%x{pwd}.chomp + "/.rvmrc") 372 | say %x{rvm env . -- --env >> #{POW_ENV}} 373 | show_env 374 | else 375 | say ".rvmrc does not exist." 376 | end 377 | end 378 | 379 | private 380 | 381 | def powenv_exists? 382 | File.exists?(POW_ENV) 383 | end 384 | 385 | def show_env 386 | if powenv_exists? && File.readlines(POW_ENV).any? 387 | say %x{echo && cat #{POW_ENV} && echo} 388 | else 389 | say "\nYou haven't yet configured any custom environment variables for pow." 390 | say "Try `powder env BACON chunky` to set ENV[\"BACON\"]=chunky" 391 | say " or `powder env BACON` to remove ENV[\"BACON\"]" 392 | say " or `powder prod` to set RAILS_ENV=production.\n\n" 393 | end 394 | end 395 | 396 | def remove_env(key) 397 | if powenv_exists? && File.readlines(POW_ENV).grep(/export #{key}=/).any? 398 | %x{sed -i '' '/^export #{key}=.*$/d' #{POW_ENV}} 399 | end 400 | end 401 | 402 | def create_or_update_env(key, value) 403 | if exists = powenv_exists? && File.readlines(POW_ENV).grep(/export #{key}=/).any? 404 | %x{sed -i '' 's/^export #{key}=.*$/export #{key}=#{value}/' #{POW_ENV}} 405 | say "Modified #{POW_ENV}" 406 | else 407 | %x{echo "export #{key}=#{value}" >> #{POW_ENV} && touch tmp/restart.txt} 408 | say "Appended to #{POW_ENV}" 409 | gitignore POW_ENV unless exists 410 | end 411 | end 412 | 413 | def gitignore(filename) 414 | if File.exists?(".gitignore") && File.readlines(".gitignore").grep(Regexp.new(filename)).none? 415 | %x{echo #{filename} >> .gitignore} 416 | say "\nYou'll probably be wanting to .gitignore that new .powenv file..." 417 | say "Here, let me take care of that for you.\n\n" 418 | end 419 | end 420 | 421 | def current_dir_name 422 | File.basename(%x{pwd}.chomp) 423 | end 424 | 425 | def configured_pow_name 426 | return nil unless File.exists?(POWDER_CONFIG) 427 | 428 | File.foreach(POWDER_CONFIG) do |line| 429 | next if line =~ /^($|#)/ 430 | return line.chomp 431 | end 432 | 433 | return nil 434 | end 435 | 436 | def configured_pow_http_port 437 | return 20559 unless File.exists?(POW_CONFIG) 438 | 439 | return File.open(POW_CONFIG).read.match(/export[\s]+POW_HTTP_PORT[\s]*=[\s]*(\d+)/) || 20559 440 | end 441 | 442 | def current_dir_pow_name 443 | current_dir_name.tr('_', '-') 444 | end 445 | 446 | def get_pow_name 447 | configured_pow_name || current_dir_pow_name 448 | end 449 | 450 | def write_pow_config(name=nil) 451 | return if ! name || options[:"no-config"] 452 | powder_exists = File.exists?(POWDER_CONFIG) 453 | configured_name = get_pow_name 454 | 455 | unlink if powder_exists && configured_name != name 456 | 457 | if options[:force] || ! powder_exists 458 | File.open(POWDER_CONFIG, "w") do |f| 459 | f.puts(name) 460 | end 461 | say "Created powder config #{POWDER_CONFIG}" 462 | elsif !options[:force] && powder_exists && configured_name != name 463 | say "Cowardly refusing to overwrite #{POWDER_CONFIG}" 464 | exit 1 465 | end 466 | end 467 | 468 | def is_powable? 469 | if File.exists?('config.ru') || File.exists?('public/index.html') 470 | true 471 | elsif legacy = (is_rails2_app? || is_radiant_app?) 472 | say "This appears to be a #{legacy} application. You need a config.ru file." 473 | if yes? "Do you want to autogenerate a basic config.ru for #{legacy}?" 474 | create_file "config.ru", get_gist("https://gist.github.com/sstephenson/909308/raw") 475 | return true 476 | else 477 | say "Did not create config.ru" 478 | return false 479 | end 480 | else 481 | say "This does not appear to be a rack app as there is no config.ru." 482 | say "Pow can also host static apps if there is an index.html in public/" 483 | return false 484 | end 485 | end 486 | 487 | def is_rails2_app? 488 | File.exists?('config/environment.rb') && 489 | !`grep RAILS_GEM_VERSION config/environment.rb`.empty? ? 'Rails 2' : nil 490 | end 491 | 492 | def is_radiant_app? 493 | File.exists?('config/environment.rb') && 494 | !`grep Radiant::Initializer config/environment.rb`.empty? ? 'Radiant' : nil 495 | end 496 | 497 | def domain 498 | if File.exists? File.expand_path(POW_CONFIG) 499 | returned_domain = %x{source #{POW_CONFIG}; echo $POW_DOMAINS}.gsub("\n", "").split(",").first 500 | returned_domain = %x{source #{POW_CONFIG}; echo $POW_DOMAIN}.gsub("\n", "") if returned_domain.nil? || returned_domain.empty? 501 | returned_domain = 'test' if returned_domain.nil? || returned_domain.empty? 502 | returned_domain 503 | else 504 | 'test' 505 | end 506 | end 507 | 508 | def check_rdebug_initializer 509 | rails_initializer = %x{pwd}.chomp + "/config/initializers/rdebug.rb" 510 | rack_initializer = %x{pwd}.chomp + "/rdebug.rb" 511 | unless File.exists?(rack_initializer) || File.exists?(rails_initializer) 512 | say "Its appears that the required initializer for rdebug doesn't exists in your application." 513 | if yes? "Do you want to create it(y/n)?" 514 | if yes? "This is a Rails/Radiant app(y/n)?" 515 | create_file rails_initializer, get_gist("https://gist.github.com/csiszarattila/1135055/raw") 516 | else 517 | create_file rack_initializer, get_gist("https://gist.github.com/csiszarattila/1262647/raw") 518 | append_to_file 'config.ru', "\nrequire 'rdebug.rb'" 519 | end 520 | restart 521 | else 522 | return false 523 | end 524 | end 525 | end 526 | 527 | def get_gist(url) 528 | uri = URI.parse(url) 529 | http = Net::HTTP.new(uri.host, uri.port) 530 | http.use_ssl = true 531 | http.verify_mode = OpenSSL::SSL::VERIFY_NONE 532 | request = Net::HTTP::Get.new(uri.request_uri) 533 | http.request(request).body 534 | end 535 | 536 | def start_on_yosemite 537 | return say "Pow daemon configuration missing." unless File.exists?(POW_DAEMON_PLIST_PATH) 538 | %x{launchctl bootstrap gui/"$UID" #{POW_DAEMON_PLIST_PATH} 2>/dev/null} 539 | 540 | %x{launchctl enable gui/"$UID"/cx.pow.powd 2>/dev/null} 541 | %x{launchctl kickstart -k gui/"$UID"/cx.pow.powd 2>/dev/null} 542 | end 543 | 544 | def stop_on_yosemite 545 | %{sudo pfctl -a "com.apple/250.PowFirewall" -F all 2>/dev/null} 546 | end 547 | 548 | def start_on_mavericks 549 | return say "Pow firewall configuration missing." unless File.exists?(POW_FIREWALL_PLIST_PATH) 550 | %x{launchctl load #{POW_FIREWALL_PLIST_PATH} 2>/dev/null} 551 | 552 | return say "Pow daemon configuration missing." unless File.exists?(POW_DAEMON_PLIST_PATH) 553 | %x{launchctl load #{POW_DAEMON_PLIST_PATH} 2>/dev/null} 554 | end 555 | 556 | def stop_on_mavericks 557 | if File.exists? POW_FIREWALL_PLIST_PATH 558 | if ports = File.open(POW_FIREWALL_PLIST_PATH).read.match(/fwd .*?,([\d]+).*?dst-port ([\d]+)/) 559 | http_port, dst_port = ports[1..2] 560 | end 561 | end 562 | 563 | http_port ||= 20559 564 | dst_port ||= 80 565 | 566 | if rule = %x{sudo ipfw show | grep ",#{http_port} .* dst-port #{dst_port} in"}.split.first 567 | %x{sudo ipfw delete #{rule} && sudo sysctl -w net.inet.ip.forwarding=0} 568 | end 569 | end 570 | 571 | end 572 | end 573 | 574 | Powder::CLI.start 575 | -------------------------------------------------------------------------------- /lib/powder.rb: -------------------------------------------------------------------------------- 1 | module Powder 2 | # Get the origin of the application link, whether it's a link to a 3 | # rack app or proxy to a port. 4 | def get_app_origin(app_link) 5 | if File.symlink? app_link 6 | File.readlink(app_link) 7 | else 8 | port = File.readlines(app_link)[0] 9 | "proxy port: #{port}" 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/powder/version.rb: -------------------------------------------------------------------------------- 1 | module Powder 2 | VERSION = "0.4.0" 3 | end 4 | -------------------------------------------------------------------------------- /man/powder.1: -------------------------------------------------------------------------------- 1 | .\" generated with Ronn/v0.7.3 2 | .\" http://github.com/rtomayko/ronn/tree/0.7.3 3 | . 4 | .TH "POWDER" "1" "August 2012" "" "" 5 | . 6 | .SH "NAME" 7 | \fBpowder\fR \- manage Pow Rack server 8 | . 9 | .SH "SYNOPSIS" 10 | \fBpowder\fR 11 | . 12 | .SH "DESCRIPTION" 13 | Command\-line management utility for 37signals\' Pow zero\-configuration Rack server for OS X (http://pow\.cx/)\. 14 | . 15 | .SH "HOMEPAGE" 16 | https://github\.com/Rodreegez/powder 17 | . 18 | .SH "EXAMPLES" 19 | . 20 | .SS "Display usage information" 21 | \fB$ powder [\-h|help]\fR 22 | . 23 | .br 24 | => Display usage information 25 | . 26 | .br 27 | # Lists name and brief descriptions of the tasks available 28 | . 29 | .SS "Linking applications in Pow" 30 | powder will attempt to read \.powder, which names a default symlink for the current project 31 | . 32 | .P 33 | \fB$ powder link\fR 34 | . 35 | .br 36 | => Link the current dir to ~/\.pow/\fIcurrent_directory\fR 37 | . 38 | .P 39 | \fB$ powder link [bacon]\fR 40 | . 41 | .br 42 | => Link the current dir to ~/\.pow/bacon 43 | . 44 | .br 45 | => Create \.powder, contents bacon 46 | . 47 | .P 48 | \fB$ powder link [bacon] \-\-no\-create\fR 49 | . 50 | .br 51 | => Link the current dir to ~/\.pow/bacon 52 | . 53 | .P 54 | \fB$ powder link [bacon] \-\-force\fR 55 | . 56 | .br 57 | => Remove the current pow symlink, and \.powder 58 | . 59 | .br 60 | => Link the current dir to ~/\.pow/bacon 61 | . 62 | .br 63 | => Create \.powder, contents bacon 64 | . 65 | .P 66 | \fB$ powder default\fR => Link the current dir to ~/\.pow/default # Serve this directory for all unhandled domains 67 | . 68 | .P 69 | For both forms of link, if the current directory doesn\'t look like an app that can be powed it will offer to download a basic \fBconfig\.ru\fR for Rails 2 70 | . 71 | .SS "Unlinking applications" 72 | \fB$ powder unlink\fR 73 | . 74 | .br 75 | => Unlink current_dir or the symlink defined in \.powder 76 | . 77 | .P 78 | \fB$ powder unlink bacon\fR 79 | . 80 | .br 81 | => Unlink bacon 82 | . 83 | .P 84 | \fB$ powder cleanup\fR 85 | . 86 | .br 87 | => remove all invalid symbolic links 88 | . 89 | .SS "Working with Pow" 90 | \fB$ powder config\fR 91 | . 92 | .br 93 | => Get Pow\'s current configuration information 94 | . 95 | .P 96 | \fB$ powder list\fR 97 | . 98 | .br 99 | => List all the current apps linked in ~/\.pow 100 | . 101 | .br 102 | # aliased as \fBpowder \-l\fR 103 | . 104 | .P 105 | \fB$ powder status\fR 106 | . 107 | .br 108 | => Get Pow\'s current status information 109 | . 110 | .P 111 | \fB$ powder version\fR 112 | . 113 | .br 114 | => Returns the current powder version 115 | . 116 | .br 117 | # aliased as \fBpowder \-v\fR 118 | . 119 | .SS "Working with applications" 120 | \fB$ powder open\fR 121 | . 122 | .br 123 | => Opens the pow link in a browser 124 | . 125 | .br 126 | # aliased as powder \-o 127 | . 128 | .P 129 | \fB$ powder open [bacon]\fR 130 | . 131 | .br 132 | => Opens http://bacon\.test in a browser 133 | . 134 | .br 135 | # if you have set up alternative top level domains in \.powconfig, 136 | . 137 | .br 138 | # then the first listed domain will be opened\. 139 | . 140 | .P 141 | \fB$ powder open \-\-browser Safari\fR => Opens the pow link in a specific browser (in this case, Safari) # Also aliased as \-b 142 | . 143 | .P 144 | \fB$ powder open \-b \'Google Chrome\'\fR => Opens the pow link with browsers with more than one word 145 | . 146 | .P 147 | \fB$ powder open \-\-path home\fR => Opens the pow link with a path appended (http://bacon.test/home) # Also aliased as \-p 148 | . 149 | .P 150 | # Should also works with all the other \'open\' options: \fB$ powder open bacon \-b Safari\fR \fB$ powder open \-\-xip \-b Firefox\fR \fB$ powder \-o \-x \-b \'Google Chrome\'\fR 151 | . 152 | .SS "Managing application restarts" 153 | \fB$ powder restart\fR 154 | . 155 | .br 156 | => Restart the current app 157 | . 158 | .br 159 | # aliased as \fBpowder \-r\fR 160 | . 161 | .P 162 | \fB$ powder always_restart\fR 163 | . 164 | .br 165 | => Always restart the current app 166 | . 167 | .br 168 | # aliased as powder \-a 169 | . 170 | .P 171 | \fB$ powder no_restarts\fR 172 | . 173 | .br 174 | => don\'t do any automatic restarting of the current app 175 | . 176 | .SS "Working with logs" 177 | \fB$ powder applog\fR 178 | . 179 | .br 180 | => tail the log of the current app 181 | . 182 | .P 183 | \fB$ powder log\fR 184 | . 185 | .br 186 | => Tails the pow log\. 187 | . 188 | .br 189 | # Not the application log, but the pow log, available at 190 | . 191 | .br 192 | # ~/Library/Logs/Pow/apps/#{app\-directory}\.log 193 | . 194 | .SS "Working with Environment Variables" 195 | \fB$ powder env\fR => Displays your current custom pow environment variables # Pow reads environment varialbles from \.powenv 196 | . 197 | .P 198 | \fB$ powder env_reset\fR => Deletes your \.powenv, removing all custom environment variables\. 199 | . 200 | .P 201 | \fB$ powder env BACON chunky\fR => Pass an arbitrary environment variable to pow, eg, ENV["BACON"] = "chunky" # Remove an ENV by passing in no value, eg: powder env BACON # If you already have a \.gitignore, the newly created \.powenv will also be ignored automatically\. 202 | . 203 | .P 204 | \fB$ powder [production|development|test]\fR => Run your Rails app as Production # aliased as powder [prod|dev] # This is a wrapper for powder env RAILS_ENV \.\.\. 205 | . 206 | .SS "Installing and uninstalling Pow" 207 | \fB$ powder install\fR 208 | . 209 | .br 210 | => Installs pow server 211 | . 212 | .br 213 | # (I know, "curl get\.pow\.cx | sh" isn\'t hard, but this is \fIeven\fR easier) 214 | . 215 | .P 216 | \fB$ powder uninstall\fR 217 | . 218 | .br 219 | => Uninstalls pow server 220 | . 221 | .P 222 | \fB$ powder update\fR 223 | . 224 | .br 225 | => Updates pow server 226 | . 227 | .br 228 | # Really this is just an alias to powder install, but it feels more natural 229 | . 230 | .br 231 | # this way\. 232 | . 233 | .SS "Enabling and Disabling Pow" 234 | \fB$ powder up\fR 235 | . 236 | .br 237 | => Enable Pow 238 | . 239 | .P 240 | \fB$ powder down\fR 241 | . 242 | .br 243 | => Disable Pow 244 | . 245 | .P 246 | \fB$ powder debug\fR => Opens a debug shell with your application environment 247 | . 248 | .SH "AUTHOR" 249 | Built by rodreegez \fIhttps://github\.com/Rodreegez\fR and philnash \fIhttps://github\.com/philnash\fR\. 250 | -------------------------------------------------------------------------------- /man/powder.1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | powder(1) - manage Pow Rack server 7 | 44 | 45 | 52 | 53 |
54 | 55 | 63 | 64 |
    65 |
  1. powder(1)
  2. 66 |
  3. 67 |
  4. powder(1)
  5. 68 |
69 | 70 |

NAME

71 |

72 | powder - manage Pow Rack server 73 |

74 | 75 |

SYNOPSIS

76 | 77 |

powder

78 | 79 |

DESCRIPTION

80 | 81 |

Command-line management utility for 37signals' Pow zero-configuration Rack server for OS X (http://pow.cx/).

82 | 83 |

HOMEPAGE

84 | 85 |

https://github.com/Rodreegez/powder

86 | 87 |

EXAMPLES

88 | 89 |

Display usage information

90 | 91 |

$ powder [-h|help]
92 | => Display usage information
93 | # Lists name and brief descriptions of the tasks available

94 | 95 |

Linking applications in Pow

96 | 97 |

powder will attempt to read .powder, which names a default symlink for the current project

98 | 99 |

$ powder link
100 | => Link the current dir to ~/.pow/current_directory

101 | 102 |

$ powder link [bacon]
103 | => Link the current dir to ~/.pow/bacon
104 | => Create .powder, contents bacon

105 | 106 |

$ powder link [bacon] --no-create
107 | => Link the current dir to ~/.pow/bacon

108 | 109 |

$ powder link [bacon] --force
110 | => Remove the current pow symlink, and .powder
111 | => Link the current dir to ~/.pow/bacon
112 | => Create .powder, contents bacon

113 | 114 |

$ powder default 115 | => Link the current dir to ~/.pow/default 116 | # Serve this directory for all unhandled domains

117 | 118 |

For both forms of link, if the current directory doesn't 119 | look like an app that can be powed it will offer to download 120 | a basic config.ru for Rails 2

121 | 122 |

Unlinking applications

123 | 124 |

$ powder unlink
125 | => Unlink current_dir or the symlink defined in .powder

126 | 127 |

$ powder unlink bacon
128 | => Unlink bacon

129 | 130 |

$ powder cleanup
131 | => remove all invalid symbolic links

132 | 133 |

Working with Pow

134 | 135 |

$ powder config
136 | => Get Pow's current configuration information

137 | 138 |

$ powder list
139 | => List all the current apps linked in ~/.pow
140 | # aliased as powder -l

141 | 142 |

$ powder status
143 | => Get Pow's current status information

144 | 145 |

$ powder version
146 | => Returns the current powder version
147 | # aliased as powder -v

148 | 149 |

Working with applications

150 | 151 |

$ powder open
152 | => Opens the pow link in a browser
153 | # aliased as powder -o

154 | 155 |

$ powder open [bacon]
156 | => Opens http://bacon.test in a browser
157 | # if you have set up alternative top level domains in .powconfig,
158 | # then the first listed domain will be opened.

159 | 160 |

$ powder open --browser Safari 161 | => Opens the pow link in a specific browser (in this case, Safari) 162 | # Also aliased as -b

163 | 164 |

$ powder open -b 'Google Chrome' 165 | => Opens the pow link with browsers with more than one word

166 | 167 |

$ powder open --path home 168 | => Opens the pow link with a path appended (http://bacon.test/home) 169 | # Also aliased as -p

170 | 171 |

# Should also works with all the other 'open' options: 172 | $ powder open bacon -b Safari 173 | $ powder open --xip -b Firefox 174 | $ powder -o -x -b 'Google Chrome'

175 | 176 |

Managing application restarts

177 | 178 |

$ powder restart
179 | => Restart the current app
180 | # aliased as powder -r

181 | 182 |

$ powder always_restart
183 | => Always restart the current app
184 | # aliased as powder -a

185 | 186 |

$ powder no_restarts
187 | => don't do any automatic restarting of the current app

188 | 189 |

Working with logs

190 | 191 |

$ powder applog
192 | => tail the log of the current app

193 | 194 |

$ powder log
195 | => Tails the pow log.
196 | # Not the application log, but the pow log, available at
197 | # ~/Library/Logs/Pow/apps/#{app-directory}.log

198 | 199 |

Working with Environment Variables

200 | 201 |

$ powder env 202 | => Displays your current custom pow environment variables 203 | # Pow reads environment varialbles from .powenv

204 | 205 |

$ powder env_reset 206 | => Deletes your .powenv, removing all custom environment variables.

207 | 208 |

$ powder env BACON chunky 209 | => Pass an arbitrary environment variable to pow, eg, ENV["BACON"] = "chunky" 210 | # Remove an ENV by passing in no value, eg: powder env BACON 211 | # If you already have a .gitignore, the newly created .powenv will also be ignored automatically.

212 | 213 |

$ powder [production|development|test] 214 | => Run your Rails app as Production 215 | # aliased as powder [prod|dev] 216 | # This is a wrapper for powder env RAILS_ENV ...

217 | 218 |

Installing and uninstalling Pow

219 | 220 |

$ powder install
221 | => Installs pow server
222 | # (I know, "curl get.pow.cx | sh" isn't hard, but this is even easier)

223 | 224 |

$ powder uninstall
225 | => Uninstalls pow server

226 | 227 |

$ powder update
228 | => Updates pow server
229 | # Really this is just an alias to powder install, but it feels more natural
230 | # this way.

231 | 232 |

Enabling and Disabling Pow

233 | 234 |

$ powder up
235 | => Enable Pow

236 | 237 |

$ powder down
238 | => Disable Pow

239 | 240 |

$ powder debug 241 | => Opens a debug shell with your application environment

242 | 243 |

AUTHOR

244 | 245 |

Built by rodreegez and philnash.

246 | 247 | 248 |
    249 |
  1. 250 |
  2. August 2012
  3. 251 |
  4. powder(1)
  5. 252 |
253 | 254 |
255 | 256 | 257 | -------------------------------------------------------------------------------- /man/powder.1.ronn: -------------------------------------------------------------------------------- 1 | powder(1) -- manage Pow Rack server 2 | =================================== 3 | 4 | ## SYNOPSIS 5 | 6 | `powder` 7 | 8 | ## DESCRIPTION 9 | 10 | Command-line management utility for 37signals' Pow zero-configuration Rack server for OS X (http://pow.cx/). 11 | 12 | ## HOMEPAGE 13 | 14 | https://github.com/Rodreegez/powder 15 | 16 | ## EXAMPLES 17 | 18 | ### Display usage information 19 | 20 | `$ powder [-h|help]` 21 | => Display usage information 22 | # Lists name and brief descriptions of the tasks available 23 | 24 | ### Linking applications in Pow 25 | 26 | powder will attempt to read .powder, which names a default symlink for the current project 27 | 28 | `$ powder link` 29 | => Link the current dir to ~/.pow/ 30 | 31 | `$ powder link [bacon]` 32 | => Link the current dir to ~/.pow/bacon 33 | => Create .powder, contents bacon 34 | 35 | `$ powder link [bacon] --no-create` 36 | => Link the current dir to ~/.pow/bacon 37 | 38 | `$ powder link [bacon] --force` 39 | => Remove the current pow symlink, and .powder 40 | => Link the current dir to ~/.pow/bacon 41 | => Create .powder, contents bacon 42 | 43 | `$ powder default` 44 | => Link the current dir to ~/.pow/default 45 | # Serve this directory for all unhandled domains 46 | 47 | For both forms of link, if the current directory doesn't 48 | look like an app that can be powed it will offer to download 49 | a basic **config.ru** for Rails 2 50 | 51 | ### Unlinking applications 52 | 53 | `$ powder unlink` 54 | => Unlink current_dir or the symlink defined in .powder 55 | 56 | `$ powder unlink bacon` 57 | => Unlink bacon 58 | 59 | `$ powder cleanup` 60 | => remove all invalid symbolic links 61 | 62 | ### Working with Pow 63 | 64 | `$ powder config` 65 | => Get Pow's current configuration information 66 | 67 | `$ powder list` 68 | => List all the current apps linked in ~/.pow 69 | # aliased as `powder -l` 70 | 71 | `$ powder status` 72 | => Get Pow's current status information 73 | 74 | `$ powder version` 75 | => Returns the current powder version 76 | # aliased as `powder -v` 77 | 78 | ### Working with applications 79 | 80 | `$ powder open` 81 | => Opens the pow link in a browser 82 | # aliased as powder -o 83 | 84 | `$ powder open [bacon]` 85 | => Opens http://bacon.test in a browser 86 | # if you have set up alternative top level domains in .powconfig, 87 | # then the first listed domain will be opened. 88 | 89 | `$ powder open --browser Safari` 90 | => Opens the pow link in a specific browser (in this case, Safari) 91 | # Also aliased as -b 92 | 93 | `$ powder open -b 'Google Chrome'` 94 | => Opens the pow link with browsers with more than one word 95 | 96 | `$ powder open --path home` 97 | => Opens the pow link with a path appended (http://bacon.test/home) 98 | # Also aliased as -p 99 | 100 | # Should also works with all the other 'open' options: 101 | `$ powder open bacon -b Safari` 102 | `$ powder open --xip -b Firefox` 103 | `$ powder -o -x -b 'Google Chrome'` 104 | 105 | ### Managing application restarts 106 | 107 | `$ powder restart` 108 | => Restart the current app 109 | # aliased as `powder -r` 110 | 111 | `$ powder always_restart` 112 | => Always restart the current app 113 | # aliased as powder -a 114 | 115 | `$ powder no_restarts` 116 | => don't do any automatic restarting of the current app 117 | 118 | ### Working with logs 119 | 120 | `$ powder applog` 121 | => tail the log of the current app 122 | 123 | `$ powder log` 124 | => Tails the pow log. 125 | # Not the application log, but the pow log, available at 126 | # ~/Library/Logs/Pow/apps/#{app-directory}.log 127 | 128 | ### Working with Environment Variables 129 | 130 | `$ powder env` 131 | => Displays your current custom pow environment variables 132 | # Pow reads environment varialbles from .powenv 133 | 134 | `$ powder env_reset` 135 | => Deletes your .powenv, removing all custom environment variables. 136 | 137 | `$ powder env BACON chunky` 138 | => Pass an arbitrary environment variable to pow, eg, ENV["BACON"] = "chunky" 139 | # Remove an ENV by passing in no value, eg: powder env BACON 140 | # If you already have a .gitignore, the newly created .powenv will also be ignored automatically. 141 | 142 | `$ powder [production|development|test]` 143 | => Run your Rails app as Production 144 | # aliased as powder [prod|dev] 145 | # This is a wrapper for powder env RAILS_ENV ... 146 | 147 | ### Installing and uninstalling Pow 148 | 149 | `$ powder install` 150 | => Installs pow server 151 | # (I know, "curl get.pow.cx | sh" isn't hard, but this is _even_ easier) 152 | 153 | `$ powder uninstall` 154 | => Uninstalls pow server 155 | 156 | `$ powder update` 157 | => Updates pow server 158 | # Really this is just an alias to powder install, but it feels more natural 159 | # this way. 160 | 161 | ### Enabling and Disabling Pow 162 | 163 | `$ powder up` 164 | => Enable Pow 165 | 166 | `$ powder down` 167 | => Disable Pow 168 | 169 | `$ powder debug` 170 | => Opens a debug shell with your application environment 171 | 172 | ## AUTHOR 173 | 174 | Built by [rodreegez](https://github.com/Rodreegez) and [philnash](https://github.com/philnash). 175 | -------------------------------------------------------------------------------- /powder.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "powder/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "powder" 7 | s.version = Powder::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.authors = ["Phil Nash", "Adam Rogers"] 10 | s.email = ["no"] 11 | s.homepage = "https://github.com/powder-rb/powder" 12 | s.summary = %q{Makes Pow even easier} 13 | s.description = %q{Makes Pow even easier. I mean really, really, ridiculously easy.} 14 | s.license = 'MIT' 15 | 16 | s.rubyforge_project = "powder" 17 | 18 | s.files = `git ls-files`.split("\n") 19 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 20 | s.executables = ["powder"] 21 | s.require_paths = ["lib"] 22 | 23 | s.add_dependency 'thor', '>=0.11.5' 24 | s.add_development_dependency 'rake' 25 | end 26 | --------------------------------------------------------------------------------