git_swap 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a991bd670b579c23e29abdcc9a98b7400d85447f7f48508a628e15a4adff303c
4
+ data.tar.gz: ceb06a4bab1f1ccb5e337d68a35c58798d9bc5bfd6329e373e57dc9883b1586e
5
+ SHA512:
6
+ metadata.gz: bcaea6bfa551bd6c58e8a1b93165046f7b77b121a73e0cb6c6b48cc5ea7d4d299fbc39d57bcdf34f3f88658de39d9ebd823047e20082d20f0d0a824eb2dceb9a
7
+ data.tar.gz: 4f11f20f56adbb64f8bc54589b38333444f00ed5cb0f2cba1849b54bc0e1d9b3656e4a97cc695898debb35b0b43d53e00d2254a316d7309cbd2edfca7262e885
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/git_swap'
3
+
4
+ GitSwap::Swapper.new(ARGV).run
@@ -0,0 +1,4 @@
1
+ require_relative 'git_swap/swapper'
2
+ require_relative 'git_swap/git_helper'
3
+ require_relative 'git_swap/options'
4
+ require_relative 'git_swap/config'
@@ -0,0 +1,130 @@
1
+ require 'yaml'
2
+
3
+ module GitSwap
4
+ class Config
5
+ attr_reader :profiles, :selected_profile
6
+ def initialize(args)
7
+ @profiles = load!
8
+ @args = args
9
+ @selected_profile = get_profile(args)
10
+ end
11
+
12
+ def get_profile(args)
13
+ args.detect {|a| !a.start_with? '-'}
14
+ end
15
+
16
+ def username
17
+ profiles[selected_profile]["username"]
18
+ end
19
+
20
+ def email
21
+ profiles[selected_profile]["email"]
22
+ end
23
+
24
+ def name
25
+ profiles[selected_profile]["name"]
26
+ end
27
+
28
+ def ssh
29
+ profiles[selected_profile]["ssh"]
30
+ end
31
+
32
+ def ssh_command
33
+ "ssh -i #{ssh}"
34
+ end
35
+
36
+ def profile
37
+ @selected_profile
38
+ end
39
+
40
+ def valid_profile?
41
+ if profiles.has_key?(selected_profile)
42
+ return true
43
+ else
44
+ puts "Profile '#{selected_profile}' not found!"
45
+ return false
46
+ end
47
+ end
48
+
49
+ def configure!
50
+ @profiles = build_profiles
51
+ write_profiles_to_config_file if @profiles.any?
52
+ end
53
+
54
+ def edit!
55
+ system("#{ENV['EDITOR']} '#{File.expand_path('~/.gitswap')}'")
56
+ end
57
+
58
+ def build_profiles
59
+ puts "How many profiles would you like to create?"
60
+ profile_count = STDIN.gets.chomp.to_i
61
+ profiles = Array.new(profile_count, {})
62
+ current = 1
63
+ profiles.map do |profile|
64
+ puts "\n#{ordinal(current)} profile name (e.g. 'work' or 'personal'):"
65
+ profile[:profile_name] = STDIN.gets.chomp
66
+ puts "Git username for #{profile[:profile_name]}:"
67
+ profile[:git_username] = STDIN.gets.chomp
68
+ puts "Git email for #{profile[:profile_name]}:"
69
+ profile[:git_email] = STDIN.gets.chomp
70
+ puts "Git name for #{profile[:profile_name]}:"
71
+ profile[:git_name] = STDIN.gets.chomp
72
+ puts "Path to ssh key for #{profile[:profile_name]} (e.g. '~/.ssh/id_rsa'):"
73
+ profile[:ssh_key] = STDIN.gets.chomp
74
+
75
+ current +=1
76
+ profile.dup
77
+ end
78
+ rescue Interrupt
79
+ return {}
80
+ end
81
+
82
+ def ordinal(number)
83
+ # Source: https://github.com/infertux/ordinalize_full
84
+ abs_number = number.abs
85
+ suffix = if (11..13).cover?(abs_number % 100)
86
+ "th"
87
+ else
88
+ case abs_number % 10
89
+ when 1 then "st"
90
+ when 2 then "nd"
91
+ when 3 then "rd"
92
+ else "th"
93
+ end
94
+ end
95
+ "#{abs_number}#{suffix}"
96
+ end
97
+
98
+ def write_profiles_to_config_file
99
+ File.open(File.expand_path('~/.gitswap'), 'w') do |file|
100
+ profiles.each do |profile|
101
+ file.write "#{profile[:profile_name]}:\n"
102
+ file.write " username: #{profile[:git_username]}\n"
103
+ file.write " email: #{profile[:git_email]}\n"
104
+ file.write " name: #{profile[:git_name]}\n"
105
+ file.write " ssh: #{profile[:ssh_key]}\n"
106
+ end
107
+ end
108
+ end
109
+
110
+ def print_list
111
+ profiles = @profiles.map do |key, value|
112
+ prefix = value["username"] == current_git_username ? "=>" : " "
113
+ "#{prefix} #{key}"
114
+ end
115
+ puts profiles
116
+ puts "\n# => - current" if @profiles.any? {|key, value| value["username"] == current_git_username}
117
+ end
118
+
119
+ private
120
+
121
+ def load!
122
+ # TODO: RCR - Handle missing or empty config file
123
+ YAML.load_file(File.expand_path('~/.gitswap')) || {}
124
+ end
125
+
126
+ def current_git_username
127
+ `git config user.username`.chomp
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,44 @@
1
+ module GitSwap
2
+ class GitHelper
3
+ def self.git_repo?
4
+ !find_git_repo.nil?
5
+ end
6
+
7
+ private
8
+ # Copied from https://gist.github.com/nickmccurdy/8466084
9
+ # Script: Find the current git repository
10
+ # Based on https://github.com/mojombo/grit/pull/178 by https://github.com/derricks
11
+
12
+ # Returns true if the given path represents a root directory (/ or C:/)
13
+ def self.root_directory?(file_path)
14
+ # Implementation inspired by http://stackoverflow.com/a/4969416:
15
+ # Does file + ".." resolve to the same directory as file_path?
16
+ File.directory?(file_path) &&
17
+ File.expand_path(file_path) == File.expand_path(File.join(file_path, '..'))
18
+ end
19
+
20
+ # Returns the git root directory given a path inside the repo. Returns nil if
21
+ # the path is not in a git repo.
22
+ def self.find_git_repo(start_path = '.')
23
+ raise NoSuchPathError unless File.exists?(start_path)
24
+
25
+ current_path = File.expand_path(start_path)
26
+
27
+ # for clarity: set to an explicit nil and then just return whatever
28
+ # the current value of this variable is (nil or otherwise)
29
+ return_path = nil
30
+
31
+ until root_directory?(current_path)
32
+ if File.exists?(File.join(current_path, '.git'))
33
+ # done
34
+ return_path = current_path
35
+ break
36
+ else
37
+ # go up a directory and try again
38
+ current_path = File.dirname(current_path)
39
+ end
40
+ end
41
+ return_path
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,104 @@
1
+ module GitSwap
2
+ class Options
3
+ attr_reader :args
4
+ def initialize(args)
5
+ @args = args
6
+ end
7
+
8
+ def flags
9
+ @flags ||= args.select do |arg|
10
+ arg.match(/\A\-[ceglv]{1}\z/) ||
11
+ arg.match(/\A\-\-(config|edit|global|list|verbose|version){1}\z/)
12
+ end
13
+ end
14
+
15
+ def valid_args?
16
+ if config?
17
+ return true
18
+ elsif edit?
19
+ return true
20
+ elsif list?
21
+ return true
22
+ elsif version?
23
+ return true
24
+ elsif verbose?
25
+ return true
26
+ elsif no_flags?
27
+ return true
28
+ elsif one_flag? && !flag_only?
29
+ return true
30
+ elsif usage?
31
+ return true
32
+ else
33
+ puts "Invalid args"
34
+ return false
35
+ end
36
+ end
37
+
38
+ def usage?
39
+ args.count == 0
40
+ end
41
+
42
+ def config?
43
+ config_flag? && args.count == 1
44
+ end
45
+
46
+ def edit?
47
+ edit_flag? && args.count == 1
48
+ end
49
+
50
+ def list?
51
+ list_flag? && args.count == 1
52
+ end
53
+
54
+ def version?
55
+ version_flag? && args.count == 1
56
+ end
57
+
58
+ def global?
59
+ (flags.include? '-g') || (flags.include? '--global')
60
+ end
61
+
62
+ def verbose?
63
+ verbose_flag? && args.count > 1
64
+ end
65
+
66
+ private
67
+
68
+ def config_flag?
69
+ (flags.include? '-c') || (flags.include? '--config')
70
+ end
71
+
72
+ def edit_flag?
73
+ (flags.include? '-e') || (flags.include? '--edit')
74
+ end
75
+
76
+ def list_flag?
77
+ (flags.include? '-l') || (flags.include? '--list')
78
+ end
79
+
80
+ def version_flag?
81
+ ((flags.include? '-v') && args.count == 1) || (flags.include? '--version')
82
+ end
83
+
84
+ def verbose_flag?
85
+ ((flags.include? '-v') && args.count > 1) || (flags.include? '--verbose')
86
+ end
87
+
88
+ def no_flags?
89
+ args.length == 1 && flag_count(args) == 0
90
+ end
91
+
92
+ def one_flag?
93
+ args.length == 2 && flag_count(args) == 1
94
+ end
95
+
96
+ def flag_only?
97
+ list_flag? || config_flag? || version_flag?
98
+ end
99
+
100
+ def flag_count(args)
101
+ args.count {|a| a.start_with? '-'}
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,118 @@
1
+ require_relative './version'
2
+ require 'active_support/core_ext/module/delegation'
3
+
4
+ module GitSwap
5
+ class Swapper
6
+ attr_reader :config, :options
7
+ delegate :usage?, :config?, :edit?, :list?, :version?, :global?, to: :options
8
+ delegate :profile, :name, :username, :email, :ssh, :ssh_command, :print_list, :configure!, :edit!, :valid_profile?, to: :config
9
+
10
+ def initialize(args)
11
+ raise ArgumentError unless args.is_a? Array
12
+ @options = GitSwap::Options.new(args)
13
+ @config = GitSwap::Config.new(args)
14
+ end
15
+
16
+ def run
17
+ return unless options.valid_args?
18
+ if usage?
19
+ print_usage
20
+ elsif config?
21
+ configure!
22
+ elsif edit?
23
+ edit!
24
+ elsif list?
25
+ print_list
26
+ elsif version?
27
+ print_version
28
+ else
29
+ set!
30
+ end
31
+ end
32
+
33
+ def git_repo?
34
+ if GitHelper.git_repo? || global?
35
+ return true
36
+ else
37
+ puts "Not a git repo. Please run from a git repo or run with `-g` to update global settings."
38
+ return false
39
+ end
40
+ end
41
+
42
+ def set!
43
+ return unless valid_profile? && git_repo?
44
+
45
+ set_git_config
46
+ set_ssh
47
+ print_settings
48
+ end
49
+
50
+ def print_usage
51
+ puts usage
52
+ end
53
+
54
+ def print_version
55
+ puts GitSwap::VERSION
56
+ end
57
+
58
+ def print_settings
59
+ if options.verbose?
60
+ puts "\nGit Config:"
61
+ puts `git config #{git_config_flag} -l --show-origin | grep user`
62
+ puts "\nSSH:"
63
+ puts `ssh-add -l`
64
+ else
65
+ puts "Swapped to profile #{profile}"
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def git_config_flag
72
+ @git_config_flag ||= global? ? '--global' : ''
73
+ end
74
+
75
+ def set_git_config
76
+ `git config #{git_config_flag} user.name "#{name}"`
77
+ `git config #{git_config_flag} user.username "#{username}"`
78
+ `git config #{git_config_flag} user.email "#{email}"`
79
+ end
80
+
81
+ def set_ssh
82
+ `git config #{git_config_flag} core.sshCommand "#{ssh_command}"`
83
+ if options.verbose?
84
+ `ssh-add #{ssh}`
85
+ else
86
+ `ssh-add #{ssh} 2>/dev/null`
87
+ end
88
+ end
89
+
90
+ def usage
91
+ <<~USAGE
92
+ usage: git swap [-c | --config] [-e | --edit] [-l | --list] [-v | --version]
93
+ <profile> [-v | --verbose] [-g | --global]
94
+
95
+ configure profiles
96
+ git swap -c
97
+
98
+ open configuration file in editor
99
+ git swap -e
100
+
101
+ swap to a profile for local development only
102
+ git swap <profile>
103
+
104
+ swap to a profile globally
105
+ git swap -g <profile>
106
+
107
+ swap to a profile and see all output
108
+ git swap -v <profile>
109
+
110
+ see available profiles
111
+ git swap -l
112
+
113
+ view installed gem version
114
+ git swap -v
115
+ USAGE
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,3 @@
1
+ module GitSwap
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git_swap
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Randall Reed, Jr.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-07-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.1.4
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.1.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec_junit_formatter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.4.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.4.1
83
+ description: Easily swap between git profiles (name, username, email) and ssh keys
84
+ email:
85
+ - randallreedjr@gmail.com
86
+ executables:
87
+ - git-swap
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - bin/git-swap
92
+ - lib/git_swap.rb
93
+ - lib/git_swap/config.rb
94
+ - lib/git_swap/git_helper.rb
95
+ - lib/git_swap/options.rb
96
+ - lib/git_swap/swapper.rb
97
+ - lib/git_swap/version.rb
98
+ homepage: https://www.github.com/randallreedjr/git_swap
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubygems_version: 3.0.3
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: Swap between git profiles
121
+ test_files: []