Class: Dotgpg::Cli
- Inherits:
-
Thor
- Object
- Thor
- Dotgpg::Cli
- Includes:
- Thor::Actions
- Defined in:
- lib/dotgpg/cli.rb
Instance Method Summary collapse
- #add(file = nil) ⇒ Object
- #cat(*files) ⇒ Object
- #edit(*files) ⇒ Object
- #init(directory = ".") ⇒ Object
- #key ⇒ Object
- #merge(*files) ⇒ Object
- #rm(file = nil) ⇒ Object
- #unsafe_cat(*files) ⇒ Object
Instance Method Details
#add(file = nil) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/dotgpg/cli.rb', line 44 def add(file=nil) return if helped? dir = Dotgpg::Dir.closest fail "not in a dotgpg directory" unless dir key = read_key_file_for_add(file) fail "#{file || "<stdin>"}: not a valid GPG key" unless key if dir.has_key?(key) && ![:force] fail "#{dir.key_path(key)}: already exists" end info "Adding #{key.name} to #{dir.path}" info " #{dir.key_path(key).relative_path_from(dir.path)}" dir.add_key(key) rescue GPGME::Error::BadPassphrase => e fail e. end |
#cat(*files) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/dotgpg/cli.rb', line 90 def cat(*files) return if helped? dir = Dotgpg::Dir.closest(*files) fail "not in a dotgpg directory" unless dir files.each do |f| dir.decrypt f, $stdout end rescue GPGME::Error::BadPassphrase => e fail e. end |
#edit(*files) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/dotgpg/cli.rb', line 112 def edit(*files) return if helped? dir = Dotgpg::Dir.closest(*files) fail "not in a dotgpg directory" unless dir dir.reencrypt files do |tempfiles| if tempfiles.any? to_edit = tempfiles.values.map do |temp| Shellwords.escape(temp.path) end system "#{Dotgpg.editor} #{to_edit.join(" ")}" fail "Problem with editor. Not saving changes" unless $?.success? end end rescue GPGME::Error::BadPassphrase => e fail e. end |
#init(directory = ".") ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/dotgpg/cli.rb', line 10 def init(directory=".") return if helped? dir = Dotgpg::Dir.new directory if dir.dotgpg.exist? fail "#{directory}/.gpg already exists" end key = Dotgpg::Key.secret_key([:email], [:"new-key"]) info "Initializing new dotgpg directory" info " #{directory}/README.md" unless File.exist? 'README.md' info " #{directory}/.gpg/#{key.email}" FileUtils.mkdir_p(dir.dotgpg) unless File.exist? 'README.md' FileUtils.cp Pathname.new(__FILE__).dirname.join("template/README.md"), dir.path.join("README.md") dir.add_key(key) end end |
#key ⇒ Object
35 36 37 38 39 40 |
# File 'lib/dotgpg/cli.rb', line 35 def key return if helped? key = Dotgpg::Key.secret_key([:email], [:"new-key"]) $stdout.print key.export(armor: true).to_s end |
#merge(*files) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/dotgpg/cli.rb', line 134 def merge(*files) require 'find' require 'digest' require 'fileutils' return if helped? fail "usage: MYFILE OLDFILE YOURFILE" unless files.length == 3 # ok, we won't know which gpg directory was used for our files because # the .merge_files are dumped in the root git dir. so we resort to ulginess # - we hash OLDFILE, search for directories which contain a .gpg subdir # and check the md5sums of all the files in said directory. if there's a # match we have our dir old_hash = Digest::SHA256.file(files[1]).hexdigest # if file is nil DotGpg:Dir.closest throws an error. if it's just a blank # string we get the "not in a dotgpg directory" message file = '' Find.find(::Dir.pwd) do |path| if FileTest.directory?(path) && File.basename(path) == ".gpg" # found a .gpg dir, check in the parent for our target file dotgpg_dir = File.dirname path gpg_files = ::Dir.glob(File.join dotgpg_dir, "*") if matched = gpg_files.find { |f| File.file?(f) && old_hash == Digest::SHA256.file(f).hexdigest } file = matched break end end end dir = Dotgpg::Dir.closest(file) fail "not in a dotgpg directory" unless dir mine = Tempfile.open('mine') old = Tempfile.open('old') yours = Tempfile.open('yours') begin # decrypt all three of our files dir.decrypt files[0], mine dir.decrypt files[1], old dir.decrypt files[2], yours # flush our io mine.flush old.flush yours.flush # TODO - could also use diff3(1) here: # # "diff3 -L mine -L old -L yours -m #{mine.path} #{old.path} #{yours.path}" # # but git merge-file's output is more diff3-ish than diff3's, weird. cmd = "git merge-file -L mine -L old -L yours -p %s %s %s 2>/dev/null" % [ Shellwords.escape(mine.path), Shellwords.escape(old.path), Shellwords.escape(yours.path) ] # run our merge diff = `#{cmd}` conflict = !$?.success? ensure # close and unlink our tempfiles mine.close! old.close! yours.close! end # make a new stringio object out of our diff output io = StringIO.new diff # create a new tempfile to write our merged file to t = Tempfile.open('merged') begin # encrypt our diff3 output dir.encrypt t, io t.flush # and copy that file back to OLDFILE (aka files[1]) since that's where # git expects to find it FileUtils.copy t.path, files[1] ensure t.close! end # this is important - this exit value is what git uses to decide if there # is a conflict or not exit (conflict ? 1 : 0) rescue GPGME::Error::BadPassphrase => e fail e. end |
#rm(file = nil) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/dotgpg/cli.rb', line 67 def rm(file=nil) return if helped?(file.nil?) dir = Dotgpg::Dir.closest fail "not in a dotgpg directory" unless dir key = read_key_file_for_rm(file) fail "#{file}: not a valid GPG key" if !key && ![:force] if key if GPGME::Key.find(:secret).include?(key) && ![:force] fail "#{file}: refusing to remove your own secret key" end info "Removing #{key.name} from #{dir.path}" info "D #{dir.key_path(key).relative_path_from(dir.path)}" dir.remove_key(key) end rescue GPGME::Error::BadPassphrase => e fail e. end |
#unsafe_cat(*files) ⇒ Object
104 105 106 107 108 109 |
# File 'lib/dotgpg/cli.rb', line 104 def unsafe_cat(*files) return if helped? files.each do |f| $stdout.puts Dotgpg.decrypt_without_validating_signatures File.open f end end |