tworingtools 4.4.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8859999037d1edd2c81b33358b8c77ea66eb3199d77e1556efe445f4e442127f
4
- data.tar.gz: 7fa2a8328f322eab2d614f92ba252a146e5e29ee134414d9bb332591fcf1c862
3
+ metadata.gz: 8a9c273d420e81312cd78a3cfb16705daa66c66cb88333b028a99aeead328b57
4
+ data.tar.gz: bf970bd1d1613d2667f7d5279ec35c5d1bc0ea68b51d07d80bb4246491706320
5
5
  SHA512:
6
- metadata.gz: d58734ba15e37cd18d69b396519c4dde656a1601388aeacf16031d378a193f9fbce7f6d71cd0ebd8d473cdf6d8f3647805956771ff4c5a8b71a460f93080dc88
7
- data.tar.gz: 57cae9321468c8d298776eeb8b96c295f760329870049620738865f840d959a36b25605f928931b163124d29877c396571a8116ac35940f7511ca7c9239bac4a
6
+ metadata.gz: e1acd45a72627aa1c61876360907b65715d55afe06c4c398d711476bc06e79baeb806475c1b46e739cecb57f5a13014273f423ff1d3b0d009987dc5e97143dfd
7
+ data.tar.gz: 6160816443577623849b42d6cd0972b6314dc523bbcdc2295d9501c4d80f6bc1e124831f9aad4d61d27f81dcda68b8bae358869d50f1d4479d06aeedcbc1bb91
data/bin/bumpr CHANGED
@@ -18,6 +18,7 @@ parser = OptionParser.new do |opts|
18
18
 
19
19
  BANNER
20
20
  opts.on('-n', '--no-commit', 'Leave changes in the git working index instead of committing them.') do |no_commit| options[:no_commit] = true end
21
+ opts.on('-cCUSTOM', '--custom=CUSTOM', 'Custom version to use for semantic component (or build number for "build" component).') do |custom| options[:custom] = custom end
21
22
  opts.on('-h', '--help', 'Print this help message.') do
22
23
  puts opts
23
24
  exit
@@ -43,7 +44,11 @@ if argument == nil then
43
44
  exit TwoRingToolError::INVALID_SEMVER_COMPONENT
44
45
  end
45
46
 
46
- command = "vrsn #{argument} --file #{version_file}"
47
+ invocation_options = Array.new
48
+ unless options[:custom] == nil then
49
+ invocation_options += ['--custom', options[:custom]]
50
+ end
51
+ command = "vrsn #{argument} --file #{version_file} #{invocation_options.join(' ')}"
47
52
  puts command
48
53
  stdout, stderr, status = Open3.capture3(command)
49
54
 
data/bin/changetag CHANGED
@@ -37,7 +37,7 @@ parser = OptionParser.new do |opts|
37
37
  end
38
38
  parser.parse!
39
39
 
40
- git_check unless options[:no_commit]
40
+ git_check
41
41
 
42
42
  # set valid git message comment character
43
43
 
@@ -13,7 +13,8 @@ parser = OptionParser.new do |opts|
13
13
  Move any contents in Unreleased under a new heading for the specified version with current date.
14
14
 
15
15
  BANNER
16
- opts.on('-h', '--help', 'Print this help message.') do
16
+ opts.on('-n', '--no-commit', 'Leave changes in the git working index instead of committing them.') do |no_commit| options[:no_commit] = true end
17
+ opts.on('-h', '--help', 'Print this help message.') do
17
18
  puts opts
18
19
  exit
19
20
  end
@@ -39,5 +40,7 @@ File.open(changelog_path, 'w+') do |writable_changelog|
39
40
  writable_changelog << changelog_contents.join('')
40
41
  end
41
42
 
42
- `git add #{changelog_path}`
43
- `git commit --message "chore(changelog): moved Unreleased entries to #{version}"`
43
+ unless options[:no_commit] then
44
+ `git add #{changelog_path}`
45
+ `git commit --message "chore(changelog): moved Unreleased entries to #{version}"`
46
+ end
@@ -31,6 +31,7 @@ parser = OptionParser.new do |opts|
31
31
  opts.on('-tTAG', '--tag=TAG', 'Override for the name of the git tag to form. If set, --podspec-name-in-tag is ignored.') do |tag| options[:tag] = tag end
32
32
  opts.on('-t', '--no-tag', 'Don\'t create a git tag to push. Usually used if this will be invoked again for another spec that will create and use the same tag.') do |no_tag| options[:no_tag] = true end
33
33
  opts.on('-rRC', '--release-candidate=RC', 'Override for the release candidate number, which is otherwise formulated by counting the previous amount of tags with the same version number and incrementing by one.') do |rc| options[:rc] = rc end
34
+ opts.on('-q', '--quick', 'Perform quick podspec lint only.') do |quick| options[:quick] = true end
34
35
  opts.on('-h', '--help', 'Print this help message.') do
35
36
  puts opts
36
37
  exit
@@ -81,15 +82,18 @@ end
81
82
 
82
83
  puts "About to lint the podspec. This takes a while... (it is now #{Time.now})"
83
84
  spec_lint_flags = Array.new
84
- if options[:allow_warnings] != nil then
85
+ if options[:allow_warnings] then
85
86
  spec_lint_flags << '--allow-warnings'
86
87
  end
87
- if options[:verbose] != nil then
88
+ if options[:verbose] then
88
89
  spec_lint_flags << '--verbose'
89
90
  end
90
- if options[:skip_tests] != nil then
91
+ if options[:skip_tests] then
91
92
  spec_lint_flags << '--skip-tests'
92
93
  end
94
+ if options[:quick] then
95
+ spec_lint_flags << '--quick'
96
+ end
93
97
  stdout, stderr, status = Open3.capture3 "rbenv exec bundle exec pod spec lint #{version_file} #{spec_lint_flags.join ' '}"
94
98
 
95
99
  puts "stdout: #{stdout}"
data/bin/release-podspec CHANGED
@@ -28,7 +28,8 @@ parser = OptionParser.new do |opts|
28
28
  opts.on('-rREPO', '--repo=REPO', 'By default, release-podspec pushes the podspec to CocoaPods trunk. By supplying this argument, instead of \`pod trunk push\`, \`pod repo push\` is used instead.') do |repo| options[:repo] = repo end
29
29
  opts.on('-cCHANGELOG_PATH', '--changelog-path=CHANGELOG_PATH', 'Location of a CHANGELOG document adhering to https://keepachangelog.com/en/1.0.0/ whose version entry should be extracted into an annotated tag for this release candidate. By default, release-podspec looks for //CHANGELOG.md. You can specify another location with this option.') do |changelog_path| options[:changelog_path] = changelog_path end
30
30
  opts.on('-tTAG', '--tag=TAG', 'Override for the name of the git tag to form. If set, --podspec-name-in-tag is ignored.') do |tag| options[:tag] = tag end
31
- opts.on('--e', '--changelog-entry=CHANGELOG_ENTRY', 'The name of the changelog entry, if it differs from the tag name.') do |changelog_entry_name_override| options[:changelog_entry_name_override] = changelog_entry_name_override end
31
+ opts.on('-e', '--changelog-entry=CHANGELOG_ENTRY', 'The name of the changelog entry, if it differs from the tag name.') do |changelog_entry_name_override| options[:changelog_entry_name_override] = changelog_entry_name_override end
32
+ opts.on('-i', '--skip-import-validation', 'Skip building/testing importability of podspec as part of pushing it to source.') do |skip_import_validation| options[:skip_import_validation] = true end
32
33
  opts.on('-h', '--help', 'Print this help message.') do
33
34
  puts opts
34
35
  exit
@@ -63,15 +64,18 @@ end
63
64
  echo_and_exec 'git push --tags'
64
65
 
65
66
  spec_lint_flags = Array.new
66
- if options[:allow_warnings] != nil then
67
+ if options[:allow_warnings] then
67
68
  spec_lint_flags << '--allow-warnings'
68
69
  end
69
- if options[:verbose] != nil then
70
+ if options[:verbose] then
70
71
  spec_lint_flags << '--verbose'
71
72
  end
72
- if options[:skip_tests] != nil then
73
+ if options[:skip_tests] then
73
74
  spec_lint_flags << '--skip-tests'
74
75
  end
76
+ if options[:skip_import_validation] then
77
+ spec_lint_flags << '--skip-import-validation'
78
+ end
75
79
 
76
80
  command = String.new
77
81
  if options[:repo] != nil then
data/bin/sync-git ADDED
@@ -0,0 +1,109 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'octokit'
4
+ require 'json'
5
+ require 'optparse'
6
+ require_relative '../lib/echoexec'
7
+ require_relative '../lib/git_helpers'
8
+
9
+ # failure modes
10
+ FURTHER_REQUESTS_REQUIRE_TOKEN = 65
11
+ MISSING_REQUIRED_CREDENTIALS = 66
12
+
13
+ options = {}
14
+ parser = OptionParser.new do |opts|
15
+ opts.banner = <<~BANNER
16
+
17
+ Usage: sync-git [options] <directory>
18
+
19
+ For each of your GitHub forks, clone your forked version, then go in and add a remote
20
+ to the upstream version, and set up local tracking branches for both remotes' default
21
+ branches. Then fast-forward them both, fetch all tags etc.
22
+
23
+ <directory> is the path containing the directories holding your forks, and/or
24
+ to where those you don't yet have should be cloned.
25
+
26
+ Examples:
27
+
28
+ sync-git -u/--username <user> -p/--password <pass> [-o/--one-time-pw <otp>] .
29
+ sync-git -u/--username <user> -t/--token <token> .
30
+ sync-git -u/--username <user> -t/--token -n/--repo-name that-one-repo-I-forked <token> .
31
+
32
+ If you already have a Personal Access Token, provide it in the second form.
33
+ Otherwise, use the first form, which will register a new token for you named
34
+ “sync-git”. Then use that to invoke the program again. This is because
35
+ requests using basic authentication (user/pass) are too rate limited.
36
+
37
+ Options:
38
+
39
+ BANNER
40
+
41
+ opts.on('-uUSERNAME', '--username=USERNAME', 'GitHub username. Required for all invocations.') do |user| options[:username] = user end
42
+ opts.on('-tTOKEN', '--token=TOKEN', 'GitHub personal access token. The primary way to use this program.') do |t| options[:token] = t end
43
+ opts.on('-pPASSWORD', '--password=PASSWORD', 'GitHub password.') do |pass| options[:password] = pass end
44
+ opts.on('-oOTP', '--one-time-pw=OTP', 'GitHub 2FA token, if you have it enabled.') do |otp| options[:otp] = otp end
45
+ opts.on('-rREPO', '--repo-name=REPO', 'The name of a particular repository to sync.') do |repo| options[:repo] = repo end
46
+ opts.on('-v', '--verbose', 'Enable verbose logging.') do options[:verbose] = true end
47
+ end
48
+ parser.parse!
49
+ root_dir_path = ARGV[0]
50
+
51
+ # authenticate the github client, producing a token for callers to use if they try with user/pass, as that is rate limited
52
+ github = nil
53
+ if nil != options[:token] then
54
+ github = Octokit::Client.new(:access_token => options[:token])
55
+ puts 'Running with provided token...'
56
+ elsif nil != options[:username] && nil != options[:password]
57
+ github = Octokit::Client.new \
58
+ :login => options[:username],
59
+ :password => options[:password]
60
+
61
+ headers = Hash.new
62
+ if nil != options[:otp] then
63
+ headers['X-GitHub-OTP'] = options[:otp]
64
+ end
65
+
66
+ token = github.create_authorization \
67
+ :scopes => ["user"],
68
+ :note => "sync-git",
69
+ :headers => headers
70
+
71
+ puts "Created new token, use it to call sync-git again:"
72
+ puts
73
+ puts "\tsync-git -u #{user} -t #{token.token}"
74
+ puts
75
+ exit FURTHER_REQUESTS_REQUIRE_TOKEN
76
+ else
77
+ puts "Must provide either a username/token or username/password/otp combination to authenticate."
78
+ puts parser
79
+ exit MISSING_REQUIRED_CREDENTIALS
80
+ end
81
+
82
+ github.auto_paginate = true
83
+
84
+ repos = github.repos
85
+
86
+ # sync owned repos
87
+ owned_repos = repos.select {|x| !x.fork}
88
+ if options[:repo] != nil then
89
+ owned_repos.select! {|x| x.name == options[:repo]}
90
+ end
91
+ owned_repos.each do |owned_repo|
92
+ puts '---'
93
+ owned_repo_info = github.repo(owned_repo.id)
94
+ sync_repo(owned_repo_info, root_dir_path)
95
+ end
96
+
97
+ # get the list of forks to sync
98
+ forks = repos.select {|x| x.fork}
99
+ if options[:repo] != nil then
100
+ forks.select! {|x| x.name == options[:repo]}
101
+ end
102
+
103
+ # sync the forks
104
+ forks.each do |forked_repo|
105
+ puts '---'
106
+
107
+ forked_repo_info = github.repo(forked_repo.id)
108
+ sync_fork(forked_repo_info, root_dir_path)
109
+ end
@@ -0,0 +1,77 @@
1
+ require 'octokit'
2
+ require_relative 'echoexec'
3
+
4
+ def sync_repo repo_info, root_dir_path
5
+ name = repo_info.name
6
+ ssh_url = repo_info.ssh_url
7
+
8
+ path = "#{root_dir_path}/#{name}"
9
+ already_cloned = Dir.exist?(path)
10
+
11
+ # clone any forks not already cloned
12
+ unless already_cloned then
13
+ echo_and_exec "git clone #{ssh_url} #{path}"
14
+ end
15
+
16
+ # for repos that were cloned previously, update them by fast-forwarding the default branch and fetch all tags
17
+ if already_cloned then
18
+ Dir.chdir path do
19
+ echo_and_exec "git fetch && git fetch --tags && git pull --ff-only"
20
+ end
21
+ end
22
+ end
23
+
24
+
25
+ def sync_fork forked_repo_info, root_dir_path
26
+ upstream_ssh_url = forked_repo_info.source.ssh_url
27
+ original_owner = forked_repo_info.source.owner.login
28
+ name = forked_repo_info.name
29
+ fork_ssh_url = forked_repo_info.ssh_url
30
+
31
+ upstream_remote_name = 'upstream'
32
+ fork_remote_name = 'fork'
33
+ path = "#{root_dir_path}/_Forks/#{original_owner}/#{name}"
34
+ already_cloned = Dir.exist?(path)
35
+
36
+ # clone any forks not already cloned
37
+ unless already_cloned then
38
+ echo_and_exec "git clone #{fork_ssh_url} #{path}"
39
+ end
40
+
41
+ Dir.chdir path do
42
+ # if we just cloned the repo locally, set up both remotes
43
+ unless already_cloned then
44
+ echo_and_exec "git remote add #{upstream_remote_name} #{upstream_ssh_url}"
45
+ echo_and_exec "git remote rename origin #{fork_remote_name}"
46
+ end
47
+
48
+ # get the names of the default branches
49
+ fork_default_branch_name = `git remote show #{fork_remote_name} | grep "HEAD branch" | cut -d ":" -f 2`.strip
50
+ fork_default_local_branch_name = "#{fork_remote_name}_#{fork_default_branch_name}"
51
+ upstream_default_branch_name = `git remote show #{upstream_remote_name} | grep "HEAD branch" | cut -d ":" -f 2`.strip
52
+ upstream_default_local_branch_name = "#{upstream_remote_name}_#{upstream_default_branch_name}"
53
+
54
+ # if we just cloned the repo locally, set local default tracking branches
55
+ unless already_cloned then
56
+ # rename the cloned local default branch to reflect that it's tracking the fork remote's version
57
+ echo_and_exec "git branch -m #{fork_default_branch_name} #{fork_default_local_branch_name}"
58
+
59
+ # set up a local branch to track the upstream remote's default branch
60
+ echo_and_exec "git fetch #{upstream_remote_name}"
61
+ echo_and_exec "git checkout -b #{upstream_default_local_branch_name} #{upstream_remote_name}/#{upstream_default_branch_name}"
62
+
63
+ # push the local upstream default tracking branch to the fork's remote, so it also has a copy alongside it's default branch
64
+ echo_and_exec "git push #{fork_remote_name} HEAD:#{upstream_default_local_branch_name}"
65
+ end
66
+
67
+ # for repos that were cloned previously, update them by fast-forwarding both default branches and fetch all tags
68
+ if already_cloned then
69
+ echo_and_exec "git checkout #{fork_default_local_branch_name}"
70
+ echo_and_exec "git pull --ff-only #{fork_remote_name}"
71
+ echo_and_exec "git fetch --tags #{fork_remote_name}"
72
+
73
+ echo_and_exec "git checkout #{upstream_default_local_branch_name}"
74
+ echo_and_exec "git pull --ff-only #{upstream_remote_name}"
75
+ end
76
+ end
77
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tworingtools
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.2
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew McKnight
@@ -11,19 +11,19 @@ cert_chain: []
11
11
  date: 2020-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: github_api
14
+ name: octokit
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.19'
19
+ version: 4.20.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.19'
26
+ version: 4.20.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: '2.1'
41
41
  description: |2
42
42
  - xcsims: Delete all simulators and recreate one for each compatible platform and device type pairing.
43
- - sync-forks: Make sure all your GitHub forks are clones into a given directory, and have upstream remotes pointing to the repos that were forked.
43
+ - sync-git: Make sure all your GitHub repos are cloned into a given directory and keep them synced with upstream. Forks are maintained with a remote for both the fork and upstream, both remotes' default branches are tracked in local counterparts, and the upstream default branch is also pushed to the fork.
44
44
  - changetag: Extract changelog entries to write into git tag annotation messages.
45
45
  - prerelease-podspec: Branch and create/push a release candidate tag, modify the podspec to use that version tag, and try linting it.
46
46
  - release-podspec: Create a tag with the version and push it to repo origin, push podspec to CocoaPods trunk.
@@ -52,7 +52,7 @@ email: andrew@tworingsoft.com
52
52
  executables:
53
53
  - clean-rc-tags
54
54
  - xcsims
55
- - sync-forks
55
+ - sync-git
56
56
  - changetag
57
57
  - prerelease-podspec
58
58
  - release-podspec
@@ -69,11 +69,12 @@ files:
69
69
  - bin/prerelease-podspec
70
70
  - bin/release-podspec
71
71
  - bin/revert-failed-release-tag
72
- - bin/sync-forks
72
+ - bin/sync-git
73
73
  - bin/xcsims
74
74
  - lib/echoexec.rb
75
75
  - lib/errors.rb
76
76
  - lib/git_check.rb
77
+ - lib/git_helpers.rb
77
78
  homepage: https://github.com/TwoRingSoft/tools
78
79
  licenses:
79
80
  - MIT
data/bin/sync-forks DELETED
@@ -1,90 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- require 'github_api'
4
- require 'json'
5
- require 'optparse'
6
- require_relative '../lib/echoexec'
7
-
8
- # failure modes
9
- FURTHER_REQUESTS_REQUIRE_TOKEN = 65
10
- MISSING_REQUIRED_CREDENTIALS = 66
11
-
12
- options = {}
13
- parser = OptionParser.new do |opts|
14
- opts.banner = <<~BANNER
15
-
16
- Usage: sync-forks [options] <directory>
17
-
18
- <directory> is the path containing the directories holding your forks, and/or
19
- to where those you don't yet have should be cloned.
20
-
21
- Examples:
22
-
23
- sync-forks -u/--username <user> -p/--password <pass> [-o/--one-time-pw <otp>] .
24
- sync-forks -u/--username <user> -t/--token <token> .
25
- sync-forks -u/--username <user> -t/--token -n/--repo-name that-one-repo-I-forked <token> .
26
-
27
- If you already have a Personal Access Token, provide it in the second form.
28
- Otherwise, use the first form, which will register a new token for you named
29
- “sync-forks”. Then use that to invoke the program again. This is because
30
- requests using basic authentication (user/pass) are too rate limited.
31
-
32
- Options:
33
-
34
- BANNER
35
-
36
- opts.on('-uUSERNAME', '--username=USERNAME', 'GitHub username. Required for all invocations.') do |user| options[:username] = user end
37
- opts.on('-tTOKEN', '--token=TOKEN', 'GitHub personal access token. The primary way to use this program.') do |t| options[:token] = t end
38
- opts.on('-pPASSWORD', '--password=PASSWORD', 'GitHub password.') do |pass| options[:password] = pass end
39
- opts.on('-oOTP', '--one-time-pw=OTP', 'GitHub 2FA token, if you have it enabled.') do |otp| options[:otp] = otp end
40
- opts.on('-rREPO', '--repo-name=REPO', 'The name of a particular repository to sync.') do |repo| options[:repo] = repo end
41
- end
42
- parser.parse!
43
-
44
- github = nil
45
- if nil != options[:token] && nil != options[:username] then
46
- github = Github.new oauth_token: options[:token]
47
- elsif nil != options[:username] && nil != options[:password]
48
- github = Github.new do |config|
49
- config.basic_auth = "#{options[:username]}:#{options[:password]}"
50
- if nil != options[:otp] then
51
- config.connection_options = {headers: {"X-GitHub-OTP" => options[:otp]}}
52
- end
53
- end
54
- token = github.auth.create scopes: ['repo'], note: 'sync-forks3'
55
- puts "Created new token, use it to call sync-forks again:"
56
- puts
57
- puts "\tsync-forks -u #{user} -t #{token.token}"
58
- puts
59
- exit FURTHER_REQUESTS_REQUIRE_TOKEN
60
- else
61
- puts "Must provide either a username/token or username/password/otp combination to authenticate."
62
- puts parser
63
- exit MISSING_REQUIRED_CREDENTIALS
64
- end
65
-
66
- repos = github.repos.list user: options[:username], auto_pagination: true
67
- forks = repos.select {|x| x.fork}
68
-
69
- if options[:repo] != nil then
70
- forks.select! {|x| x.name == options[:repo]}
71
- end
72
-
73
- current_dir = Dir.new(ARGV[0])
74
- Dir.chdir current_dir
75
- forks.each do |forked|
76
- info = github.repos(user: options[:username], repo: forked.name).get
77
- fork_url = info.source.ssh_url
78
- name = forked.name
79
- url = forked.ssh_url
80
-
81
- puts '---'
82
- if current_dir.entries.include? name then
83
- puts "#{name} already exists."
84
- else
85
- echo_and_exec "git clone #{url}"
86
- Dir.chdir "#{name}"
87
- echo_and_exec "git remote add upstream #{fork_url}"
88
- Dir.chdir ".."
89
- end
90
- end