cocoapods-repo-shard 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +5 -0
  5. data/.rubocop_cocoapods.yml +138 -0
  6. data/.travis.yml +10 -0
  7. data/CHANGELOG.md +6 -0
  8. data/Gemfile +11 -0
  9. data/Gemfile.lock +105 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +11 -0
  12. data/Rakefile +16 -0
  13. data/cocoapods-repo-shard.gemspec +22 -0
  14. data/lib/cocoapods_plugin.rb +1 -0
  15. data/lib/cocoapods_repo_shard.rb +1 -0
  16. data/lib/cocoapods_repo_shard/command.rb +1 -0
  17. data/lib/cocoapods_repo_shard/command/repo/shard.rb +109 -0
  18. data/lib/cocoapods_repo_shard/gem_version.rb +3 -0
  19. data/spec/command/repo/shard_spec.rb +136 -0
  20. data/spec/fixtures/spec-repos/test_repo/Specs/BananaLib/0.0.1/BananaLib.podspec +19 -0
  21. data/spec/fixtures/spec-repos/test_repo/Specs/BananaLib/0.9/BananaLib.podspec +19 -0
  22. data/spec/fixtures/spec-repos/test_repo/Specs/BananaLib/1.0/BananaLib.podspec +20 -0
  23. data/spec/fixtures/spec-repos/test_repo/Specs/Faulty_spec/1.0.0/Faulty_spec.podspec +0 -0
  24. data/spec/fixtures/spec-repos/test_repo/Specs/IncorrectPath/1.0/IncorrectPath.podspec +4 -0
  25. data/spec/fixtures/spec-repos/test_repo/Specs/JSONKit/1.13/JSONKit.podspec +11 -0
  26. data/spec/fixtures/spec-repos/test_repo/Specs/JSONKit/1.4/JSONKit.podspec +11 -0
  27. data/spec/fixtures/spec-repos/test_repo/Specs/JSONKit/999.999.999/JSONKit.podspec +12 -0
  28. data/spec/fixtures/spec-repos/test_repo/Specs/JSONSpec/0.9/JSONSpec.podspec.json +4 -0
  29. data/spec/fixtures/spec-repos/test_repo/Specs/JSONSpec/1.0/JSONSpec.podspec.json +4 -0
  30. data/spec/fixtures/spec-repos/test_repo/Specs/StraySpec.podspec +4 -0
  31. data/spec/spec_helper.rb +50 -0
  32. metadata +115 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 78fe5c41407f1caec0b0f4b33758ac667e1b5147
4
+ data.tar.gz: f9cac41b6f95a34086c9f8380aa27bb14606006f
5
+ SHA512:
6
+ metadata.gz: 4068c773469ab20cbb6ca3965c6ebad275d3a926e42d2feae084f3adf19cb8cac50bc15bf870453bfe5323314a355ed198c693fdf2f35e46fcb6117d58e07844
7
+ data.tar.gz: 9131427d8c8f7f2e8ae8f1a0dd0b3577650e582a4ff6b771abc1f1ac528b965d7ad5a0817713eb8795e919935e7f1a24a1bea49b40cb801341284cacb2b59a3c
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ pkg
3
+ .idea/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ inherit_from:
2
+ - .rubocop_cocoapods.yml
3
+
4
+ Metrics/LineLength:
5
+ Max: 120
@@ -0,0 +1,138 @@
1
+ AllCops:
2
+ Include:
3
+ - ./Rakefile
4
+ - ./Gemfile
5
+ - ./*.gemspec
6
+ Exclude:
7
+ - ./spec/fixtures/**/*
8
+ - ./vendor/bundle/**/*
9
+
10
+ # At the moment not ready to be used
11
+ # https://github.com/bbatsov/rubocop/issues/947
12
+ Documentation:
13
+ Enabled: false
14
+
15
+ #- CocoaPods -----------------------------------------------------------------#
16
+
17
+ # We adopted raise instead of fail.
18
+ SignalException:
19
+ EnforcedStyle: only_raise
20
+
21
+ # They are idiomatic
22
+ AssignmentInCondition:
23
+ Enabled: false
24
+
25
+ # Allow backticks
26
+ AsciiComments:
27
+ Enabled: false
28
+
29
+ # Indentation clarifies logic branches in implementations
30
+ IfUnlessModifier:
31
+ Enabled: false
32
+
33
+ # No enforced convention here.
34
+ SingleLineBlockParams:
35
+ Enabled: false
36
+
37
+ # We only add the comment when needed.
38
+ Encoding:
39
+ Enabled: false
40
+
41
+ # Having these make it easier to *not* forget to add one when adding a new
42
+ # value and you can simply copy the previous line.
43
+ Style/TrailingCommaInArguments:
44
+ EnforcedStyleForMultiline: comma
45
+
46
+ Style/TrailingCommaInLiteral:
47
+ EnforcedStyleForMultiline: comma
48
+
49
+ Style/MultilineOperationIndentation:
50
+ EnforcedStyle: indented
51
+
52
+ # Clashes with CLAide Command#validate!
53
+ GuardClause:
54
+ Enabled: false
55
+
56
+ # Not always desirable: lib/claide/command/plugins_helper.rb:12:15
57
+ Next:
58
+ Enabled: false
59
+
60
+ # Autocorrect makes this cop much more useful, taking away needless guessing
61
+ Lint/EndAlignment:
62
+ AutoCorrect: true
63
+
64
+
65
+ # Arbitrary max lengths for classes simply do not work and enabling this will
66
+ # lead to a never ending stream of annoyance and changes.
67
+ Metrics/ClassLength:
68
+ Enabled: false
69
+
70
+ # Arbitrary max lengths for modules simply do not work and enabling this will
71
+ # lead to a never ending stream of annoyance and changes.
72
+ Metrics/ModuleLength:
73
+ Enabled: false
74
+
75
+ # Arbitrary max lengths for methods simply do not work and enabling this will
76
+ # lead to a never ending stream of annoyance and changes.
77
+ Metrics/MethodLength:
78
+ Enabled: false
79
+
80
+ # No enforced convention here.
81
+ Metrics/BlockNesting:
82
+ Enabled: false
83
+
84
+ # It will be obvious which code is complex, Rubocop should only lint simple
85
+ # rules for us.
86
+ Metrics/AbcSize:
87
+ Enabled: false
88
+
89
+ # It will be obvious which code is complex, Rubocop should only lint simple
90
+ # rules for us.
91
+ Metrics/CyclomaticComplexity:
92
+ Enabled: false
93
+
94
+ # It will be obvious which code is complex, Rubocop should only lint simple
95
+ # rules for us.
96
+ Metrics/PerceivedComplexity:
97
+ Enabled: false
98
+
99
+ #- CocoaPods support for Ruby 1.8.7 ------------------------------------------#
100
+
101
+ HashSyntax:
102
+ EnforcedStyle: hash_rockets
103
+
104
+ Lambda:
105
+ Enabled: false
106
+
107
+ DotPosition:
108
+ EnforcedStyle: trailing
109
+
110
+ EachWithObject:
111
+ Enabled: false
112
+
113
+ Style/SpecialGlobalVars:
114
+ Enabled: false
115
+
116
+ #- CocoaPods specs -----------------------------------------------------------#
117
+
118
+ # Allow for `should.match /regexp/`.
119
+ AmbiguousRegexpLiteral:
120
+ Exclude:
121
+ - spec/**/*
122
+
123
+ Performance/RedundantMatch:
124
+ Exclude:
125
+ - spec/**/*
126
+
127
+ # Allow `object.should == object` syntax.
128
+ Void:
129
+ Exclude:
130
+ - spec/**/*
131
+
132
+ ClassAndModuleChildren:
133
+ Exclude:
134
+ - spec/**/*
135
+
136
+ UselessComparison:
137
+ Exclude:
138
+ - spec/**/*
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.3.0
5
+ branches:
6
+ only:
7
+ - master
8
+ before_install:
9
+ - git config --global user.email "you@example.com"
10
+ - git config --global user.name "Your Name"
@@ -0,0 +1,6 @@
1
+ ## 1.0.0 (2016-04-15)
2
+
3
+ ##### Enhancements
4
+
5
+ * Initial implementation.
6
+ [Samuel Giddins](https://github.com/segiddins)
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cocoapods-repo-shard.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'cocoapods', '1.0.0.beta.7'
8
+
9
+ gem 'rspec'
10
+ gem 'rubocop'
11
+ end
@@ -0,0 +1,105 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cocoapods-repo-shard (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (4.2.6)
10
+ i18n (~> 0.7)
11
+ json (~> 1.7, >= 1.7.7)
12
+ minitest (~> 5.1)
13
+ thread_safe (~> 0.3, >= 0.3.4)
14
+ tzinfo (~> 1.1)
15
+ ast (2.2.0)
16
+ claide (1.0.0.beta.3)
17
+ cocoapods (1.0.0.beta.7)
18
+ activesupport (>= 4.0.2)
19
+ claide (>= 1.0.0.beta.3, < 2.0)
20
+ cocoapods-core (= 1.0.0.beta.7)
21
+ cocoapods-deintegrate (>= 1.0.0.beta.1, < 2.0)
22
+ cocoapods-downloader (= 1.0.0.beta.3)
23
+ cocoapods-plugins (>= 1.0.0.beta.1, < 2.0)
24
+ cocoapods-search (= 1.0.0.beta.2)
25
+ cocoapods-stats (= 1.0.0.beta.4)
26
+ cocoapods-trunk (= 1.0.0.beta.3)
27
+ cocoapods-try (>= 1.0.0.beta.3, < 2.0)
28
+ colored (~> 1.2)
29
+ escape (~> 0.0.4)
30
+ fourflusher (~> 0.3.0)
31
+ molinillo (~> 0.4.4)
32
+ nap (~> 1.0)
33
+ xcodeproj (= 1.0.0.beta.4)
34
+ cocoapods-core (1.0.0.beta.7)
35
+ activesupport (>= 4.0.2)
36
+ fuzzy_match (~> 2.0.4)
37
+ nap (~> 1.0)
38
+ cocoapods-deintegrate (1.0.0.beta.1)
39
+ cocoapods-downloader (1.0.0.beta.3)
40
+ cocoapods-plugins (1.0.0.beta.1)
41
+ nap
42
+ cocoapods-search (1.0.0.beta.2)
43
+ cocoapods-stats (1.0.0.beta.4)
44
+ cocoapods-trunk (1.0.0.beta.3)
45
+ nap (>= 0.8, < 2.0)
46
+ netrc (= 0.7.8)
47
+ cocoapods-try (1.0.0.beta.3)
48
+ colored (1.2)
49
+ diff-lcs (1.2.5)
50
+ escape (0.0.4)
51
+ fourflusher (0.3.0)
52
+ fuzzy_match (2.0.4)
53
+ i18n (0.7.0)
54
+ json (1.8.3)
55
+ minitest (5.8.4)
56
+ molinillo (0.4.4)
57
+ nap (1.1.0)
58
+ netrc (0.7.8)
59
+ parser (2.3.0.6)
60
+ ast (~> 2.2)
61
+ powerpack (0.1.1)
62
+ rainbow (2.1.0)
63
+ rake (11.1.0)
64
+ rspec (3.4.0)
65
+ rspec-core (~> 3.4.0)
66
+ rspec-expectations (~> 3.4.0)
67
+ rspec-mocks (~> 3.4.0)
68
+ rspec-core (3.4.4)
69
+ rspec-support (~> 3.4.0)
70
+ rspec-expectations (3.4.0)
71
+ diff-lcs (>= 1.2.0, < 2.0)
72
+ rspec-support (~> 3.4.0)
73
+ rspec-mocks (3.4.1)
74
+ diff-lcs (>= 1.2.0, < 2.0)
75
+ rspec-support (~> 3.4.0)
76
+ rspec-support (3.4.1)
77
+ rubocop (0.38.0)
78
+ parser (>= 2.3.0.6, < 3.0)
79
+ powerpack (~> 0.1)
80
+ rainbow (>= 1.99.1, < 3.0)
81
+ ruby-progressbar (~> 1.7)
82
+ unicode-display_width (~> 1.0, >= 1.0.1)
83
+ ruby-progressbar (1.7.5)
84
+ thread_safe (0.3.5)
85
+ tzinfo (1.2.2)
86
+ thread_safe (~> 0.1)
87
+ unicode-display_width (1.0.2)
88
+ xcodeproj (1.0.0.beta.4)
89
+ activesupport (>= 3)
90
+ claide (>= 1.0.0.beta.1, < 2.0)
91
+ colored (~> 1.2)
92
+
93
+ PLATFORMS
94
+ ruby
95
+
96
+ DEPENDENCIES
97
+ bundler (~> 1.11)
98
+ cocoapods (= 1.0.0.beta.7)
99
+ cocoapods-repo-shard!
100
+ rake (~> 11.0)
101
+ rspec
102
+ rubocop
103
+
104
+ BUNDLED WITH
105
+ 1.12.0.rc
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Samuel Giddins <segiddins@segiddins.me>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,11 @@
1
+ # cocoapods-repo-shard
2
+
3
+ This plugin allows sharding a spec repo's `Specs` directory to be more performant under various `git` operations. By sharding a repository, a large amount of specs can be stored at logarithmic cost, rather than linear cost. Most private specs repos will never have to be concerned with the particular performance characteristics of git, but the [master specs repo](https://github.com/CocoaPods/Specs) is large enough that sharding will bring a massive performance gain.
4
+
5
+ ## Installation
6
+
7
+ $ gem install cocoapods-repo-shard
8
+
9
+ ## Usage
10
+
11
+ $ pod repo shard REPO_NAME --lengths=1,1,1
@@ -0,0 +1,16 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+
6
+ require 'rspec/core/rake_task'
7
+ require 'rubocop/rake_task'
8
+
9
+ RSpec::Core::RakeTask.new
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: [:rubocop, :spec]
13
+ rescue LoadError
14
+ puts '[!] Some tasks have been disabled due to missing dependencies. ' \
15
+ 'Run `bundle install`.'
16
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cocoapods_repo_shard/gem_version.rb'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cocoapods-repo-shard'
8
+ spec.version = CocoapodsRepoShard::VERSION
9
+ spec.authors = ['Samuel Giddins']
10
+ spec.email = ['segiddins@segiddins.me']
11
+ spec.summary = 'Shard a CocoaPods specs repository.'
12
+ spec.homepage = 'https://github.com/CocoaPods/cocoapods-repo-shard'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_development_dependency 'bundler', '~> 1.11'
21
+ spec.add_development_dependency 'rake', '~> 11.0'
22
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods_repo_shard/command'
@@ -0,0 +1 @@
1
+ require 'cocoapods_repo_shard/gem_version'
@@ -0,0 +1 @@
1
+ require 'cocoapods_repo_shard/command/repo/shard'
@@ -0,0 +1,109 @@
1
+ module Pod
2
+ class Command
3
+ class Repo
4
+ class Shard < Repo
5
+ self.summary = 'Shards a CocoaPods specs repo in-place.'
6
+
7
+ self.arguments = [
8
+ CLAide::Argument.new('NAME', true),
9
+ ]
10
+
11
+ attr_reader :source
12
+ attr_reader :name
13
+ attr_reader :lengths
14
+
15
+ def self.options
16
+ [
17
+ ['--lengths=l1,l2,...', 'The prefix lengths to shard the source with'],
18
+ ].concat(super)
19
+ end
20
+
21
+ def initialize(argv)
22
+ @name = argv.shift_argument
23
+ @lengths = argv.option('lengths')
24
+ super
25
+ end
26
+
27
+ def validate!
28
+ help! 'A repo name is required.' unless @name
29
+
30
+ @source = config.sources_manager.sources([@name]).first
31
+ help! "No repo named `#{@name}` found." unless source.specs_dir
32
+ unless source.specs_dir.basename.to_s == 'Specs'
33
+ raise Informative, 'Cannot shard a repo that does not use the `Specs` directory'
34
+ end
35
+
36
+ if lengths
37
+ @lengths = lengths.split(',').map(&:to_i)
38
+ help! 'All lengths must be positive' if lengths.any? { |l| l <= 0 }
39
+ end
40
+
41
+ super
42
+ end
43
+
44
+ extend Executable
45
+ executable :git
46
+
47
+ def run
48
+ require 'fileutils'
49
+ require 'yaml'
50
+
51
+ @lengths ||= ideal_lengths(source.pods.size).tap do |ideal_lengths|
52
+ UI.puts "Sharding to ideal prefix lengths #{ideal_lengths.inspect}"
53
+ end
54
+
55
+ new_specs_dir = source.repo + 'temp_specs_dir'
56
+ new_specs_dir.mkpath
57
+
58
+ new_metadata = Source::Metadata.new(source.metadata.to_hash.update('prefix_lengths' => @lengths))
59
+
60
+ UI.puts 'Copying specs into sharded structure'
61
+ source.pods.each do |name|
62
+ path = new_specs_dir.join(new_metadata.path_fragment(name))
63
+ path.parent.mkpath
64
+ FileUtils.cp_r(source.pod_path(name), path)
65
+ end
66
+
67
+ UI.puts 'Replacing existing specs directory with sharded copy'
68
+ source.specs_dir.rmtree
69
+ FileUtils.mv(new_specs_dir, source.specs_dir)
70
+
71
+ UI.puts 'Writing updated source metadata'
72
+ source.metadata_path.open('w') { |f| f.write(YAML.dump(new_metadata.to_hash)) }
73
+ source.send(:refresh_metadata)
74
+
75
+ UI.section 'Committing changes to the specs repo' do
76
+ Dir.chdir(source.repo) do
77
+ git! 'add', source.specs_dir
78
+ git! 'add', source.metadata_path
79
+ git! 'commit', '-m',
80
+ "Sharded to use #{lengths.inspect} prefix lengths"
81
+ end
82
+ end
83
+
84
+ UI.puts "Finished sharding the #{source.name} repo.\n" \
85
+ "After verifying the changes, push the changes in #{UI.path(source.repo)} upstream."
86
+ ensure
87
+ new_specs_dir.rmtree if new_specs_dir && new_specs_dir.directory?
88
+ end
89
+
90
+ private
91
+
92
+ def ideal_lengths(total)
93
+ possibilities = (0..3).cycle.first(4 * 4).permutation(4).to_a.
94
+ each(&:sort!).uniq.each { |perm| perm.delete(0) }
95
+ possibilities.min_by do |perm|
96
+ cost(total, perm) +
97
+ 0.75 * cost(total * 2, perm) +
98
+ 0.33 * cost(total * 4, perm)
99
+ end
100
+ end
101
+
102
+ def cost(total, lengths)
103
+ (total / (16**lengths.reduce(0, &:+))) +
104
+ lengths.reduce(0) { |s, l| s + 16**l }
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,3 @@
1
+ module CocoapodsRepoShard
2
+ VERSION = '1.0.0'.freeze
3
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pod::Command::Repo::Shard do
4
+ describe 'CLAide' do
5
+ it 'registers itself' do
6
+ expect(Pod::Command.parse(%w(repo shard))).to be_instance_of described_class
7
+ end
8
+ end
9
+
10
+ describe '#validate!' do
11
+ let(:argv) { %w() }
12
+ subject { Pod::Command.parse(%w(repo shard) + argv) }
13
+
14
+ context 'without arguments' do
15
+ it 'raises due to missing repo name' do
16
+ expect { subject.validate! }.to raise_error(CLAide::Help, /A repo name is required/)
17
+ end
18
+ end
19
+
20
+ context 'with an unknown repo name' do
21
+ let(:argv) { %w(missing-repo) }
22
+ it 'raises due to missing repo name' do
23
+ expect { subject.validate! }.to raise_error(CLAide::Help, /No repo named `missing-repo` found/)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe 'sharding' do
29
+ let(:repos_dir) { Pathname(Dir.mktmpdir) }
30
+ let(:repo) { 'test_repo' }
31
+ before do
32
+ repos_dir.rmtree
33
+ FileUtils.cp_r(Pod::Config.instance.repos_dir, repos_dir)
34
+ Pod::Config.instance.repos_dir = repos_dir
35
+ Dir.chdir(repos_dir + repo) do
36
+ `git init .`
37
+ `git add .`
38
+ `git commit -am 'Initial Commit'`
39
+ end
40
+ end
41
+ after do
42
+ repos_dir # .rmtree
43
+ end
44
+
45
+ let(:argv) { [repo] }
46
+
47
+ subject do
48
+ described_class.invoke(argv)
49
+ Pod::Config.instance.sources_manager.sources([repo]).first
50
+ end
51
+
52
+ context 'with explicit lengths' do
53
+ let(:argv) { super() + %w(--lengths=1,2,3) }
54
+
55
+ it 'shards correctly' do
56
+ expect(subject.metadata.prefix_lengths).to eq([1, 2, 3])
57
+
58
+ expect(subject.all_specs.map { |s| [s.to_s, s.defined_in_file] }.sort).to eq [
59
+ ['BananaLib (0.0.1)', subject.specs_dir + '3/8e/ca9/BananaLib/0.0.1/BananaLib.podspec'],
60
+ ['BananaLib (0.9)', subject.specs_dir + '3/8e/ca9/BananaLib/0.9/BananaLib.podspec'],
61
+ ['BananaLib (1.0)', subject.specs_dir + '3/8e/ca9/BananaLib/1.0/BananaLib.podspec'],
62
+ ['IncorrectPath (0.9)', subject.specs_dir + '9/0c/8c9/IncorrectPath/1.0/IncorrectPath.podspec'],
63
+ ['JSONKit (1.13)', subject.specs_dir + '1/3f/e43/JSONKit/1.13/JSONKit.podspec'],
64
+ ['JSONKit (1.4)', subject.specs_dir + '1/3f/e43/JSONKit/1.4/JSONKit.podspec'],
65
+ ['JSONKit (999.999.999)', subject.specs_dir + '1/3f/e43/JSONKit/999.999.999/JSONKit.podspec'],
66
+ ['JSONSpec (0.9)', subject.specs_dir + 'd/8d/54f/JSONSpec/0.9/JSONSpec.podspec.json'],
67
+ ['JSONSpec (1.0)', subject.specs_dir + 'd/8d/54f/JSONSpec/1.0/JSONSpec.podspec.json'],
68
+ ]
69
+ end
70
+ end
71
+
72
+ context 'with implicit lengths' do
73
+ it 'shards correctly' do
74
+ expect(subject.metadata.prefix_lengths).to eq([])
75
+
76
+ expect(subject.all_specs.map { |s| [s.to_s, s.defined_in_file] }.sort).to eq [
77
+ ['BananaLib (0.0.1)', subject.specs_dir + 'BananaLib/0.0.1/BananaLib.podspec'],
78
+ ['BananaLib (0.9)', subject.specs_dir + 'BananaLib/0.9/BananaLib.podspec'],
79
+ ['BananaLib (1.0)', subject.specs_dir + 'BananaLib/1.0/BananaLib.podspec'],
80
+ ['IncorrectPath (0.9)', subject.specs_dir + 'IncorrectPath/1.0/IncorrectPath.podspec'],
81
+ ['JSONKit (1.13)', subject.specs_dir + 'JSONKit/1.13/JSONKit.podspec'],
82
+ ['JSONKit (1.4)', subject.specs_dir + 'JSONKit/1.4/JSONKit.podspec'],
83
+ ['JSONKit (999.999.999)', subject.specs_dir + 'JSONKit/999.999.999/JSONKit.podspec'],
84
+ ['JSONSpec (0.9)', subject.specs_dir + 'JSONSpec/0.9/JSONSpec.podspec.json'],
85
+ ['JSONSpec (1.0)', subject.specs_dir + 'JSONSpec/1.0/JSONSpec.podspec.json'],
86
+ ]
87
+ end
88
+ end
89
+
90
+ context 'with an already sharded directory' do
91
+ before do
92
+ described_class.invoke(%W(#{repo} --lengths=1,1))
93
+ end
94
+
95
+ context 're-sharding' do
96
+ let(:argv) { super() + %w(--lengths=1,2,3) }
97
+
98
+ it 'shards correctly' do
99
+ expect(subject.metadata.prefix_lengths).to eq([1, 2, 3])
100
+
101
+ expect(subject.all_specs.map { |s| [s.to_s, s.defined_in_file] }.sort).to eq [
102
+ ['BananaLib (0.0.1)', subject.specs_dir + '3/8e/ca9/BananaLib/0.0.1/BananaLib.podspec'],
103
+ ['BananaLib (0.9)', subject.specs_dir + '3/8e/ca9/BananaLib/0.9/BananaLib.podspec'],
104
+ ['BananaLib (1.0)', subject.specs_dir + '3/8e/ca9/BananaLib/1.0/BananaLib.podspec'],
105
+ ['IncorrectPath (0.9)', subject.specs_dir + '9/0c/8c9/IncorrectPath/1.0/IncorrectPath.podspec'],
106
+ ['JSONKit (1.13)', subject.specs_dir + '1/3f/e43/JSONKit/1.13/JSONKit.podspec'],
107
+ ['JSONKit (1.4)', subject.specs_dir + '1/3f/e43/JSONKit/1.4/JSONKit.podspec'],
108
+ ['JSONKit (999.999.999)', subject.specs_dir + '1/3f/e43/JSONKit/999.999.999/JSONKit.podspec'],
109
+ ['JSONSpec (0.9)', subject.specs_dir + 'd/8d/54f/JSONSpec/0.9/JSONSpec.podspec.json'],
110
+ ['JSONSpec (1.0)', subject.specs_dir + 'd/8d/54f/JSONSpec/1.0/JSONSpec.podspec.json'],
111
+ ]
112
+ end
113
+ end
114
+
115
+ context 'un-sharding' do
116
+ let(:argv) { super() + %w(--lengths=) }
117
+
118
+ it 'shards correctly' do
119
+ expect(subject.metadata.prefix_lengths).to eq([])
120
+
121
+ expect(subject.all_specs.map { |s| [s.to_s, s.defined_in_file] }.sort).to eq [
122
+ ['BananaLib (0.0.1)', subject.specs_dir + 'BananaLib/0.0.1/BananaLib.podspec'],
123
+ ['BananaLib (0.9)', subject.specs_dir + 'BananaLib/0.9/BananaLib.podspec'],
124
+ ['BananaLib (1.0)', subject.specs_dir + 'BananaLib/1.0/BananaLib.podspec'],
125
+ ['IncorrectPath (0.9)', subject.specs_dir + 'IncorrectPath/1.0/IncorrectPath.podspec'],
126
+ ['JSONKit (1.13)', subject.specs_dir + 'JSONKit/1.13/JSONKit.podspec'],
127
+ ['JSONKit (1.4)', subject.specs_dir + 'JSONKit/1.4/JSONKit.podspec'],
128
+ ['JSONKit (999.999.999)', subject.specs_dir + 'JSONKit/999.999.999/JSONKit.podspec'],
129
+ ['JSONSpec (0.9)', subject.specs_dir + 'JSONSpec/0.9/JSONSpec.podspec.json'],
130
+ ['JSONSpec (1.0)', subject.specs_dir + 'JSONSpec/1.0/JSONSpec.podspec.json'],
131
+ ]
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,19 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'BananaLib'
3
+ s.version = '0.0.1'
4
+ s.authors = 'Banana Corp', { 'Monkey Boy' => 'monkey@banana-corp.local' }
5
+ s.homepage = 'http://banana-corp.local/banana-lib.html'
6
+ s.summary = 'Chunky bananas!'
7
+ s.description = 'Full of chunky bananas.'
8
+ s.source = { :git => 'http://banana-corp.local/banana-lib.git', :commit => 'dbf863b4d7cf6c22d4bf89969fe7505c61950958' }
9
+ s.source_files = 'Classes/*.{h,m}', 'Vendor'
10
+ s.xcconfig = { 'OTHER_LDFLAGS' => '-framework SystemConfiguration' }
11
+ s.prefix_header_file = 'Classes/BananaLib.pch'
12
+ s.resources = "Resources/*.png"
13
+ s.dependency 'monkey', '~> 1.0.1', '< 1.0.9'
14
+ s.license = {
15
+ :type => 'MIT',
16
+ :file => 'LICENSE',
17
+ :text => 'Permission is hereby granted ...'
18
+ }
19
+ end
@@ -0,0 +1,19 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'BananaLib'
3
+ s.version = '0.9'
4
+ s.authors = 'Banana Corp', { 'Monkey Boy' => 'monkey@banana-corp.local' }
5
+ s.homepage = 'http://banana-corp.local/banana-lib.html'
6
+ s.summary = 'Chunky bananas!'
7
+ s.description = 'Full of chunky bananas.'
8
+ s.source = { :git => 'http://banana-corp.local/banana-lib.git', :tag => 'v1.0' }
9
+ s.source_files = 'Classes/*.{h,m}', 'Vendor'
10
+ s.xcconfig = { 'OTHER_LDFLAGS' => '-framework SystemConfiguration' }
11
+ s.prefix_header_file = 'Classes/BananaLib.pch'
12
+ s.resources = "Resources/*.png"
13
+ s.dependency 'monkey', '~> 1.0.1', '< 1.0.9'
14
+ s.license = {
15
+ :type => 'MIT',
16
+ :file => 'LICENSE',
17
+ :text => 'Permission is hereby granted ...'
18
+ }
19
+ end
@@ -0,0 +1,20 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'BananaLib'
3
+ s.version = '1.0'
4
+ s.authors = 'Banana Corp', { 'Monkey Boy' => 'monkey@banana-corp.local' }
5
+ s.homepage = 'http://banana-corp.local/banana-lib.html'
6
+ s.summary = 'Chunky bananas!'
7
+ s.description = 'Full of chunky bananas.'
8
+ s.source = { :git => 'http://banana-corp.local/banana-lib.git', :tag => 'v1.0' }
9
+ s.source_files = 'Classes/*.{h,m}', 'Vendor'
10
+ s.xcconfig = { 'OTHER_LDFLAGS' => '-framework SystemConfiguration' }
11
+ s.prefix_header_file = 'Classes/BananaLib.pch'
12
+ s.resources = "Resources/*.png"
13
+ s.requires_arc = true
14
+ s.dependency 'monkey', '~> 1.0.1', '< 1.0.9'
15
+ s.license = {
16
+ :type => 'MIT',
17
+ :file => 'LICENSE',
18
+ :text => 'Permission is hereby granted ...'
19
+ }
20
+ end
@@ -0,0 +1,4 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'IncorrectPath'
3
+ s.version = '0.9'
4
+ end
@@ -0,0 +1,11 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'JSONKit'
3
+ s.version = '1.13'
4
+ s.license = 'BSD / Apache License, Version 2.0'
5
+ s.summary = 'A Very High Performance Objective-C JSON Library.'
6
+ s.homepage = 'https://github.com/johnezang/JSONKit'
7
+ s.author = 'John Engelhart'
8
+ s.source = { :git => 'https://github.com/johnezang/JSONKit.git', :tag => 'v1.13' }
9
+
10
+ s.source_files = 'JSONKit.*'
11
+ end
@@ -0,0 +1,11 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'JSONKit'
3
+ s.version = '1.4'
4
+ s.license = 'BSD / Apache License, Version 2.0'
5
+ s.summary = 'A Very High Performance Objective-C JSON Library.'
6
+ s.homepage = 'https://github.com/johnezang/JSONKit'
7
+ s.author = 'John Engelhart'
8
+ s.source = { :git => 'https://github.com/johnezang/JSONKit.git', :tag => 'v1.4' }
9
+
10
+ s.source_files = 'JSONKit.*'
11
+ end
@@ -0,0 +1,12 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'JSONKit'
3
+ s.version = '999.999.999'
4
+ s.license = 'BSD / Apache License, Version 2.0'
5
+ s.summary = 'A Very High Performance Objective-C JSON Library.'
6
+ s.homepage = 'https://github.com/johnezang/JSONKit'
7
+ s.author = 'John Engelhart'
8
+ s.source = { :git => 'https://github.com/johnezang/JSONKit.git', :commit => '0aff3deb5e1bb2bbc88a83fd71c8ad5550185cce' }
9
+
10
+ s.source_files = 'JSONKit.*'
11
+ s.compiler_flags = '-Wno-deprecated-objc-isa-usage', '-Wno-format'
12
+ end
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "JSONSpec",
3
+ "version": "0.9"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "JSONSpec",
3
+ "version": "1.0"
4
+ }
@@ -0,0 +1,4 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'IncorrectPath'
3
+ s.version = '0.9'
4
+ end
@@ -0,0 +1,50 @@
1
+ require 'bundler/setup'
2
+ require 'cocoapods'
3
+
4
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
5
+
6
+ require File.expand_path('../../lib/cocoapods_plugin', __FILE__)
7
+
8
+ #-----------------------------------------------------------------------------#
9
+
10
+ module Pod
11
+ # Disable the wrapping so the output is deterministic in the tests.
12
+ #
13
+ UI.disable_wrap = true
14
+
15
+ # Redirects the messages to an internal store.
16
+ #
17
+ module UI
18
+ @output = ''
19
+ @warnings = ''
20
+
21
+ class << self
22
+ attr_accessor :output
23
+ attr_accessor :warnings
24
+
25
+ def puts(message = '')
26
+ @output << "#{message}\n"
27
+ end
28
+
29
+ def warn(message = '', _actions = [])
30
+ @warnings << "#{message}\n"
31
+ end
32
+
33
+ def print(message)
34
+ @output << message
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ #-----------------------------------------------------------------------------#
41
+
42
+ RSpec.configure do |c|
43
+ c.before(:each) do
44
+ Pod::UI.output = ''
45
+ Pod::UI.warnings = ''
46
+
47
+ Pod::Config.instance.repos_dir = Pathname(__FILE__) + '../fixtures/spec-repos'
48
+ Pod::Config.instance.verbose = false
49
+ end
50
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-repo-shard
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Giddins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.0'
41
+ description:
42
+ email:
43
+ - segiddins@segiddins.me
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - ".rubocop.yml"
51
+ - ".rubocop_cocoapods.yml"
52
+ - ".travis.yml"
53
+ - CHANGELOG.md
54
+ - Gemfile
55
+ - Gemfile.lock
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - cocoapods-repo-shard.gemspec
60
+ - lib/cocoapods_plugin.rb
61
+ - lib/cocoapods_repo_shard.rb
62
+ - lib/cocoapods_repo_shard/command.rb
63
+ - lib/cocoapods_repo_shard/command/repo/shard.rb
64
+ - lib/cocoapods_repo_shard/gem_version.rb
65
+ - spec/command/repo/shard_spec.rb
66
+ - spec/fixtures/spec-repos/test_repo/Specs/BananaLib/0.0.1/BananaLib.podspec
67
+ - spec/fixtures/spec-repos/test_repo/Specs/BananaLib/0.9/BananaLib.podspec
68
+ - spec/fixtures/spec-repos/test_repo/Specs/BananaLib/1.0/BananaLib.podspec
69
+ - spec/fixtures/spec-repos/test_repo/Specs/Faulty_spec/1.0.0/Faulty_spec.podspec
70
+ - spec/fixtures/spec-repos/test_repo/Specs/IncorrectPath/1.0/IncorrectPath.podspec
71
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONKit/1.13/JSONKit.podspec
72
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONKit/1.4/JSONKit.podspec
73
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONKit/999.999.999/JSONKit.podspec
74
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONSpec/0.9/JSONSpec.podspec.json
75
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONSpec/1.0/JSONSpec.podspec.json
76
+ - spec/fixtures/spec-repos/test_repo/Specs/StraySpec.podspec
77
+ - spec/spec_helper.rb
78
+ homepage: https://github.com/CocoaPods/cocoapods-repo-shard
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.6.3
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Shard a CocoaPods specs repository.
102
+ test_files:
103
+ - spec/command/repo/shard_spec.rb
104
+ - spec/fixtures/spec-repos/test_repo/Specs/BananaLib/0.0.1/BananaLib.podspec
105
+ - spec/fixtures/spec-repos/test_repo/Specs/BananaLib/0.9/BananaLib.podspec
106
+ - spec/fixtures/spec-repos/test_repo/Specs/BananaLib/1.0/BananaLib.podspec
107
+ - spec/fixtures/spec-repos/test_repo/Specs/Faulty_spec/1.0.0/Faulty_spec.podspec
108
+ - spec/fixtures/spec-repos/test_repo/Specs/IncorrectPath/1.0/IncorrectPath.podspec
109
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONKit/1.13/JSONKit.podspec
110
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONKit/1.4/JSONKit.podspec
111
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONKit/999.999.999/JSONKit.podspec
112
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONSpec/0.9/JSONSpec.podspec.json
113
+ - spec/fixtures/spec-repos/test_repo/Specs/JSONSpec/1.0/JSONSpec.podspec.json
114
+ - spec/fixtures/spec-repos/test_repo/Specs/StraySpec.podspec
115
+ - spec/spec_helper.rb