vendor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.gitignore +12 -0
  2. data/.travis.yml +4 -0
  3. data/Gemfile +8 -0
  4. data/Gemfile.lock +68 -0
  5. data/LICENCE +19 -0
  6. data/Rakefile +11 -0
  7. data/Readme.markdown +109 -0
  8. data/bin/vendor +62 -0
  9. data/lib/vendor/api.rb +49 -0
  10. data/lib/vendor/cli/auth.rb +38 -0
  11. data/lib/vendor/cli.rb +23 -0
  12. data/lib/vendor/config.rb +51 -0
  13. data/lib/vendor/extensions/array.rb +7 -0
  14. data/lib/vendor/extensions/fixnum.rb +7 -0
  15. data/lib/vendor/extensions/hash.rb +10 -0
  16. data/lib/vendor/extensions/string.rb +11 -0
  17. data/lib/vendor/plist.rb +255 -0
  18. data/lib/vendor/vendor_spec/builder.rb +83 -0
  19. data/lib/vendor/vendor_spec/dsl.rb +39 -0
  20. data/lib/vendor/vendor_spec/loader.rb +23 -0
  21. data/lib/vendor/version.rb +5 -0
  22. data/lib/vendor/xcode/object.rb +102 -0
  23. data/lib/vendor/xcode/objects/pbx_build_file.rb +9 -0
  24. data/lib/vendor/xcode/objects/pbx_container_item_proxy.rb +8 -0
  25. data/lib/vendor/xcode/objects/pbx_file_reference.rb +21 -0
  26. data/lib/vendor/xcode/objects/pbx_frameworks_build_phase.rb +9 -0
  27. data/lib/vendor/xcode/objects/pbx_group.rb +13 -0
  28. data/lib/vendor/xcode/objects/pbx_native_target.rb +11 -0
  29. data/lib/vendor/xcode/objects/pbx_project.rb +12 -0
  30. data/lib/vendor/xcode/objects/pbx_resources_build_phase.rb +7 -0
  31. data/lib/vendor/xcode/objects/pbx_shell_script_build_phase.rb +7 -0
  32. data/lib/vendor/xcode/objects/pbx_sources_build_phase.rb +9 -0
  33. data/lib/vendor/xcode/objects/pbx_target_dependency.rb +7 -0
  34. data/lib/vendor/xcode/objects/pbx_variant_group.rb +7 -0
  35. data/lib/vendor/xcode/objects/xc_build_configuration.rb +7 -0
  36. data/lib/vendor/xcode/objects/xc_configuration_list.rb +9 -0
  37. data/lib/vendor/xcode/project.rb +130 -0
  38. data/lib/vendor.rb +33 -0
  39. data/spec/spec_helper.rb +17 -0
  40. data/spec/support/api_stubs.rb +12 -0
  41. data/spec/support/resources/files/SecondViewController.h +13 -0
  42. data/spec/support/resources/files/SecondViewController.m +43 -0
  43. data/spec/support/resources/projects/ProjectWithSpecs/ProjectWithSpecs.xcodeproj/project.pbxproj +320 -0
  44. data/spec/support/resources/projects/TabBarWithUnitTests/TabBarWithUnitTests.xcodeproj/project.pbxproj +473 -0
  45. data/spec/support/resources/vendors/DKBenchmark/DKBenchmark.h +18 -0
  46. data/spec/support/resources/vendors/DKBenchmark/DKBenchmark.m +73 -0
  47. data/spec/support/resources/vendors/DKBenchmark/DKBenchmark.vendorspec +11 -0
  48. data/spec/support/resources/vendors/DKBenchmarkUnsafe/DKBenchmark.h +18 -0
  49. data/spec/support/resources/vendors/DKBenchmarkUnsafe/DKBenchmark.m +73 -0
  50. data/spec/support/resources/vendors/DKBenchmarkUnsafe/DKBenchmark.vendorspec +11 -0
  51. data/spec/support/temp_project.rb +21 -0
  52. data/spec/vendor/api_spec.rb +25 -0
  53. data/spec/vendor/cli/auth_spec.rb +54 -0
  54. data/spec/vendor/config_spec.rb +62 -0
  55. data/spec/vendor/vendor_spec/builder_spec.rb +86 -0
  56. data/spec/vendor/vendor_spec/dsl_spec.rb +67 -0
  57. data/spec/vendor/vendor_spec/loader_spec.rb +41 -0
  58. data/spec/vendor/xcode/object_spec.rb +76 -0
  59. data/spec/vendor/xcode/objects/pbx_project_spec.rb +26 -0
  60. data/spec/vendor/xcode/project_spec.rb +211 -0
  61. data/vendor.gemspec +33 -0
  62. metadata +234 -0
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ build
2
+ *.pbxuser
3
+ *.mode1v3
4
+ .DS_Store
5
+ pkg
6
+ *.xcworkspace
7
+ xcuserdata
8
+ contents.xcworkspacedata
9
+ *.gem
10
+ tmp
11
+ log
12
+ *.vendor
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - ree
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in vendor.gemspec
4
+ gemspec
5
+
6
+ # For testing
7
+ gem 'ruby-debug', :platforms => :ruby_18
8
+ gem 'ruby-debug19', :platforms => :ruby_19
data/Gemfile.lock ADDED
@@ -0,0 +1,68 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ vendor (0.0.1)
5
+ colorize
6
+ json
7
+ rake
8
+ rest-client
9
+ ripl
10
+ rubyzip
11
+ thor
12
+
13
+ GEM
14
+ remote: http://rubygems.org/
15
+ specs:
16
+ archive-tar-minitar (0.5.2)
17
+ bond (0.4.1)
18
+ colorize (0.5.8)
19
+ columnize (0.3.4)
20
+ diff-lcs (1.1.2)
21
+ fakeweb (1.3.0)
22
+ json (1.5.4)
23
+ linecache (0.46)
24
+ rbx-require-relative (> 0.0.4)
25
+ linecache19 (0.5.12)
26
+ ruby_core_source (>= 0.1.4)
27
+ mime-types (1.16)
28
+ rake (0.9.2)
29
+ rbx-require-relative (0.0.5)
30
+ rest-client (1.6.3)
31
+ mime-types (>= 1.16)
32
+ ripl (0.5.1)
33
+ bond (~> 0.4.0)
34
+ rspec (2.6.0)
35
+ rspec-core (~> 2.6.0)
36
+ rspec-expectations (~> 2.6.0)
37
+ rspec-mocks (~> 2.6.0)
38
+ rspec-core (2.6.4)
39
+ rspec-expectations (2.6.0)
40
+ diff-lcs (~> 1.1.2)
41
+ rspec-mocks (2.6.0)
42
+ ruby-debug (0.10.4)
43
+ columnize (>= 0.1)
44
+ ruby-debug-base (~> 0.10.4.0)
45
+ ruby-debug-base (0.10.4)
46
+ linecache (>= 0.3)
47
+ ruby-debug-base19 (0.11.25)
48
+ columnize (>= 0.3.1)
49
+ linecache19 (>= 0.5.11)
50
+ ruby_core_source (>= 0.1.4)
51
+ ruby-debug19 (0.11.6)
52
+ columnize (>= 0.3.1)
53
+ linecache19 (>= 0.5.11)
54
+ ruby-debug-base19 (>= 0.11.19)
55
+ ruby_core_source (0.1.5)
56
+ archive-tar-minitar (>= 0.5.2)
57
+ rubyzip (0.9.4)
58
+ thor (0.14.6)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ fakeweb
65
+ rspec
66
+ ruby-debug
67
+ ruby-debug19
68
+ vendor!
data/LICENCE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Keith Pitt
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake'
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = 'spec/**/*_spec.rb'
8
+ spec.rspec_opts = ['--backtrace']
9
+ end
10
+
11
+ task :default => :spec
data/Readme.markdown ADDED
@@ -0,0 +1,109 @@
1
+ # Vendor – an iOS library management system
2
+
3
+ Vendor makes the process of using and managing libraries in iOS easy. Vendor is modeled after [Bundler](https://github.com/carlhuda/bundler). Vendor streamlines the installation and update process for dependent libraries. It also tracks versions and manages dependencies between libraries.
4
+
5
+ ## Installation
6
+
7
+ If you have [RVM](http://beginrescueend.com/rvm/install/) installed, simply run:
8
+
9
+ ```bash
10
+ $ gem install vendor
11
+ ```
12
+
13
+ Otherwise, you'll need to:
14
+
15
+ ```bash
16
+ $ sudo gem install vendor
17
+ ```
18
+
19
+ ## Installing Libraries
20
+
21
+ ### Step 1: Specify dependencies
22
+
23
+ Specify your dependencies in a Vendors file in your project's root.
24
+
25
+ ```ruby
26
+ source "https://vendorage.com"
27
+
28
+ lib "DKBenchmark"
29
+ lib "DKPredicateBuilder"
30
+ lib "JSONKit", :git => "https://github.com/johnezang/JSONKit.git"
31
+ ```
32
+
33
+ You can do this by either creating a `Vendorfile` manually, or by running:
34
+
35
+ ```bash
36
+ $ vendor init
37
+ ```
38
+
39
+ ### Step 2: Install dependencies
40
+
41
+ ```bash
42
+ $ vendor install
43
+ $ git add Vendors.lock
44
+ ```
45
+
46
+ Installing a vendor library gets the latest version of the code, and adds them directly to your project in a "Vendor" group.
47
+
48
+ As part of the installation process the required frameworks are added aswell as any compiler/linker flags. The installed version of the library is captured in the Vendors.lock file.
49
+
50
+ ### Step 3: Restart XCode
51
+
52
+ XCode sometimes goes bonkers if you try and make a modification to it while its running. It's easier just to either `vendor install` while its not running, or restart right after installing libraries.
53
+
54
+ ## Creating Libraries
55
+
56
+ ```bash
57
+ $ vendor library create
58
+ ```
59
+
60
+ Will create a `.vendorspec` file that looks something like this:
61
+
62
+ ```ruby
63
+ name "DKBenchmark"
64
+ version "0.1"
65
+
66
+ authors "keithpitt"
67
+ email "me@keithpitt.com"
68
+ homepage "http://www.keithpitt.com"
69
+ description "Easy benchmarking in Objective-C using blocks"
70
+
71
+ github "https://github.com/keithpitt/DKBenchmark"
72
+
73
+ files [ "DKBenchmark.h", "DKBenchmark.m" ]
74
+ ```
75
+
76
+ Change what you need to match your project, and to push the library to
77
+ [http://vendorage.com](http://vendorage.com), just run the following:
78
+
79
+ ```bash
80
+ $ vendor library publish
81
+ ```
82
+
83
+ ## History
84
+
85
+ Vendor was inspired by a blog post entitled [Vendor – Bringing Bundler to iOS](http://engineering.gomiso.com/2011/08/08/vendor-the-best-way-to-manage-ios-libraries/). I had started working on Vendor after they started doing it themselves. Their repo can be found here [https://github.com/bazaarlabs/vendor](https://github.com/bazaarlabs/vendor). I took many of the ideas (and parts of this Readme) from their code.
86
+
87
+ After reading [this blog post](http://www.germanforblack.com/articles/false-fears) by Ben Schwarz, I decided just to start something.
88
+
89
+ > There is no value in hoarding away your treasures. If you’re genuinely creating things that you want to share with other people, then put them out there, fail, make mistakes and poor judgements... but for gods sake, do something!
90
+
91
+ So I've probably made mistake or two. But thats OK, because at least I have *something* working. If you see something you think could be done better, feel free to fork and submit a pull request :)
92
+
93
+ ## Contributers
94
+
95
+ * [Keith Pitt](http://www.keithpitt.com)
96
+ * [Tim Lee](http://twitter.com/#!/timothy1ee)
97
+ * [Jari Bakken](https://github.com/jarib/plist/blob/master/lib/plist/ascii.rb)
98
+
99
+ ## Note on Patches/Pull Requests
100
+
101
+ 1. Fork the project.
102
+ 2. Make your feature addition or bug fix.
103
+ 3. Add tests for it. This is important so I don't break it in a future version unintentionally.
104
+ 4. Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
105
+ 5. Send me a pull request. Bonus points for topic branches.
106
+
107
+ ## Copyright
108
+
109
+ Copyright (c) 2011 Keith Pitt. See LICENSE for details.
data/bin/vendor ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+
4
+ require "thor"
5
+ require "ripl"
6
+
7
+ $:.push File.expand_path(File.join(__FILE__, "..", "..", "lib"))
8
+
9
+ require "vendor"
10
+ require "vendor/cli"
11
+
12
+ class Vendor::App < Thor
13
+
14
+ desc "auth", "Login to your vendorage.com account"
15
+ def auth
16
+ begin
17
+ Vendor::CLI::Auth.with_api_key do |api_key|
18
+ puts "Successfully authenticated".green
19
+ end
20
+ rescue Vendor::API::Error => e
21
+ puts "Error: #{e.message}".red
22
+ end
23
+ end
24
+
25
+ desc "build MANIFEST_FILE", "Build a vendor package from a vendorspec file"
26
+ def build(file)
27
+ builder = Vendor::Manifest::Builder.new(File.expand_path(file))
28
+ if builder.build
29
+ puts "Successfully built Vendor".green
30
+ puts "Name: #{builder.name}"
31
+ puts "Version: #{builder.version}"
32
+ puts "File: #{builder.filename}"
33
+ end
34
+ end
35
+
36
+ desc "publish VENDOR_FILE", "Publish a vendor package to vendorage.com"
37
+ def publish(file)
38
+ begin
39
+ Vendor::CLI::Auth.with_api_key do |api_key|
40
+ url = Vendor::API.publish :file => File.expand_path(file), :api_key => api_key
41
+ puts "Successfully published to #{url}".green
42
+ end
43
+ rescue Vendor::API::Error => e
44
+ puts "Error: #{e.message}".red
45
+ end
46
+ end
47
+
48
+ desc "console", "Load an interactive shell with the Vendor classes loaded"
49
+ def console
50
+ # Need to clear the arguments otherwise they are passed through to RIPL
51
+ ARGV.clear
52
+ Ripl.start :binding => Vendor::CLI.instance_eval{ binding }
53
+ end
54
+
55
+ # Exit with 1 if thor encounters an error (such as command missing)
56
+ def self.exit_on_failure?
57
+ true
58
+ end
59
+
60
+ end
61
+
62
+ Vendor::App.start
data/lib/vendor/api.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'rest_client'
2
+
3
+ module Vendor
4
+ module API
5
+
6
+ extend self
7
+
8
+ class Error < StandardError; end
9
+
10
+ def api_key(username, password)
11
+ perform do
12
+ response = resource(username, password)["users/#{username}/api_key.json"].get
13
+ JSON.parse(response.body)["api_key"]
14
+ end
15
+ end
16
+
17
+ def publish(options)
18
+ perform do
19
+ response = resource["vendors.json"].post :version => { :package => File.new(options[:file]) }, :api_key => options[:api_key]
20
+ body = JSON.parse(response.body)
21
+
22
+ if body["status"] == "ok"
23
+ body["url"]
24
+ else
25
+ raise Error.new(body["message"])
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def perform(&block)
33
+ begin
34
+ yield
35
+ rescue RestClient::Exception => e
36
+ if e.http_code == 401
37
+ raise Error.new("Login or password is incorrect")
38
+ else
39
+ raise Error.new("Could not complete request. Server returned a status code of #{e.http_code}")
40
+ end
41
+ end
42
+ end
43
+
44
+ def resource(user = nil, pass = nil)
45
+ RestClient::Resource.new(ENV["API_URI"] || 'http://vendorage.com', :user => user, :password => pass)
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,38 @@
1
+ module Vendor
2
+ module CLI
3
+
4
+ module Auth
5
+
6
+ extend self
7
+
8
+ def api_key
9
+ Vendor::Config.get(:"credentials.vendorage_api_key")
10
+ end
11
+
12
+ def api_key=(value)
13
+ Vendor::Config.set(:"credentials.vendorage_api_key", value)
14
+ end
15
+
16
+ def fetch_api_key
17
+ puts "Please enter your vendorage.com login and password".yellow
18
+ printf "Login: "
19
+ username = STDIN.gets.chomp.strip
20
+ printf "Password: "
21
+ password = STDIN.gets.chomp.strip
22
+
23
+ Vendor::Config.set(:"credentials.vendorage_api_key", Vendor::API.api_key(username, password))
24
+ end
25
+
26
+ def with_api_key(&block)
27
+ fetch_api_key unless is_authenticated?
28
+ yield api_key if api_key
29
+ end
30
+
31
+ def is_authenticated?
32
+ !api_key.nil?
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ end
data/lib/vendor/cli.rb ADDED
@@ -0,0 +1,23 @@
1
+ require "vendor/cli/auth"
2
+
3
+ module Vendor
4
+
5
+ module CLI
6
+
7
+ # This reload method kinda works. It works if you change/add methods, but if you
8
+ # remove methods from a class, they still seem to hang around. I believe there is
9
+ # a fair amount of magic in rails that lets you call a reload!, but for the save
10
+ # of Vendor development, this will suffice.
11
+ def self.reload!
12
+ begin
13
+ old_verbose, $VERBOSE = $VERBOSE, nil
14
+ $".grep(/\/lib\/vendor/).each {|e| $".delete(e) && require(e) }
15
+ ensure
16
+ $VERBOSE = old_verbose
17
+ end
18
+ "Reloaded!"
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,51 @@
1
+ module Vendor
2
+ module Config
3
+
4
+ require 'fileutils'
5
+ require 'yaml'
6
+
7
+ extend self
8
+
9
+ def directory
10
+ @directory ||= File.expand_path("~/.vendor")
11
+ end
12
+
13
+ def directory=(dir)
14
+ @directory = dir
15
+ end
16
+
17
+ def set(key, value)
18
+ hash[key.to_sym] = value
19
+ save
20
+ value
21
+ end
22
+
23
+ def get(key)
24
+ hash[key.to_sym]
25
+ end
26
+
27
+ def hash
28
+ @hash ||= load_or_create
29
+ end
30
+
31
+ private
32
+
33
+ def config_file
34
+ File.join(directory, "config")
35
+ end
36
+
37
+ def load_or_create
38
+ if File.exist?(config_file)
39
+ YAML.load_file(config_file) || {}
40
+ else
41
+ {}
42
+ end
43
+ end
44
+
45
+ def save
46
+ FileUtils.mkdir_p(directory)
47
+ File.open(config_file, "w+") { |f| YAML.dump(hash, f) }
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,7 @@
1
+ class Array
2
+
3
+ def to_ascii_plist
4
+ "(\n#{map{ |x| x.to_ascii_plist + "," }.join("")}\n)"
5
+ end
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ class Fixnum
2
+
3
+ def to_ascii_plist
4
+ self.to_s
5
+ end
6
+
7
+ end
@@ -0,0 +1,10 @@
1
+ class Hash
2
+
3
+ def to_ascii_plist
4
+ inner = []
5
+ each { |k, v| inner << " #{k.to_s.to_ascii_plist} = #{v.to_ascii_plist};" }
6
+
7
+ "{\n#{inner.join("\n")}\n}"
8
+ end
9
+
10
+ end
@@ -0,0 +1,11 @@
1
+ class String
2
+
3
+ def to_ascii_plist
4
+ if length == 0
5
+ "\"\""
6
+ else
7
+ match(/\-|\s|\+|\<|\$|\"|\[|\=|\*/) ? self.inspect : self
8
+ end
9
+ end
10
+
11
+ end