git-cipher 0.1 → 0.2

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.
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