Permalink
Browse files

Rewritten gem in better Rubystyle and better browser/server support

Squashed commit of the following:

commit c14a883
Author: botanicus <stastny@101ideas.cz>
Date:   Thu Jul 12 19:03:01 2012 +0100

    Should works now.

commit d2a9343
Author: botanicus <stastny@101ideas.cz>
Date:   Thu Jul 12 17:08:15 2012 +0100

    Preview works.

commit 2fd37ca
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:48:52 2012 +0100

    Let's use something which is made for parsing CLI and executing commands: Nake.

commit b119103
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:24:53 2012 +0100

    Improper indentation, doesn't make sense.

commit aa40db5
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:21:21 2012 +0100

    Kernel#abort does exactly this.

commit 5c05e76
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:20:57 2012 +0100

    Using this syntax is more fault-tolerant, easier to reuse without all the dependencies. Not that big deal in this case but still.

commit 4841827
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:11:53 2012 +0100

    A bit more rubyish.

commit a15244a
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:06:27 2012 +0100

    Ignore Gemfile.lock. This file SHOULD be included in projects such as sites, not really in libraries. Reasoning: in sites we test that our + lib code works together. In generic libraries we can just assume whatever version will be fine. If it's not the case, we specify range of versions in Gemspec or gemfile.

commit 799a8ff
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:03:39 2012 +0100

    No Rakefile, why Rake?

commit 6ca4b47
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:03:10 2012 +0100

    Duplicates. By saying 'gemspec', we're saying take a look to the gemspec and take the dependencies from there.

commit 4353778
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:02:10 2012 +0100

    Typo.

commit aa1b91f
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 11:01:11 2012 +0100

    If someone press Ctrl+c, he expects that this happens ;)

commit 17a22b8
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 10:57:57 2012 +0100

    Tell users about private beta and how to get in. This message will be shown upon gem install apiary. @zzen check the message if it's alright like that.

commit c00d743
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 10:51:55 2012 +0100

    In my oppinion it's good to use \n at the end of files, try to use unix tools such as grep in the project otherwise.

commit f4cee92
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 10:49:06 2012 +0100

    Ah, of course, project_root is missing.

commit 0640802
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 10:47:33 2012 +0100

    I know, I used to do that too, thinking it's cool ... but think about it, you're introducing an unnecessary dependency, what if some poor guy doesn't have Git? Gemspec files should have no dependencies whatsoever.

commit a9a18de
Author: botanicus <stastny@101ideas.cz>
Date:   Fri Jul 6 10:44:35 2012 +0100

    It's unix baby, let's make it executable!
  • Loading branch information...
1 parent 8ce3fa1 commit 98712f2c5ead2de5f0d284523369b9e1a6951481 @botanicus botanicus committed with Almad Jul 13, 2012
Showing with 137 additions and 189 deletions.
  1. +2 −1 .gitignore
  2. +0 −8 Gemfile
  3. +0 −26 Gemfile.lock
  4. +1 −1 LICENSE
  5. +12 −4 apiary.gemspec
  6. +24 −11 bin/apiary
  7. +0 −2 lib/apiary.rb
  8. +0 −12 lib/apiary/cli.rb
  9. +0 −63 lib/apiary/cmd.rb
  10. +0 −41 lib/apiary/commands/base.rb
  11. +94 −18 lib/apiary/commands/preview.rb
  12. +4 −2 lib/apiary/version.rb
View
@@ -11,6 +11,7 @@ spec/reports
test/tmp
test/version_tmp
tmp
+/*.apib
# YARD artifacts
.yardoc
@@ -19,4 +20,4 @@ doc/
.DS_STORE
-
+Gemfile.lock
View
@@ -1,11 +1,3 @@
source "http://rubygems.org"
gemspec
-
-gem "launchy", ">= 0.3"
-gem "rest-client", ">= 1.6"
-
-group :development do
- gem "rake", ">= 0.8.7"
-end
-
View
@@ -1,26 +0,0 @@
-PATH
- remote: .
- specs:
- apiary (0.0.1)
- launchy (>= 0.3.2)
- rest-client (~> 1.6.1)
-
-GEM
- remote: http://rubygems.org/
- specs:
- addressable (2.2.8)
- launchy (2.1.0)
- addressable (~> 2.2.6)
- mime-types (1.18)
- rake (0.9.2.2)
- rest-client (1.6.7)
- mime-types (>= 1.16)
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- apiary!
- launchy (>= 0.3)
- rake (>= 0.8.7)
- rest-client (>= 1.6)
View
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
16 apiary.gemspec 100644 → 100755
@@ -1,4 +1,9 @@
-$:.unshift File.expand_path("../lib", __FILE__)
+#!/usr/bin/env gem build
+# encoding: utf-8
+
+project_root = File.dirname(__FILE__)
+
+$:.unshift(File.expand_path(File.join(project_root, "lib")))
require "apiary/version"
@@ -14,7 +19,10 @@ Gem::Specification.new do |gem|
gem.executables = "apiary"
gem.license = "MIT"
- gem.files = %x{ git ls-files }.split("\n").select { |d| d =~ %r{^(License|README|bin/|data/|ext/|lib/|spec/|test/)} }
+ gem.files = Dir.glob("#{project_root}/{lib,spec,apiary.gemspec,Gemfile,README.md,LICENSE}/**/*")
+
+ gem.add_dependency "nake"
gem.add_dependency "rest-client", "~> 1.6.1"
- gem.add_dependency "launchy", ">= 0.3.2"
-end
+
+ gem.post_install_message = "This gem is a client for http://apiary.io. Apiary is in closed beta version now, you need an invitation. If you don't have one, visit http://apiary.us2.list-manage.com/subscribe?u=b89934a238dcec9533f4a834a&id=08f2bdde55 to get on the waiting list!"
+end
View
@@ -1,14 +1,27 @@
-#!/usr/bin/env ruby
-# encoding: UTF-8
+#!/usr/bin/env nake
+# encoding: utf-8
-begin
- require "pathname"
- bin_file = Pathname.new(__FILE__).realpath
+# Make sure symlinks to this file work.
+real_bin_path = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
+root_directory = File.expand_path(File.join(File.dirname(real_bin_path), ".."))
+lib_directory = File.join(root_directory, "lib")
- $:.unshift File.expand_path("../../lib", bin_file)
+# In development environment we want to use ./lib.
+unless $LOAD_PATH.include?(lib_directory)
+ $LOAD_PATH.unshift(lib_directory)
+end
- require "apiary/cli"
- Apiary::CLI.start(*ARGV)
-rescue Interrupt
- puts("\n Cancelled.")
-end
+require "nake"
+require "apiary/commands/preview"
+
+Nake.verbose = false
+
+Nake.args["-H", "--help"] = lambda do |*|
+ puts
+
+ Nake::Task.tasks.each do |name, task|
+ puts "#{File.basename(__FILE__)} #{name} # #{task.description}"
+ end
+
+ exit
+end
View
@@ -1,2 +0,0 @@
-module Apiary; end
-
View
@@ -1,12 +0,0 @@
-require "apiary"
-require "apiary/cmd"
-
-class Apiary::CLI
-
- def self.start(*args)
- command = args.shift.strip rescue "help"
- Apiary::Command.load
- Apiary::Command.run(command, args)
- end
-
-end
View
@@ -1,63 +0,0 @@
-# Base skeleton taken from Heroku base command,
-# https://github.com/heroku/heroku/blob/master/lib/heroku/command.rb
-# (c) Heroku and contributors
-
-module Apiary
- module Command
- class CommandFailed < RuntimeError; end
-
- def self.commands
- @@commands ||= {}
- end
-
- def self.command_aliases
- @@command_aliases ||= {}
- end
-
- def self.load
- Dir[File.join(File.dirname(__FILE__), "commands", "*.rb")].each do |file|
- require file
- end
- end
-
- def self.parse(cmd)
- commands[cmd] || commands[command_aliases[cmd]]
- end
-
- def self.prepare_run(cmd, args=[])
- command = parse(cmd)
-
- unless command
- if %w( -v --version ).include?(cmd)
- command = parse('version')
- else
- error([
- "`#{cmd}` is not an apiary command.",
- ].compact.join("\n"))
- end
- end
-
- # add args, opts
- [ command[:klass].new(), command[:method] ]
- end
-
- def self.register_command(command)
- commands[command[:command]] = command
- end
-
-
- def self.run(cmd, arguments=[])
- object, method = prepare_run(cmd, arguments.dup)
- object.send(method)
- rescue CommandFailed => e
- error e.message
- rescue OptionParser::ParseError
- commands[cmd] ? run("help", [cmd]) : run("help")
- end
-
- def self.error(message)
- $stderr.puts(message)
- exit(1)
- end
- end
-end
@@ -1,41 +0,0 @@
-class Apiary::Command::Base
-
- attr_reader :args
- attr_reader :options
-
- def initialize(args=[], options={})
- @args = args
- @options = options
- end
-
- def self.namespace
- self.to_s.split("::").last.downcase
- end
-
- attr_reader :args
- attr_reader :options
-
- def self.method_added(method)
- return if self == Apiary::Command::Base
- return if private_method_defined?(method)
- return if protected_method_defined?(method)
-
- # help = extract_help_from_caller(caller.first)
- resolved_method = (method.to_s == "index") ? nil : method.to_s
- command = [ self.namespace, resolved_method ].compact.join(":")
- # banner = extract_banner(help) || command
-
- Apiary::Command.register_command(
- :klass => self,
- :method => method,
- :namespace => self.namespace,
- :command => command
- # :banner => banner.strip,
- # :help => help.join("\n"),
- # :summary => extract_summary(help),
- # :description => extract_description(help),
- # :options => extract_options(help)
- )
- end
-
-end
@@ -1,27 +1,103 @@
-require "apiary/commands/base"
+# encoding: utf-8
+
+# Usage:
+# apiary preview
+# apiary preview my_apib_file.apib
+# apiary preview [my_apib_file.apib] --api_host=api.apiary.io
+# apiary preview [my_apib_file.apib] --browser=Safari
+# apiary preview [my_apib_file.apib] --server
+# apiary preview [my_apib_file.apib] --server --port=8010
# Display preview of local blueprint file
-#
-class Apiary::Command::Preview < Apiary::Command::Base
- # preview
- #
- # Launch web browser and display preview of local blueprint file
- #
- def index
+require "rest_client"
+
+Task.new(:preview) do |task|
+ task.description = "Display preview of local blueprint file"
- api_server = ENV['APIARY_API_HOST'] || "api.apiary.io"
- require 'launchy'
- require 'rest_client'
+ # Configuration.
+ task.config[:apib_path] = nil
+ task.config[:api_host] = "api.apiary.io"
+ task.config[:headers] = {accept: "text/html", content_type: "text/plain"}
+ task.config[:browser] = "Google Chrome"
+ task.config[:port] = 8080
- headers = {:accept => "text/html",:content_type => "text/plain"}
- response = RestClient.post "https://#{api_server}/blueprint/generate", IO.read('apiary.apib'), headers
+ # Singleton methods.
+ def validate_apib_file(apib_file)
+ unless File.exist?(apib_file)
+ abort "Apiary definition file hasn't been found: #{apib_file.inspect}"
+ end
+ end
- aFile = File.new("/tmp/apiarypreview.html", "w")
- aFile.write(response)
- aFile.close
+ def default_apib_path
+ self.config[:apib_path] || "#{File.basename(Dir.pwd)}.apib"
+ end
- Launchy.open("file:///tmp/apiarypreview.html")
+ def browser(options)
+ options[:browser] || self.config[:browser]
end
-end
+ def api_host(options)
+ options[:api_host] || self.config[:api_host]
+ end
+
+ def port(options)
+ options[:port] || config[:port]
+ end
+
+ def rack_app(&block)
+ Rack::Builder.new do
+ run lambda { |env| [200, Hash.new, [block.call]] }
+ end
+ end
+
+ def run_server(apib_path, options)
+ require "rack"
+
+ port = self.port(options)
+
+ app = self.rack_app do
+ host = self.api_host(options)
+ self.query_apiary(host, apib_path)
+ end
+
+ Rack::Server.start(Port: port, app: app)
+ end
+
+ def preview_path(apib_path)
+ basename = File.basename(apib_path)
+ "/tmp/#{basename}-preview.html"
+ end
+
+ def query_apiary(host, apib_path)
+ url = "https://#{host}/blueprint/generate"
+ data = File.read(apib_path)
+ RestClient.post(url, data, self.config[:headers])
+ end
+
+ def open_generated_page(path, options)
+ sh "open -a '#{self.browser(options)}' '#{path}'"
+ end
+
+ # TODO: Support non OS X systems again. Could be done
+ # through launchy or similar projects, but launchy seemed
+ # to be tad buggy to me (ignored application I wanted to use),
+ # so for now it's done through the open command.
+ def generate_static(apib_path, options)
+ File.open(self.preview_path(apib_path), "w") do |file|
+ file.write(self.query_apiary(self.api_host(options), apib_path))
+ self.open_generated_page(file.path, options)
+ end
+ end
+
+ # The actual definition.
+ task.define do |apib_path = default_apib_path, options|
+ self.validate_apib_file(apib_path)
+
+ if options[:server]
+ self.run_server(apib_path, options)
+ else
+ self.generate_static(apib_path, options)
+ end
+ end
+end
View
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
module Apiary
- VERSION = "0.0.1"
-end
+ VERSION ||= "0.0.1"
+end

0 comments on commit 98712f2

Please sign in to comment.