Skip to content
Browse files

Draft for spec create from GitHub

  • Loading branch information...
1 parent 421ddf8 commit 368b7086412e0d4a15ceb5bc238124d1441dcb0c @fabiopelosin fabiopelosin committed Apr 13, 2012
Showing with 215 additions and 36 deletions.
  1. +2 −0 Gemfile
  2. +4 −0 Gemfile.lock
  3. +209 −36 lib/cocoapods/command/spec.rb
View
2 Gemfile
@@ -3,6 +3,7 @@ source "http://rubygems.org"
gem "open4"
gem "colored"
gem "escape"
+gem "json"
group :development do
gem "xcodeproj", :git => "git://github.com/CocoaPods/Xcodeproj.git"
@@ -14,4 +15,5 @@ group :development do
gem "rb-fsevent"
gem "vcr"
gem "webmock"
+ gem "awesome_print"
end
View
4 Gemfile.lock
@@ -8,10 +8,12 @@ GEM
remote: http://rubygems.org/
specs:
addressable (2.2.7)
+ awesome_print (1.0.2)
bacon (1.1.0)
colored (1.2)
crack (0.3.1)
escape (0.0.4)
+ json (1.6.6)
kicker (2.5.0)
rb-fsevent
metaclass (0.0.1)
@@ -31,9 +33,11 @@ PLATFORMS
ruby
DEPENDENCIES
+ awesome_print
bacon
colored
escape
+ json
kicker
mocha-on-bacon
open4
View
245 lib/cocoapods/command/spec.rb
@@ -1,14 +1,21 @@
+require 'net/https'
+require 'uri'
+require 'json'
+require 'awesome_print'
+
module Pod
class Command
class Spec < Command
def self.banner
-%{Managing PodSpec files:
+ %{Managing PodSpec files:
- $ pod spec create NAME
+ $ pod spec create [NAME]
+ $ pod spec create [https://github.com/user/repo]
Creates a PodSpec, in the current working dir, called `NAME.podspec'.
+ If a GitHub url is passed the spec is prepopulated.
- $ pod spec lint NAME.podspec
+ $ pod spec lint [NAME.podspec]
Validates `NAME.podspec'. In case `NAME.podspec' is omitted, it defaults
to `*.podspec' in the current working dir.}
@@ -17,7 +24,7 @@ def self.banner
def initialize(argv)
args = argv.arguments
unless (args[0] == 'create' && args.size == 2) ||
- (args[0] == 'lint' && args.size <= 2)
+ (args[0] == 'lint' && args.size <= 2)
super
end
@action, @name = args.first(2)
@@ -28,8 +35,70 @@ def run
end
def create
- author = `git config --get user.name`.strip
- email = `git config --get user.email`.strip
+ spec = is_git_hub ? github_spec_doc : spec_doc
+ (Pathname.pwd + "#{@name}.podspec").open('w') { |f| f << spec }
+ end
+
+ def lint
+ file = @name ? Pathname.new(@name) : Pathname.pwd.glob('*.podspec').first
+ spec = Specification.from_file(file)
+ puts "\nThe #{spec.name} specification contains all the required attributes.".green if spec.validate!
+
+ warnings = []
+ warnings << 'The name of the specificaiton should match the name of the podspec file' if spec.name + '.podspec' != @name
+ warnings << 'Missing license[:type]' unless spec.license && spec.license[:type]
+ warnings << 'Missing license[:file] or [:text]' unless spec.license && (spec.license[:file] || spec.license[:text])
+ warnings << "Github repositories should end in `.git'" if spec.source[:git] =~ /github.com/ && spec.source[:git] !~ /.*\.git/
+ warnings << "Github repositories should end in `.git'" if spec.source[:git] =~ /github.com/ && spec.source[:git] !~ /.*\.git/
+ warnings << "The description should end with a dot" if spec.description && spec.description !~ /.*\./
+ warnings << "The summary should end with a dot" if spec.summary !~ /.*\./
+ unless warnings.empty?
+ puts "\n[!] The #{spec.name} specification raised the following warnings".yellow
+ warnings.each { |warn| puts ' - '+ warn }
+ end
+ puts
+ end
+
+ private
+
+ def is_git_hub
+ @name =~ /https:\/\/github.com\/.*\/.*/
+ end
+
+ def find_github_info
+ full, user, repo = *(@name.match /https:\/\/github.com\/(.*)\/(.*)/).to_a
+ user_data = fetch_request("users/#{user}")
+ repo_data = fetch_request("repos/#{user}/#{repo}")
+ tags_data = fetch_request("repos/#{user}/#{repo}/tags")
+ [user_data, repo_data, tags_data]
+ end
+
+ def fetch_request(request_url)
+ uri = URI.parse("https://api.github.com/#{request_url}")
+ http = Net::HTTP.new(uri.host, uri.port)
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ request = Net::HTTP::Get.new(uri.request_uri)
+ response = http.request(request)
+ JSON.parse(response.body) if response.is_a?(Net::HTTPSuccess)
+ end
+
+ def find_suggested_tag(tags_data)
+ tags = tags_data.map {|hash| hash["name"] }
+ versions = tags.reject {|t| t !~ /[0-9]+\.[0-9]+\.?[0-9]*/ }
+ versions.sort.last || '0.0.1'
+ end
+
+ def version_from_tag(tag)
+ tag.match /[0-9]+\.[0-9]+\.?[0-9]*/
+ end
+
+ def github_spec_doc
+ user_data, repo_data, tags_data = find_github_info
+ tag = find_suggested_tag(tags_data)
+ version = version_from_tag(tag)
+
+ @name = repo_data["name"]
spec = <<-SPEC.gsub(/^ /, '')
#
# Be sure to run `pod spec lint #{@name}.podspec' to ensure this is a
@@ -38,10 +107,136 @@ def create
# Remove all comments before submitting the spec.
#
Pod::Spec.new do |s|
+
+ # ――― REQUIRED ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
+
s.name = '#{@name}'
+ s.version = '#{version}'
+ s.summary = '#{repo_data["description"].gsub(/[']/, '\\\\\'')}'
+ s.homepage = '#{repo_data["homepage"] != "" ? repo_data["homepage"] : repo_data["html_url"]}'
+ s.source = { :git => '#{repo_data["clone_url"]}', :tag => '#{tag}' }
+ s.author = { '#{user_data["name"]}' => '#{user_data["email"]}' }
+ # s.author = { '#{user_data["name"]}' => '#{user_data["email"]}', 'other author' => 'and email address' }
+
+ # Specify the license of the pod.
+ # :type The type of the license.
+ # :file The file containing the license of the pod.
+ # :range If a dedicated license file is not available specify a file
+ # that contains the license and the range of the lines
+ # containing the license.
+ # :text If the license is not available in any of the files it should be
+ # included here.
+ s.license = {
+ :type => 'MIT',
+ :file => 'LICENSE',
+ # :range => 1..15,
+ # :text => 'Permission is hereby granted ...'
+ }
+
+ # A list of file patterns which select the source files that should be
+ # added to the Pods project. If the pattern is a directory then the
+ # path will automatically have '*.{h,m,mm,c,cpp}' appended.
+ #
+ # Alternatively, you can use the FileList class for even more control
+ # over the selected files.
+ # (See http://rake.rubyforge.org/classes/Rake/FileList.html.)
+ #
+ s.source_files = 'Classes', 'Classes/**/*.{h,m}'
+
+ # ――― OPTIONAL ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
+
+ s.description = 'An optional longer description of #{@name}.'
+
+ # If this Pod runs only on iOS or OS X, then specify that with one of
+ # these, or none if it runs on both platforms.
+ #
+ # s.platform = :ios
+ # s.platform = :osx
+
+ # A list of resources included with the Pod. These are copied into the
+ # target bundle with a build phase script.
+ #
+ # Also allows the use of the FileList class like `source_files does.
+ #
+ # s.resource = "icon.png"
+ # s.resources = "Resources/*.png"
+
+ # A list of paths to remove after installing the Pod without the
+ # `--no-clean' option. These can be examples, docs, and any other type
+ # of files that are not needed to build the Pod.
+ #
+ # *NOTE*: Never remove license and README files.
+ #
+ # Also allows the use of the FileList class like `source_files does.
+ #
+ # s.clean_path = "examples"
+ # s.clean_paths = "examples", "doc"
+
+ # Specify a list of frameworks that the application needs to link
+ # against for this Pod to work.
+ #
+ # s.framework = 'SomeFramework'
+ # s.frameworks = 'SomeFramework', 'AnotherFramework'
+
+ # Specify a list of libraries that the application needs to link
+ # against for this Pod to work.
+ #
+ # s.library = 'iconv'
+ # s.libraries = 'iconv', 'xml2'
+
+ # If this Pod uses ARC, specify it like so.
+ #
+ # s.requires_arc = true
+
+ # Finally, specify any Pods that this Pod depends on.
+ #
+ # s.dependency 'JSONKit', '~> 1.4'
+ #
+ # ――― EXTRA ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
+
+ # If you need to specify any other build settings, add them to the
+ # xcconfig hash.
+ #
+ # s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
+
+ # If available specify the documentation homepage.
+ # :html The online link for the documentation.
+ # :appledoc Ammend the default appledoc options used
+ # by cocoapods if needed.
+ #
+ # s.documentation = {
+ # :html => 'http://EXAMPLE/#{@name}/documentation',
+ # :appledoc => [
+ # '--project-name', '#{@name}',
+ # '--project-company', 'Company Name',
+ # '--docset-copyright', copyright,
+ # '--ignore', 'Common',
+ # '--index-desc', 'readme.markdown',
+ # '--no-keep-undocumented-objects',
+ # '--no-keep-undocumented-members',
+ # ]
+ # }
+
+ end
+ SPEC
+ end
+
+ def spec_doc
+ name = @name
+ author = `git config --get user.name`.strip
+ email = `git config --get user.email`.strip
+ spec = <<-SPEC.gsub(/^ /, '')
+ #
+ # Be sure to run `pod spec lint #{name}.podspec' to ensure this is a
+ # valid spec.
+ #
+ # Remove all comments before submitting the spec.
+ #
+ Pod::Spec.new do |s|
+ s.name = '#{name}'
s.version = '1.0.0'
- s.summary = 'A short description of #{@name}.'
- s.homepage = 'http://EXAMPLE/#{@name}'
+ s.summary = 'A short description of #{name}.'
+ s.homepage = 'http://EXAMPLE/#{name}'
# Specify the authors of the library, with email addresses. You can often find
# the email addresses of the authors by using the SCM log. E.g. $ git log
@@ -53,21 +248,21 @@ def create
# Specify the location from where the source should be retreived.
#
- s.source = { :git => 'http://EXAMPLE/#{@name}.git', :tag => '1.0.0' }
- # s.source = { :svn => 'http://EXAMPLE/#{@name}/tags/1.0.0' }
- # s.source = { :hg => 'http://EXAMPLE/#{@name}', :revision => '1.0.0' }
+ s.source = { :git => 'http://EXAMPLE/#{name}.git', :tag => '1.0.0' }
+ # s.source = { :svn => 'http://EXAMPLE/#{name}/tags/1.0.0' }
+ # s.source = { :hg => 'http://EXAMPLE/#{name}', :revision => '1.0.0' }
- s.description = 'An optional longer description of #{@name}.'
+ s.description = 'An optional longer description of #{name}.'
# If available specify the documentation homepage.
# :html The online link for the documentation.
# :appledoc Ammend the default appledoc options used
# by cocoapods if needed.
#
s.documentation = {
- # :html => 'http://EXAMPLE/#{@name}/documentation',
+ # :html => 'http://EXAMPLE/#{name}/documentation',
# :appledoc => [
- # '--project-name', '#{@name}',
+ # '--project-name', '#{name}',
# '--project-company', 'Company Name',
# '--docset-copyright', copyright,
# '--ignore', 'Common',
@@ -151,29 +346,7 @@ def create
# Finally, specify any Pods that this Pod depends on.
#
# s.dependency 'JSONKit', '~> 1.4'
- end
SPEC
- (Pathname.pwd + "#{@name}.podspec").open('w') { |f| f << spec }
- end
-
- def lint
- file = @name ? Pathname.new(@name) : Pathname.pwd.glob('*.podspec').first
- spec = Specification.from_file(file)
-
- puts "\nThe #{spec.name} specification contains all the required attributes.".green if spec.validate!
-
- warnings = []
- warnings << 'The name of the specificaiton should match the name of the podspec file' if spec.name + '.podspec' != @name
- warnings << 'Missing license[:type]' unless spec.license && spec.license[:type]
- warnings << 'Missing license[:file] or [:text]' unless spec.license && (spec.license[:file] || spec.license[:text])
- warnings << "Github repositories should end in `.git'" if spec.source[:git] =~ /github.com/ && spec.source[:git] !~ /.*\.git/
-
-
- unless warnings.empty?
- puts "\n[!] The #{spec.name} specification raised the following warnings".yellow
- warnings.each { |warn| puts ' - '+ warn }
- end
- puts
end
end
end

0 comments on commit 368b708

Please sign in to comment.
Something went wrong with that request. Please try again.