Add CLI
parent
033309696b
commit
46417ae3b5
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'twik/cli'
|
||||
|
||||
Twik::Cli.new(ARGV).run
|
|
@ -0,0 +1,30 @@
|
|||
require 'twik'
|
||||
require 'twik/cli/config'
|
||||
require 'twik/cli/options'
|
||||
|
||||
class Twik
|
||||
class Cli
|
||||
attr_reader :config
|
||||
|
||||
def initialize(args)
|
||||
@config = Config.new(args)
|
||||
end
|
||||
|
||||
def twik
|
||||
@twik ||= Twik.new(config.privatekey, length: config.length, type: config.type.to_sym)
|
||||
end
|
||||
|
||||
def run
|
||||
masterkey = ask('Master key: ')
|
||||
puts twik.generate(config.tag, masterkey)
|
||||
end
|
||||
|
||||
def ask(prompt)
|
||||
print prompt
|
||||
res = STDIN.noecho(&:gets).chomp
|
||||
puts
|
||||
|
||||
res
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
require 'twik/private_key'
|
||||
|
||||
require 'xdg'
|
||||
require 'yaml'
|
||||
|
||||
class Twik
|
||||
class Cli
|
||||
class Config
|
||||
CONFIG_FILE = [XDG['CONFIG_HOME'], 'twik', 'config.yml'].join(File::SEPARATOR)
|
||||
|
||||
def self.default
|
||||
{
|
||||
'profiles' => {
|
||||
'default' => {
|
||||
'privatekey' => Twik::PrivateKey.generate,
|
||||
'length' => 16,
|
||||
'type' => 'alphanumeric_and_special_chars',
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
attr_reader :yaml, :args
|
||||
|
||||
def initialize(args)
|
||||
file = File.new(CONFIG_FILE)
|
||||
@args = Options.parse(args)
|
||||
@yaml = YAML.load_file(file.path)
|
||||
end
|
||||
|
||||
def profile
|
||||
args['profile'] || 'default'
|
||||
end
|
||||
|
||||
def options
|
||||
@options ||= yaml['profiles'][profile].merge(args)
|
||||
end
|
||||
|
||||
def method_missing(symbol)
|
||||
options.key?(symbol.to_s) ? options[symbol.to_s] : super
|
||||
end
|
||||
|
||||
class File
|
||||
attr_reader :path
|
||||
|
||||
def initialize(path)
|
||||
@path = path
|
||||
create unless ::File.exist?(path)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create
|
||||
directory = ::File.dirname(path)
|
||||
::FileUtils.mkdir_p directory unless ::File.directory?(directory)
|
||||
|
||||
::File.open(path, 'w') do |file|
|
||||
file.write(YAML.dump(Twik::Cli::Config.default))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,56 @@
|
|||
require 'optparse'
|
||||
|
||||
class Twik
|
||||
class Cli
|
||||
class Options
|
||||
def self.parse(args)
|
||||
options = {}
|
||||
|
||||
parser = ::OptionParser.new do |opts|
|
||||
opts.banner = 'Usage: twik [options] tag'
|
||||
|
||||
opts.separator ''
|
||||
opts.separator 'Specific options:'
|
||||
|
||||
opts.on('-l', '--length LENGTH', 'length of generated password (4-26). Default: 16') do |length|
|
||||
options['length'] = length.to_i
|
||||
end
|
||||
|
||||
opts.on('-p', '--profile PROFILE', "profile to use. Default: 'default'") do |profile|
|
||||
options['profile'] = profile
|
||||
end
|
||||
|
||||
opts.on('-t', '--type TYPE', Twik::TYPE,
|
||||
"type of password:", " #{Twik::TYPE.join(', ')}", " Default: alphanumeric_and_special_chars") do |type|
|
||||
options['type'] = type.to_sym
|
||||
end
|
||||
|
||||
opts.separator ''
|
||||
opts.separator 'Common options:'
|
||||
|
||||
opts.on_tail('-h', '--help', 'Show this message') do
|
||||
puts opts
|
||||
exit
|
||||
end
|
||||
|
||||
opts.on_tail('--version', 'Show version') do
|
||||
puts "#{opts.program_name} #{Immoconv::VERSION}"
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
parser.parse!(args)
|
||||
rescue OptionParser::MissingArgument, OptionParser::InvalidOption => e
|
||||
puts e.message
|
||||
puts parser
|
||||
exit
|
||||
end
|
||||
|
||||
options['tag'] = args.shift
|
||||
|
||||
options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
class Twik
|
||||
class PrivateKey
|
||||
def self.generate
|
||||
format = [8, 4, 4, 4, 12]
|
||||
separator = '-'
|
||||
chars = ('A'..'Z').to_a + ('0'..'9').to_a
|
||||
|
||||
format.map do |i|
|
||||
i.times.inject('') do |res, j|
|
||||
res + chars[Random.rand(chars.length)]
|
||||
end
|
||||
end.join(separator)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|||
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
spec.add_dependency 'xdg'
|
||||
|
||||
spec.add_development_dependency "bundler", "~> 1.7"
|
||||
spec.add_development_dependency "rake", "~> 10.0"
|
||||
|
||||
|
|
Loading…
Reference in New Issue