git-cipher 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/git-cipher +113 -19
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f65b15e499a669209962429243007bbdbbdaaeaa
4
- data.tar.gz: 21f8abf07fbcb9ef6c7c55c75f78530b965c8815
3
+ metadata.gz: 3d52bb65c34660958a91e70fef43d596610bede9
4
+ data.tar.gz: 7d83c6b13437a4fa8c1d166b76fda86abdf9a990
5
5
  SHA512:
6
- metadata.gz: 614dfcf2bb60ce0f183d20d3c23aa032f58b9b8e5b69bf6fa679c6bd3fd5a94625790099d327526fd7fe353f063fb95646bac1b71cae7ff9bc276005b49f244b
7
- data.tar.gz: dc7c936e44505b66408eb91c9c19fa736cee2805c5a44e131547ba93382b6ffce0aaf11abe451e983d18b2642f1ce9ae502e9ba148b719627aa37c75d943417d
6
+ metadata.gz: 53dec9da0d8e7bed2874793c25bde8e9fad254059bdccee796dec7b131a7191a6a863ced6873e797007167236de4a5f25dfc562b33e01a7506d98da32d7872cb
7
+ data.tar.gz: e1c65440edaeb32687e7b124f6c497bd8e9413f4ef7c7f92a23d55d13ab29691a820eed6918ca819f6273e4308fb8c1a4d9cabd5939b4661da25ee785766e2f2
@@ -4,13 +4,14 @@
4
4
  require 'fileutils'
5
5
  require 'pathname'
6
6
  require 'shellwords'
7
+ require 'tempfile'
7
8
 
8
9
  class Cipher
9
10
  EXTENSION = 'encrypted'
10
11
  DEFAULT_GPG_USER = 'greg@hurrell.net'
11
12
  DEFAULT_GPG_PRESET_COMMAND = '/usr/local/opt/gpg-agent/libexec/gpg-preset-passphrase'
12
13
  VALID_OPTIONS = %w[force help]
13
- VALID_SUBCOMMANDS = %w[decrypt encrypt help preset forget]
14
+ VALID_SUBCOMMANDS = %w[decrypt encrypt help log preset forget]
14
15
 
15
16
  def run
16
17
  send @subcommand
@@ -69,14 +70,7 @@ private
69
70
  end
70
71
 
71
72
  def decrypt!(file)
72
- unless ENV['GPG_AGENT_INFO']
73
- die <<-MSG
74
- GPG_AGENT_INFO not present in the environment.
75
- Try running:
76
- eval $(gpg-agent --daemon)
77
- #{command_name} preset
78
- MSG
79
- end
73
+ require_agent
80
74
 
81
75
  pathname = Pathname.new(file)
82
76
  basename = pathname.basename.to_s
@@ -104,16 +98,7 @@ private
104
98
  puts red('[warning: plain-text newer than ciphertext; skipping]')
105
99
  else
106
100
  print green('[decrypting ...')
107
- execute(%{
108
- #{escape command_path('gpg')}
109
- -q
110
- --yes
111
- --batch
112
- --no-tty
113
- --use-agent
114
- -o #{escape outfile}
115
- -d #{escape file}
116
- })
101
+ gpg_decrypt(file, outfile)
117
102
  if $?.success?
118
103
  puts green(' done]')
119
104
 
@@ -219,6 +204,19 @@ private
219
204
  puts
220
205
  end
221
206
 
207
+ def gpg_decrypt(file, outfile)
208
+ execute(%{
209
+ #{escape command_path('gpg')}
210
+ -q
211
+ --yes
212
+ --batch
213
+ --no-tty
214
+ --use-agent
215
+ -o #{escape outfile}
216
+ -d #{escape file}
217
+ })
218
+ end
219
+
222
220
  def gpg_preset_command
223
221
  ENV['GPG_PRESET_COMMAND'] || get_config('presetcommand') || DEFAULT_GPG_PRESET_COMMAND
224
222
  end
@@ -248,6 +246,64 @@ private
248
246
  "\e[2K\e[0G"
249
247
  end
250
248
 
249
+ def log
250
+ if @files.empty?
251
+ # TODO: would be nice to interleave these instead of doing them serially.
252
+ puts 'No explicit paths supplied: logging all matching files'
253
+ Dir["**/.*.#{EXTENSION}"].each { |file| log!(file) }
254
+ else
255
+ @files.each { |file| log!(file) }
256
+ end
257
+ end
258
+
259
+ def log!(file)
260
+ require_agent
261
+
262
+ commits = execute(%{
263
+ #{escape command_path('git')} log
264
+ --pretty=format:%H -- #{escape file}
265
+ }).split
266
+
267
+ commits.each do |commit|
268
+ files = []
269
+ begin
270
+ # Get plaintext "post" image.
271
+ files.push(post = temp_write(show(file, commit)))
272
+ files.push(
273
+ post_plaintext = temp_write(gpg_decrypt(post.path, '-'))
274
+ )
275
+
276
+ # Get plaintext "pre" image.
277
+ files.push(pre = temp_write(show(file, "#{commit}~")))
278
+ files.push(pre_plaintext = temp_write(
279
+ pre.size.zero? ? '' : gpg_decrypt(pre.path, '-')
280
+ ))
281
+
282
+ # Print commit message.
283
+ puts execute(%{
284
+ #{escape command_path('git')} --no-pager log
285
+ --color=always -1 #{commit}
286
+ })
287
+ puts
288
+
289
+ # Print pre-to-post diff.
290
+ puts execute(%{
291
+ #{escape command_path('git')} --no-pager diff
292
+ --color=always
293
+ #{escape pre_plaintext.path}
294
+ #{escape post_plaintext.path}
295
+ })
296
+ puts
297
+
298
+ ensure
299
+ files.each do |tempfile|
300
+ tempfile.close
301
+ tempfile.unlink
302
+ end
303
+ end
304
+ end
305
+ end
306
+
251
307
  def normalize_option(option)
252
308
  normal = option.dup
253
309
 
@@ -295,12 +351,40 @@ private
295
351
  colorize(string, 31)
296
352
  end
297
353
 
354
+ def require_agent
355
+ unless ENV['GPG_AGENT_INFO']
356
+ die <<-MSG
357
+ GPG_AGENT_INFO not present in the environment.
358
+ Try running this before retrying `#{command_name} #{@subcommand}`:
359
+ eval $(gpg-agent --daemon)
360
+ #{command_name} preset
361
+ MSG
362
+ end
363
+ end
364
+
365
+ def show(file, commit)
366
+ # Redirect stderr to /dev/null because the file might not have existed prior
367
+ # to this commit.
368
+ execute(%{
369
+ #{escape command_path('git')} show
370
+ #{commit}:#{escape file} 2> /dev/null
371
+ })
372
+ end
373
+
298
374
  def strip_heredoc(doc)
299
375
  # based on method of same name from Rails
300
376
  indent = doc.scan(/^[ \t]*(?=\S)/).map(&:size).min || 0
301
377
  doc.gsub(/^[ \t]{#{indent}}/, '')
302
378
  end
303
379
 
380
+ def temp_write(contents)
381
+ file = Tempfile.new('git-cipher-')
382
+ file.chmod(0600)
383
+ file.write(contents)
384
+ file.flush
385
+ file
386
+ end
387
+
304
388
  # Print usage information and exit.
305
389
  def usage(subcommand)
306
390
  case subcommand
@@ -354,6 +438,15 @@ private
354
438
 
355
439
  #{command_name} forget
356
440
  USAGE
441
+ when 'log'
442
+ puts strip_heredoc(<<-USAGE)
443
+ #{command_name} log FILE
444
+
445
+ Shows the log message and decrypted diff for FILE
446
+ (analogous to `git log -p -- FILE`).
447
+
448
+ #{command_name} log foo
449
+ USAGE
357
450
  when 'preset'
358
451
  puts strip_heredoc(<<-USAGE)
359
452
  #{command_name} preset
@@ -369,6 +462,7 @@ private
369
462
  #{command_name} decrypt
370
463
  #{command_name} encrypt
371
464
  #{command_name} forget
465
+ #{command_name} log
372
466
  #{command_name} preset
373
467
  USAGE
374
468
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-cipher
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Hurrell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-31 00:00:00.000000000 Z
11
+ date: 2016-02-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: "\n Provides a convenient workflow for working with encrypted files
14
14
  in a public\n Git repo. Delegates the underlying work of encryption/decryption