Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Spec create #208

Merged
merged 5 commits into from

3 participants

@fabiopelosin

Changes:

  • added semanting versioning notice
  • warning if a spec description or summary does not ends with a dot
  • requires octokit gem
  • added awesome-print development gem
  • removed appledoc options from spec template
  • removed range attribute for license from the spec template
  • added warning for summary and descriptions not ending with a dot.
  • changed default podspec version to 0.0.1
  • divided template in required and optional sections

It creates stuff like JBDeviceOwner.podspec.

If is not able to find a suitable tag it presents:

img

fabiopelosin added some commits
@fabiopelosin fabiopelosin Draft for spec create from GitHub 368b708
@fabiopelosin fabiopelosin Merge branch 'master' into spec-create
* master: (24 commits)
  [fix] small typo
  [list] spec update
  [presenter] present output to per set so it doesn't wait for all the sets to be ready on lenghty operations
  [presenter] fix for spec
  [pod-list] added pod authors
  [statistics] Switch to GitHub v3 api
  [pod-list] removed accidentally commited file
  [pod-list] Presenter now just renders and doesn't puts text directly + related minor changes
  [pod-list] Possibility to use statistics without cache file
  [fixed] specs
  [pod-list] tweaks and clean up
  [pod-spec] Warning for github repos not starting with https [#204]
  [pod-list] introduced Pod::Command::Presenter::CocoaPod class that encapsulates pod presentation logic
  Added --update option to pod list command
  [pod-list] increased github cache validity to 24h
  [pod-list] caching for statistics & refactoring
  [pod-list] small fixes
  [pod-list] new class Pod::Specification::Statistics
  [cleanup] Pod::Command::Presenter
  [refactor] moved spec_present module to presenter class
  ...

Conflicts:
	lib/cocoapods/command/spec.rb
0ea0f7e
@fabiopelosin fabiopelosin GitHub support for pod spec create
- added semanting versioning notice
- warning if a spec description or summary does not ends with a dot
- requires octokit gem
- added awesome-print development gem
- removed appledoc options from spec template
- removed range attribute for license from the spec template
20613c1
@fabiopelosin fabiopelosin Fixed spec and other minor fixes for pod spec create 1997d9b
@fabiopelosin fabiopelosin Added magic comment for utf-8 encoding to spec.rb 6c304ff
@alloy
Owner

Awesome stuff!

@fabiopelosin fabiopelosin merged commit 2a21c65 into master
@alloy alloy commented on the diff
lib/cocoapods/command/spec.rb
((164 lines not shown))
unless warnings.empty?
puts "\n[!] The #{spec.name} specification raised the following warnings".yellow
warnings.each { |warn| puts ' - '+ warn }
end
puts
end
+
+ def suggest_tag_and_version(tags)
+ versions_tags = {}
+ tags.each do |tag|
+ clean_tag = tag.gsub(/^v(er)? ?/,'')
+ versions_tags[Gem::Version.new(clean_tag)] = tag if Gem::Version.correct?(clean_tag)
+ end
+ version = versions_tags.keys.sort.last || '0.0.1'
+ tag = version == '0.0.1' ? 'HEAD' : versions_tags[version]
@alloy Owner
alloy added a note

Can we default to the last commit hash here instead of ‘HEAD’?

@fabiopelosin Owner

It should not be a problem.

@fabiopelosin Owner

Ok, it should be done... not sure what happend in Travis though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@yas375

@irrationalfab some tests failed with ruby 1.9.3 after this merge(( https://secure.travis-ci.org/#!/CocoaPods/CocoaPods/builds/1104106

@fabiopelosin

ohh... thanks @yas375... It looks like I forgot some debug strings. I'll take a look at it.

@fabiopelosin

Actually this is the rss branch that I updated to show some code and discuss it, I was aware that it was broken. Master is passing after the merge. Thanks for telling anyway... I keep breaking things for the sake of speed :-)

@yas375

yes, I didn't notice that it's not in master branch) sorry)

@jzapater jzapater referenced this pull request from a commit in jzapater/CocoaPods
@markrickert markrickert Added DCRoundSwitch. Addresses issue #208 f989e7e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 13, 2012
  1. @fabiopelosin
  2. @fabiopelosin

    Merge branch 'master' into spec-create

    fabiopelosin authored
    * master: (24 commits)
      [fix] small typo
      [list] spec update
      [presenter] present output to per set so it doesn't wait for all the sets to be ready on lenghty operations
      [presenter] fix for spec
      [pod-list] added pod authors
      [statistics] Switch to GitHub v3 api
      [pod-list] removed accidentally commited file
      [pod-list] Presenter now just renders and doesn't puts text directly + related minor changes
      [pod-list] Possibility to use statistics without cache file
      [fixed] specs
      [pod-list] tweaks and clean up
      [pod-spec] Warning for github repos not starting with https [#204]
      [pod-list] introduced Pod::Command::Presenter::CocoaPod class that encapsulates pod presentation logic
      Added --update option to pod list command
      [pod-list] increased github cache validity to 24h
      [pod-list] caching for statistics & refactoring
      [pod-list] small fixes
      [pod-list] new class Pod::Specification::Statistics
      [cleanup] Pod::Command::Presenter
      [refactor] moved spec_present module to presenter class
      ...
    
    Conflicts:
    	lib/cocoapods/command/spec.rb
Commits on Apr 14, 2012
  1. @fabiopelosin

    GitHub support for pod spec create

    fabiopelosin authored
    - added semanting versioning notice
    - warning if a spec description or summary does not ends with a dot
    - requires octokit gem
    - added awesome-print development gem
    - removed appledoc options from spec template
    - removed range attribute for license from the spec template
  2. @fabiopelosin
  3. @fabiopelosin
This page is out of date. Refresh to see the latest.
View
3  Gemfile
@@ -3,6 +3,8 @@ source "http://rubygems.org"
gem "open4"
gem "colored"
gem "escape"
+gem "json"
+gem "octokit"
group :development do
gem "xcodeproj", :git => "git://github.com/CocoaPods/Xcodeproj.git"
@@ -14,4 +16,5 @@ group :development do
gem "rb-fsevent"
gem "vcr"
gem "webmock"
+ gem "awesome_print"
end
View
21 Gemfile.lock
@@ -8,10 +8,19 @@ 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)
+ faraday (0.7.6)
+ addressable (~> 2.2)
+ multipart-post (~> 1.1)
+ rack (~> 1.1)
+ faraday_middleware (0.8.6)
+ faraday (>= 0.7.4, < 0.9)
+ hashie (1.2.0)
+ json (1.6.6)
kicker (2.5.0)
rb-fsevent
metaclass (0.0.1)
@@ -19,7 +28,16 @@ GEM
metaclass (~> 0.0.1)
mocha-on-bacon (0.2.0)
mocha (>= 0.9.8)
+ multi_json (1.1.0)
+ multipart-post (1.1.5)
+ octokit (1.0.1)
+ addressable (~> 2.2)
+ faraday (~> 0.7)
+ faraday_middleware (~> 0.8)
+ hashie (~> 1.2)
+ multi_json (~> 1.0)
open4 (1.3.0)
+ rack (1.4.1)
rake (0.9.2.2)
rb-fsevent (0.9.0)
vcr (2.0.0)
@@ -31,11 +49,14 @@ PLATFORMS
ruby
DEPENDENCIES
+ awesome_print
bacon
colored
escape
+ json
kicker
mocha-on-bacon
+ octokit
open4
rake
rb-fsevent
View
357 lib/cocoapods/command/spec.rb
@@ -1,14 +1,23 @@
+# encoding: utf-8
+
+require 'net/https'
+require 'uri'
+require 'octokit'
+require 'json'
+
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,10 +26,10 @@ 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)
+ @action, @name_or_url = args.first(2)
end
def run
@@ -28,154 +37,222 @@ def run
end
def create
- 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}'
-
- # 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
- #
- s.author = { '#{author}' => '#{email}', 'other author' => 'and email address' }
- # If absolutely no email addresses are available, then you can use this form instead.
- #
- # s.author = '#{author}', 'other author'
-
- # 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.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',
- # :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',
- # ]
- }
-
- # 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 ...'
- }
-
- # 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 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}'
-
- # 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
-
- # If you need to specify any other build settings, add them to the
- # xcconfig hash.
- #
- # s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
-
- # 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 }
+ if repo_id = @name_or_url[/github.com\/([^\/]*\/[^\/]*).*/, 1]
+ data = github_data_for_template(repo_id)
+ puts semantic_versioning_notice(repo_id, data[:name]) if data[:tag] == 'HEAD'
+ else
+ data = default_data_for_template(@name_or_url)
+ end
+ spec = spec_template(data)
+ (Pathname.pwd + "#{data[:name]}.podspec").open('w') { |f| f << spec }
+ puts "\nSpecification created at #{data[:name]}.podspec\n".green
end
def lint
- file = @name ? Pathname.new(@name) : Pathname.pwd.glob('*.podspec').first
+ name = @name_or_url
+ 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 start with https://github.com" if spec.source[:git] =~ /git:\/\/github\.com/
-
-
+ 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
+
+ def suggest_tag_and_version(tags)
+ versions_tags = {}
+ tags.each do |tag|
+ clean_tag = tag.gsub(/^v(er)? ?/,'')
+ versions_tags[Gem::Version.new(clean_tag)] = tag if Gem::Version.correct?(clean_tag)
+ end
+ version = versions_tags.keys.sort.last || '0.0.1'
+ tag = version == '0.0.1' ? 'HEAD' : versions_tags[version]
@alloy Owner
alloy added a note

Can we default to the last commit hash here instead of ‘HEAD’?

@fabiopelosin Owner

It should not be a problem.

@fabiopelosin Owner

Ok, it should be done... not sure what happend in Travis though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ [tag, version.to_s]
+ end
+
+ def github_data_for_template(repo_id)
+ repo = Octokit.repo(repo_id)
+ user = Octokit.user(repo['owner']['login'])
+ tags = Octokit.tags(repo_id).map {|tag| tag.name}
+
+ tag, version = suggest_tag_and_version(tags)
+
+ data = {}
+ data[:name] = repo['name']
+ data[:version] = version
+ data[:summary] = repo['description'].gsub(/["]/, '\"')
+ data[:homepage] = repo['homepage'] != "" ? repo['homepage'] : repo['html_url']
+ data[:author_name] = user['name'] || user['login']
+ data[:author_email] = user['email'] || 'email@address.com'
+ data[:source_url] = repo['clone_url']
+ data[:tag] = tag
+ data
+ end
+
+ def default_data_for_template(name)
+ data = {}
+ data[:name] = name
+ data[:version] = '0.0.1'
+ data[:summary] = "A short description of #{name}."
+ data[:homepage] = "http://EXAMPLE/#{name}"
+ data[:author_name] = `git config --get user.name`.strip
+ data[:author_email] = `git config --get user.email`.strip
+ data[:source_url] = "http://EXAMPLE/#{name}.git"
+ data[:tag] = '0.0.1'
+ data
+ end
+
+ def spec_template(data)
+ return <<-SPEC
+#
+# Be sure to run `pod spec lint #{data[:name]}.podspec' to ensure this is a
+# valid spec.
+#
+# Remove all comments before submitting the spec.
+#
+Pod::Spec.new do |s|
+
+ # ――― REQUIRED VALUES ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+
+ s.name = "#{data[:name]}"
+ s.version = "#{data[:version]}"
+ s.summary = "#{data[:summary]}"
+ s.homepage = "#{data[:homepage]}"
+
+ # 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
+ #
+ s.author = { "#{data[:author_name]}" => "#{data[:author_email]}" }
+ # s.authors = { "#{data[:author_name]}" => "#{data[:author_email]}", "other author" => "and email address" }
+ #
+ # If absolutely no email addresses are available, then you can use this form instead.
+ #
+ # s.author = '#{data[:author_name]}', 'other author'
+
+ # Specify the location from where the source should be retreived.
+ #
+ s.source = { :git => "#{data[:source_url]}", :tag => "#{data[:tag]}" }
+ # s.source = { :svn => 'http://EXAMPLE/#{data[:name]}/tags/1.0.0' }
+ # s.source = { :hg => 'http://EXAMPLE/#{data[:name]}', :revision => '1.0.0' }
+
+ # Specify the license details. Only if no dedicated file is available include
+ # the full text of the license.
+ #
+ s.license = {
+ :type => 'MIT',
+ :file => 'LICENSE',
+ # :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 VALUES ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+
+ s.description = 'An optional longer description of #{data[: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 VALUES ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+
+ # If you need to specify any other build settings, add them to the
+ # xcconfig hash.
+ #
+ # s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
+
+end
+ SPEC
+ end
+
+ def semantic_versioning_notice(repo_id, repo)
+ return <<-EOS
+
+#{'――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
+
+I’ve recently added [#{repo}](https://github.com/CocoaPods/Specs/tree/master/#{repo}) to the [CocoaPods](https://github.com/CocoaPods/CocoaPods) package manager repo.
+
+CocoaPods is a tool for managing dependencies for OSX and iOS Xcode projects and provides a central repository for iOS/OSX libraries. This makes adding libraries to a project and updating them extremely easy and it will help users to resolve dependencies of the libraries they use.
+
+However, #{repo} doesn't have any version tags. I’ve added the current HEAD as version 0.0.1, but a version tag will make dependency resolution much easier.
+
+[Semantic version](http://semver.org) tags (instead of plain commit hashes/revisions) allow for [resolution of cross-dependencies](https://github.com/CocoaPods/Specs/wiki/Cross-dependencies-resolution-example).
+
+In case you didn’t know this yet; you can tag the current HEAD as, for instance, version 1.0.0, like so:
+
+```
+$ git tag -a 1.0.0 -m "Tag release 1.0.0"
+$ git push --tags
+```
+
+#{'――― TEMPLATE END ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
+
+#{'[!] This repo does not appear to have semantic version tags.'.yellow}
+
+After commiting the specification, consider opening a ticket with the template displayed above:
+ - link: https://github.com/#{repo_id}/issues/new
+ - title: Please add semantic version tags
+EOS
+ end
end
end
end
View
6 spec/functional/command_spec.rb
@@ -54,11 +54,11 @@ def command.url; SpecHelper.fixture('spec-repos/master'); end
spec = Pod::Specification.from_file(path)
spec.name.should == 'Bananas'
spec.license.should == { :type => "MIT", :file => "LICENSE" }
- spec.version.should == Pod::Version.new('1.0.0')
+ spec.version.should == Pod::Version.new('0.0.1')
spec.summary.should == 'A short description of Bananas.'
spec.homepage.should == 'http://EXAMPLE/Bananas'
- spec.authors.should == { `git config --get user.name`.strip => `git config --get user.email`.strip, "other author" => "and email address" }
- spec.source.should == { :git => 'http://EXAMPLE/Bananas.git', :tag => '1.0.0' }
+ spec.authors.should == { `git config --get user.name`.strip => `git config --get user.email`.strip}
+ spec.source.should == { :git => 'http://EXAMPLE/Bananas.git', :tag => '0.0.1' }
spec.description.should == 'An optional longer description of Bananas.'
spec.source_files.should == ['Classes', 'Classes/**/*.{h,m}']
end
Something went wrong with that request. Please try again.