snapgit 0.6.4
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 +7 -0
- data/.coveralls.yml +1 -0
- data/.editorconfig +17 -0
- data/.gitattributes +1 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +10 -0
- data/.rubocop_todo.yml +57 -0
- data/.travis.yml +42 -0
- data/Gemfile +4 -0
- data/LICENSE +165 -0
- data/README.md +28 -0
- data/Rakefile +79 -0
- data/bin/lolcommits +335 -0
- data/bin/snapgit +14 -0
- data/config/cucumber.yml +2 -0
- data/features/bugs.feature +63 -0
- data/features/lolcommits.feature +286 -0
- data/features/plugins.feature +20 -0
- data/features/step_definitions/lolcommits_steps.rb +142 -0
- data/features/support/env.rb +61 -0
- data/features/support/path_helpers.rb +39 -0
- data/lib/core_ext/class.rb +8 -0
- data/lib/core_ext/mini_magick/utilities.rb +15 -0
- data/lib/lolcommits.rb +34 -0
- data/lib/lolcommits/capturer.rb +24 -0
- data/lib/lolcommits/capturer/capture_cygwin.rb +22 -0
- data/lib/lolcommits/capturer/capture_fake.rb +9 -0
- data/lib/lolcommits/capturer/capture_linux.rb +45 -0
- data/lib/lolcommits/capturer/capture_linux_animated.rb +72 -0
- data/lib/lolcommits/capturer/capture_mac.rb +23 -0
- data/lib/lolcommits/capturer/capture_mac_animated.rb +73 -0
- data/lib/lolcommits/capturer/capture_windows.rb +22 -0
- data/lib/lolcommits/cli/fatals.rb +77 -0
- data/lib/lolcommits/cli/launcher.rb +29 -0
- data/lib/lolcommits/cli/process_runner.rb +48 -0
- data/lib/lolcommits/cli/timelapse_gif.rb +45 -0
- data/lib/lolcommits/configuration.rb +138 -0
- data/lib/lolcommits/git_info.rb +82 -0
- data/lib/lolcommits/init.rb +121 -0
- data/lib/lolcommits/installation.rb +128 -0
- data/lib/lolcommits/platform.rb +127 -0
- data/lib/lolcommits/plugin.rb +130 -0
- data/lib/lolcommits/plugins/dot_com.rb +50 -0
- data/lib/lolcommits/plugins/lol_protonet.rb +68 -0
- data/lib/lolcommits/plugins/lol_slack.rb +68 -0
- data/lib/lolcommits/plugins/lol_tumblr.rb +127 -0
- data/lib/lolcommits/plugins/lol_twitter.rb +155 -0
- data/lib/lolcommits/plugins/lol_yammer.rb +85 -0
- data/lib/lolcommits/plugins/lolsrv.rb +59 -0
- data/lib/lolcommits/plugins/loltext.rb +147 -0
- data/lib/lolcommits/plugins/snapgit.rb +167 -0
- data/lib/lolcommits/plugins/tranzlate.rb +115 -0
- data/lib/lolcommits/plugins/uploldz.rb +65 -0
- data/lib/lolcommits/runner.rb +134 -0
- data/lib/lolcommits/version.rb +5 -0
- data/snapgit.gemspec +63 -0
- data/test/images/test_image.jpg +0 -0
- data/test/lolcommits_test.rb +35 -0
- data/test/plugins_test.rb +52 -0
- data/vendor/ext/CommandCam/COPYING +674 -0
- data/vendor/ext/CommandCam/CommandCam.exe +0 -0
- data/vendor/ext/CommandCam/LICENSE +16 -0
- data/vendor/ext/imagesnap/ReadMeOrDont.rtf +117 -0
- data/vendor/ext/imagesnap/imagesnap +0 -0
- data/vendor/ext/videosnap/videosnap +0 -0
- data/vendor/fonts/Lato.ttf +0 -0
- data/vendor/logos/Snapgit.png +0 -0
- metadata +509 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'lolcommits/platform'
|
|
3
|
+
require 'methadone'
|
|
4
|
+
|
|
5
|
+
module Lolcommits
|
|
6
|
+
module CLI
|
|
7
|
+
# Helper methods for failing on error conditions in the lolcommits CLI.
|
|
8
|
+
module Fatals
|
|
9
|
+
include Lolcommits
|
|
10
|
+
include Methadone::CLILogging
|
|
11
|
+
|
|
12
|
+
# Check for platform related conditions that could prevent lolcommits from
|
|
13
|
+
# working properly.
|
|
14
|
+
#
|
|
15
|
+
# Die with an informative error message if any occur.
|
|
16
|
+
def self.die_on_fatal_platform_conditions!
|
|
17
|
+
# make sure the capture binaries are in a good state
|
|
18
|
+
if Platform.platform_mac?
|
|
19
|
+
%w(imagesnap videosnap).each do |executable|
|
|
20
|
+
next if File.executable? File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'ext', executable, executable)
|
|
21
|
+
fatal "Couldn't properly execute #{executable} for some reason, "\
|
|
22
|
+
'please file a bug?!'
|
|
23
|
+
exit 1
|
|
24
|
+
end
|
|
25
|
+
elsif Platform.platform_linux?
|
|
26
|
+
unless Platform.command_which('mplayer')
|
|
27
|
+
fatal "Couldn't find mplayer in your PATH!"
|
|
28
|
+
exit 1
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# make sure we can find the default font
|
|
33
|
+
unless File.readable? Lolcommits::Loltext::DEFAULT_FONT_PATH
|
|
34
|
+
fatal "Couldn't properly read Impact font from gem package, "\
|
|
35
|
+
'please file a bug?!'
|
|
36
|
+
exit 1
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# make sure imagemagick is around and good to go
|
|
40
|
+
unless Platform.valid_imagemagick_installed?
|
|
41
|
+
fatal 'FATAL: ImageMagick does not appear to be properly installed!'\
|
|
42
|
+
'(or version is too old)'
|
|
43
|
+
exit 1
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# check for a error condition with git config affecting ruby-git
|
|
47
|
+
if Platform.git_config_color_always?
|
|
48
|
+
fatal 'Due to a bug in the ruby-git library, git config for color.ui'\
|
|
49
|
+
" cannot be set to 'always'."
|
|
50
|
+
fatal "Try setting it to 'auto' instead!"
|
|
51
|
+
exit 1
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Die with an informative error message if ffmpeg is not installed.
|
|
56
|
+
# This is only used for certain functions (such as animation), so only run
|
|
57
|
+
# this when you know the user wants to perform one of them.
|
|
58
|
+
def self.die_if_no_valid_ffmpeg_installed!
|
|
59
|
+
unless Platform.valid_ffmpeg_installed?
|
|
60
|
+
fatal 'FATAL: ffmpeg does not appear to be properly installed!'
|
|
61
|
+
exit 1
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# If we are not in a git repo, we can't do git related things!
|
|
66
|
+
# Die with an informative error message in that case.
|
|
67
|
+
def self.die_if_not_git_repo!
|
|
68
|
+
debug 'Checking for valid git repo'
|
|
69
|
+
Git.open('.') # FIXME: should be extracted to GitInfo class
|
|
70
|
+
rescue ArgumentError
|
|
71
|
+
# ruby-git throws an argument error if path isnt for a valid git repo.
|
|
72
|
+
fatal "Erm? Can't do that since we're not in a valid git repository!"
|
|
73
|
+
exit 1
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'launchy'
|
|
3
|
+
|
|
4
|
+
module Lolcommits
|
|
5
|
+
module CLI
|
|
6
|
+
# Helper class for wrapping the opening of files on the desktop in a
|
|
7
|
+
# cross-platform way.
|
|
8
|
+
#
|
|
9
|
+
# Right now this is mostly just a wrapper for Launchy, in case we want
|
|
10
|
+
# to factor out it's dependency later or swap it out.
|
|
11
|
+
class Launcher
|
|
12
|
+
def self.open_image(path)
|
|
13
|
+
open_with_launchy(path)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.open_folder(path)
|
|
17
|
+
open_with_launchy(path)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Opens with Launchy, which knows how to open pretty much anything
|
|
21
|
+
# local files, urls, etc.
|
|
22
|
+
#
|
|
23
|
+
# Private so we replace it later easier if we want.
|
|
24
|
+
def self.open_with_launchy(thing)
|
|
25
|
+
Launchy.open(thing)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
module Lolcommits
|
|
4
|
+
module CLI
|
|
5
|
+
# Helper class for forking lolcommits process to the background (or not).
|
|
6
|
+
class ProcessRunner
|
|
7
|
+
# Initializes a new process runner.
|
|
8
|
+
#
|
|
9
|
+
# @param config [Lolcommits::Configuration]
|
|
10
|
+
def initialize(config)
|
|
11
|
+
@configuration = config
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Forks the lolcommits process if requested.
|
|
15
|
+
#
|
|
16
|
+
# Writes the PID of the lolcommits process to the filesystem when
|
|
17
|
+
# backgrounded, for monitoring purposes.
|
|
18
|
+
#
|
|
19
|
+
# @param please [Boolean] whether or not to fork lolcommits process
|
|
20
|
+
# @yield the main event loop for lolcommits
|
|
21
|
+
def fork_me?(please, &block)
|
|
22
|
+
if please
|
|
23
|
+
$stdout.sync = true
|
|
24
|
+
write_pid fork {
|
|
25
|
+
yield block
|
|
26
|
+
delete_pid
|
|
27
|
+
}
|
|
28
|
+
else
|
|
29
|
+
yield block
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def write_pid(pid)
|
|
36
|
+
File.open(pid_file, 'w') { |f| f.write(pid) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def delete_pid
|
|
40
|
+
File.delete(pid_file) if File.exist?(pid_file)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def pid_file
|
|
44
|
+
File.join(@configuration.loldir, 'lolcommits.pid')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'lolcommits/cli/fatals'
|
|
3
|
+
|
|
4
|
+
require 'mini_magick'
|
|
5
|
+
|
|
6
|
+
module Lolcommits
|
|
7
|
+
module CLI
|
|
8
|
+
# Creates an animated timeline GIF of lolcommits history.
|
|
9
|
+
class TimelapseGif
|
|
10
|
+
# param config [Lolcommits::Configuration]
|
|
11
|
+
def initialize(config)
|
|
12
|
+
@configuration = config
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Runs the history timeline animator task thingy
|
|
16
|
+
# param args [String] the arg passed to the gif command on CLI (optional)
|
|
17
|
+
def run(args = nil)
|
|
18
|
+
Fatals.die_if_not_git_repo!
|
|
19
|
+
|
|
20
|
+
case args
|
|
21
|
+
when 'today'
|
|
22
|
+
lolimages = @configuration.jpg_images_today
|
|
23
|
+
filename = "#{Date.today}.gif"
|
|
24
|
+
else
|
|
25
|
+
lolimages = @configuration.jpg_images
|
|
26
|
+
filename = 'archive.gif'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if lolimages.empty?
|
|
30
|
+
warn 'No lolcommits have been captured for this time yet.'
|
|
31
|
+
exit 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
puts '*** Generating animated gif.'
|
|
35
|
+
|
|
36
|
+
gif = MiniMagick::Image.new File.join @configuration.archivedir, filename
|
|
37
|
+
|
|
38
|
+
# This is for ruby 1.8.7, *lolimages just doesn't work with ruby 187
|
|
39
|
+
gif.run_command('convert', *['-delay', '50', '-loop', '0', lolimages, gif.path.to_s].flatten)
|
|
40
|
+
|
|
41
|
+
puts "*** #{gif.path} generated."
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
2
|
+
|
|
3
|
+
module Lolcommits
|
|
4
|
+
class Configuration
|
|
5
|
+
LOLCOMMITS_BASE = ENV['LOLCOMMITS_DIR'] || File.join(ENV['HOME'], '.lolcommits')
|
|
6
|
+
LOLCOMMITS_ROOT = File.join(File.dirname(__FILE__), '../..')
|
|
7
|
+
attr_writer :loldir
|
|
8
|
+
|
|
9
|
+
def initialize(attributes = {})
|
|
10
|
+
attributes.each do |attr, val|
|
|
11
|
+
send("#{attr}=", val)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def read_configuration
|
|
16
|
+
return unless File.exist?(configuration_file)
|
|
17
|
+
YAML.load(File.open(configuration_file))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def configuration_file
|
|
21
|
+
"#{loldir}/config.yml"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def loldir
|
|
25
|
+
return @loldir if @loldir
|
|
26
|
+
basename ||= File.basename(Git.open('.').dir.to_s).sub(/^\./, 'dot')
|
|
27
|
+
basename.sub!(/ /, '-')
|
|
28
|
+
@loldir = Configuration.loldir_for(basename)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def archivedir
|
|
32
|
+
dir = File.join(loldir, 'archive')
|
|
33
|
+
FileUtils.mkdir_p dir unless File.directory? dir
|
|
34
|
+
dir
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def most_recent
|
|
38
|
+
Dir.glob(File.join(loldir, '*.{jpg,gif}')).max_by { |f| File.mtime(f) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def jpg_images
|
|
42
|
+
Dir.glob(File.join(loldir, '*.jpg')).sort_by { |f| File.mtime(f) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def jpg_images_today
|
|
46
|
+
jpg_images.select { |f| Date.parse(File.mtime(f).to_s) == Date.today }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def raw_image(image_file_type = 'jpg')
|
|
50
|
+
File.join loldir, "tmp_snapshot.#{image_file_type}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def main_image(commit_sha, image_file_type = 'jpg')
|
|
54
|
+
File.join loldir, "#{commit_sha}.#{image_file_type}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def video_loc
|
|
58
|
+
File.join(loldir, 'tmp_video.mov')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def frames_loc
|
|
62
|
+
File.join(loldir, 'tmp_frames')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def puts_plugins
|
|
66
|
+
puts "Available plugins: #{Lolcommits::Runner.plugins.map(&:name).join(', ')}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def ask_for_plugin_name
|
|
70
|
+
puts_plugins
|
|
71
|
+
print 'Name of plugin to configure: '
|
|
72
|
+
STDIN.gets.strip
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def find_plugin(plugin_name)
|
|
76
|
+
Lolcommits::Runner.plugins.each do |plugin|
|
|
77
|
+
return plugin.new(nil) if plugin.name == plugin_name
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
puts "Unable to find plugin: '#{plugin_name}'"
|
|
81
|
+
puts_plugins
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Modified by Felix to return useful values
|
|
85
|
+
def do_configure!(plugin_name)
|
|
86
|
+
plugin_name = ask_for_plugin_name if plugin_name.to_s.strip.empty?
|
|
87
|
+
|
|
88
|
+
plugin = find_plugin(plugin_name)
|
|
89
|
+
return unless plugin
|
|
90
|
+
config = read_configuration || {}
|
|
91
|
+
plugin_config = plugin.configure_options!
|
|
92
|
+
# having a plugin_config, means configuring went OK
|
|
93
|
+
if plugin_config
|
|
94
|
+
# save plugin and print config
|
|
95
|
+
config[plugin_name] = plugin_config
|
|
96
|
+
save(config)
|
|
97
|
+
puts self
|
|
98
|
+
puts "\nSuccessfully configured plugin: #{plugin_name} at path '#{configuration_file}'"
|
|
99
|
+
return configuration_file
|
|
100
|
+
else
|
|
101
|
+
puts "\nAborted plugin configuration for: #{plugin_name}"
|
|
102
|
+
return false
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def save(config)
|
|
107
|
+
config_file_contents = config.to_yaml
|
|
108
|
+
File.open(configuration_file, 'w') do |f|
|
|
109
|
+
f.write(config_file_contents)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def to_s
|
|
114
|
+
read_configuration.to_yaml.to_s
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# class methods
|
|
118
|
+
|
|
119
|
+
def self.loldir_for(basename)
|
|
120
|
+
loldir = File.join(LOLCOMMITS_BASE, basename)
|
|
121
|
+
|
|
122
|
+
if File.directory? loldir
|
|
123
|
+
begin
|
|
124
|
+
# ensure 755 permissions for loldir
|
|
125
|
+
File.chmod(0755, loldir)
|
|
126
|
+
rescue Errno::EPERM
|
|
127
|
+
# abort if permissions cannot be met
|
|
128
|
+
puts "FATAL: directory '#{loldir}' should be present and writeable by user '#{ENV['USER']}'"
|
|
129
|
+
puts 'Try changing the directory permissions to 755'
|
|
130
|
+
exit 1
|
|
131
|
+
end
|
|
132
|
+
else
|
|
133
|
+
FileUtils.mkdir_p loldir
|
|
134
|
+
end
|
|
135
|
+
loldir
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
2
|
+
module Lolcommits
|
|
3
|
+
class GitInfo
|
|
4
|
+
include Methadone::CLILogging
|
|
5
|
+
attr_accessor :sha, :message, :repo_internal_path, :repo, :url,
|
|
6
|
+
:author_name, :author_email, :branch
|
|
7
|
+
|
|
8
|
+
GIT_URL_REGEX = %r{.*[:]([\/\w\-]*).git}
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
debug 'GitInfo: parsed the following values from commit:'
|
|
12
|
+
debug "GitInfo: \t#{message}"
|
|
13
|
+
debug "GitInfo: \t#{sha}"
|
|
14
|
+
debug "GitInfo: \t#{repo_internal_path}"
|
|
15
|
+
debug "GitInfo: \t#{repo}"
|
|
16
|
+
debug "GitInfo: \t#{branch}"
|
|
17
|
+
debug "GitInfo: \t#{author_name}" if author_name
|
|
18
|
+
debug "GitInfo: \t#{author_email}" if author_email
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def branch
|
|
22
|
+
@branch ||= repository.current_branch
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def message
|
|
26
|
+
@message ||= begin
|
|
27
|
+
message = last_commit.message || ''
|
|
28
|
+
message.split("\n").first
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def sha
|
|
33
|
+
@sha ||= last_commit.sha[0..10]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def repo_internal_path
|
|
37
|
+
@repo_internal_path ||= repository.repo.path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def url
|
|
41
|
+
@url ||= begin
|
|
42
|
+
remote_https_url(repository.remote.url) if repository.remote
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def repo
|
|
47
|
+
@repo ||= begin
|
|
48
|
+
if repository.remote && repository.remote.url
|
|
49
|
+
match = repository.remote.url.match(GIT_URL_REGEX)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
if match
|
|
53
|
+
match[1]
|
|
54
|
+
elsif !repository.repo.path.empty?
|
|
55
|
+
repository.repo.path.split(File::SEPARATOR)[-2]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def author_name
|
|
61
|
+
@author_name ||= last_commit.author.name if last_commit.author
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def author_email
|
|
65
|
+
@author_email ||= last_commit.author.email if last_commit.author
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def remote_https_url(url)
|
|
71
|
+
url.tr(':', '/').tr(/^git@/, 'https://').tr(/\.git$/, '') + '/commit/'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def repository(path = '.')
|
|
75
|
+
@repository ||= Git.open(path)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def last_commit
|
|
79
|
+
@commit ||= repository.log.first
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
2
|
+
module Lolcommits
|
|
3
|
+
class Init
|
|
4
|
+
require 'lolcommits'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'tmpdir'
|
|
7
|
+
|
|
8
|
+
# rubocop:disable Metrics/MethodLength
|
|
9
|
+
def self.run_setup(lolcommits_binary)
|
|
10
|
+
require 'io/console'
|
|
11
|
+
@lolcommits_binary = lolcommits_binary
|
|
12
|
+
set_lolcommits_env_config
|
|
13
|
+
|
|
14
|
+
puts 'This setup will run through the necessary steps to get you up and running'
|
|
15
|
+
puts 'Please follow the wizard to authenticate Twitter and Gravatar'
|
|
16
|
+
puts "If you don't want to use Gravatar, just don't provide any values"
|
|
17
|
+
puts 'Confirm with Enter'
|
|
18
|
+
STDIN.getch
|
|
19
|
+
|
|
20
|
+
Dir.mktmpdir do |_tmp_dir|
|
|
21
|
+
`git init` # just to make lolcommits believe we're in a git folder
|
|
22
|
+
result = request_auth_tokens
|
|
23
|
+
|
|
24
|
+
if result == false
|
|
25
|
+
puts 'Setup failed - please try again'
|
|
26
|
+
abort
|
|
27
|
+
end
|
|
28
|
+
@config_path = result
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
puts '-'
|
|
32
|
+
puts 'Successfully generated keys... now setting up your git projects:'
|
|
33
|
+
puts '-'
|
|
34
|
+
|
|
35
|
+
puts 'Do you want snapgit to automatically enable itself for all local git repositories? (y/n)'
|
|
36
|
+
if STDIN.getch.strip == 'y'
|
|
37
|
+
enable_for_all_projects
|
|
38
|
+
elsif File.directory?('.git')
|
|
39
|
+
puts 'Do you want to enable snapgit just for the local directory? (y/n)'
|
|
40
|
+
if STDIN.getch.strip == 'y'
|
|
41
|
+
enable_for_local_folder
|
|
42
|
+
return
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
puts '-'
|
|
46
|
+
puts 'Please navigate to the project you want to enable snapgit for'
|
|
47
|
+
puts 'and run `snapgit init`'
|
|
48
|
+
abort
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
|
52
|
+
|
|
53
|
+
def self.set_lolcommits_env_config
|
|
54
|
+
ENV['LOLCOMMITS_INIT_PARAMS'] = ' --delay 1' # this is required to actually work on a Mac
|
|
55
|
+
ENV['LOLCOMMITS_INIT_PARAMS'] += ' --stealth' # we don't want any output
|
|
56
|
+
ENV['LOLCOMMITS_INIT_PARAMS'] += ' &' # this way the delay is not noticable
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @return (success or not)
|
|
60
|
+
def self.request_auth_tokens
|
|
61
|
+
$stdout.sync = true
|
|
62
|
+
Configuration.new.do_configure!('snapgit')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.enable_for_local_folder
|
|
66
|
+
enable_for_project('.')
|
|
67
|
+
puts "Successfully enabled snapgit 🎉"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.enable_for_all_projects
|
|
71
|
+
projs = git_projects
|
|
72
|
+
puts projs
|
|
73
|
+
puts 'Do you want to enable snapgit for all those repos? (y/n)'
|
|
74
|
+
abort unless STDIN.getch.strip == 'y'
|
|
75
|
+
|
|
76
|
+
projs.each do |current|
|
|
77
|
+
enable_for_project(current)
|
|
78
|
+
end
|
|
79
|
+
puts "Successfully enabled snapgit for #{projs.count} projects 🎉"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def self.enable_for_project(path)
|
|
83
|
+
puts "Enabling snapgit for '#{File.expand_path(path)}'..."
|
|
84
|
+
Dir.chdir(path) do
|
|
85
|
+
# Add the `lolcommits --capture` to the post-hook
|
|
86
|
+
Lolcommits::Installation.do_enable
|
|
87
|
+
|
|
88
|
+
# Copy the config.yml to the ~/.lolcommits/[project] folder
|
|
89
|
+
to_path = Lolcommits::Configuration.new.loldir # this will use the current dir by default
|
|
90
|
+
# rubocop:disable Lint/HandleExceptions
|
|
91
|
+
begin
|
|
92
|
+
FileUtils.cp(@config_path, to_path)
|
|
93
|
+
rescue ArgumentError # if the file is the same
|
|
94
|
+
end
|
|
95
|
+
# rubocop:enable Lint/HandleExceptions
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def self.git_projects
|
|
100
|
+
puts 'Searching for git repos'
|
|
101
|
+
# We're using README.md assuming that every repo has one
|
|
102
|
+
# This is due to Spotlight not finding hidden files (.git)
|
|
103
|
+
potential = `mdfind -name "README.md" -onlyin ~`.split("\n")
|
|
104
|
+
|
|
105
|
+
# After we have all README.md we look for a .git folder in
|
|
106
|
+
# each of those
|
|
107
|
+
potential.collect do |current|
|
|
108
|
+
path = File.expand_path('..', current)
|
|
109
|
+
path if File.directory?(File.join(path, '.git'))
|
|
110
|
+
end.delete_if(&:nil?)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Cheap monkey patching to not get any output when enabling lolcommits
|
|
116
|
+
module Lolcommits
|
|
117
|
+
class Installation
|
|
118
|
+
def self.info(_str)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|