From d49a3d12616cf5fce516fbc59032a70629da648d Mon Sep 17 00:00:00 2001 From: Glenn Date: Sun, 22 Oct 2023 23:23:56 +0200 Subject: [PATCH] refactor: clean up & add module --- src/cli.cr | 42 ++++++++++++++++++++++++ src/config.cr | 24 ++++++++++++++ src/fzf.cr | 23 +++++++++++++ src/main.cr | 91 +++------------------------------------------------ src/vault.cr | 38 +++++++++++++++++++++ 5 files changed, 132 insertions(+), 86 deletions(-) create mode 100644 src/cli.cr create mode 100644 src/config.cr create mode 100644 src/fzf.cr create mode 100644 src/vault.cr diff --git a/src/cli.cr b/src/cli.cr new file mode 100644 index 0000000..8ba8695 --- /dev/null +++ b/src/cli.cr @@ -0,0 +1,42 @@ + +require "./config" +require "./fzf" + +module GX + class Cli + @home_dir : String + @config : Config + + def initialize() + # Main execution starts here + if !ENV["HOME"]? + raise "Home directory not found" + end + @home_dir = ENV["HOME"] + @config = Config.new(File.join(@home_dir, ".config/gx-vault.yml")) + + ## FIXME: check that FZF is installed + end + + def run() + # Correcting the fzf interaction part + names_display = @config.vaults.map do |vault| + vault.mounted? ? "#{vault.name} [#{ "open".colorize(:green) }]" : vault.name + end + + selected_vault_name = Fzf.run(names_display.sort) + puts ">> #{selected_vault_name}".colorize(:yellow) + selected_vault = @config.vaults.find { |v| v.name == selected_vault_name } + + if selected_vault + selected_vault.mounted? ? selected_vault.unmount : selected_vault.mount + else + STDERR.puts "Vault not found.".colorize(:red) + end + + + end + + + end +end diff --git a/src/config.cr b/src/config.cr new file mode 100644 index 0000000..d40d669 --- /dev/null +++ b/src/config.cr @@ -0,0 +1,24 @@ + +require "./vault" + +module GX +class Config + getter vaults : Array(Vault) + + def initialize(config_path : String) + @vaults = [] of Vault + load_vaults(config_path) + end + + private def load_vaults(config_path : String) + yaml_data = YAML.parse(File.read(config_path)) + vaults_data = yaml_data["vaults"].as_a + + vaults_data.each do |vault_data| + name = vault_data["name"].as_s + encrypted_path = vault_data["encrypted_path"].as_s + @vaults << Vault.new(name, encrypted_path, "#{name}.Open") + end + end +end +end diff --git a/src/fzf.cr b/src/fzf.cr new file mode 100644 index 0000000..db2738d --- /dev/null +++ b/src/fzf.cr @@ -0,0 +1,23 @@ + +module GX + class Fzf + + def self.run(list : Array(String)) : String + input = IO::Memory.new + input.puts list.join("\n") + input.rewind + + output = IO::Memory.new + error = STDERR + process = Process.new("fzf", ["--ansi"], input: input, output: output, error: error) + + unless process.wait.success? + STDERR.puts "Error executing fzf: #{error.to_s.strip}".colorize(:red) + exit(1) + end + + result = output.to_s.strip #.split.first? + end + end +end + diff --git a/src/main.cr b/src/main.cr index c6de864..903a97b 100644 --- a/src/main.cr +++ b/src/main.cr @@ -2,92 +2,11 @@ require "yaml" require "colorize" require "json" -# Vault class -class Vault - getter name : String - getter encrypted_path : String - getter mount_dir : String +require "./vault" +require "./config" +require "./cli" - def initialize(@name, @encrypted_path, mount_name : String) - home_dir = ENV["HOME"] || raise "Home directory not found" - @mount_dir = File.join(home_dir, "mnt/#{mount_name}") - end +app = GX::Cli.new +app.run - def mounted? : Bool - `mount`.includes?("#{encrypted_path} on #{mount_dir}") - end - - def mount - Dir.mkdir_p(mount_dir) unless Dir.exists?(mount_dir) - - if mounted? - puts "Already mounted. Skipping.".colorize(:yellow) - else - input = STDIN - output = STDOUT - error = STDERR - process = Process.new("gocryptfs", ["-idle", "15m", encrypted_path, mount_dir], input: input, output: output, error: error) - unless process.wait.success? - puts "Error mounting the vault".colorize(:red) - return - end - puts "Vault #{name} is now available on #{mount_dir}".colorize(:green) - end - end - def unmount - `fusermount -u #{mount_dir}` - puts "Vault #{name} is now closed.".colorize(:green) - end -end - -# Config class -class Config - getter vaults : Array(Vault) - - def initialize(config_path : String) - @vaults = [] of Vault - load_vaults(config_path) - end - - private def load_vaults(config_path : String) - yaml_data = YAML.parse(File.read(config_path)) - vaults_data = yaml_data["vaults"].as_a - - vaults_data.each do |vault_data| - name = vault_data["name"].as_s - encrypted_path = vault_data["encrypted_path"].as_s - @vaults << Vault.new(name, encrypted_path, "#{name}.Open") - end - end -end - -# Main execution starts here -home_dir = ENV["HOME"] || raise "Home directory not found" -config = Config.new(File.join(home_dir, ".config/gx-vault.yml")) - -# Correcting the fzf interaction part -input = IO::Memory.new -config.vaults.each do |vault| - name_display = vault.mounted? ? "#{vault.name} [#{ "open".colorize(:green) }]" : vault.name - input.puts name_display -end -input.rewind - -output = IO::Memory.new -error = STDERR -process = Process.new("fzf", ["--ansi"], input: input, output: output, error: error) - -unless process.wait.success? - puts "Error executing fzf: #{error.to_s.strip}".colorize(:red) - exit(1) -end - -selected_vault_name = output.to_s.strip.split.first? -selected_vault = config.vaults.find { |v| v.name == selected_vault_name } - -if selected_vault - selected_vault.mounted? ? selected_vault.unmount : selected_vault.mount -else - puts "Vault not found.".colorize(:red) -end diff --git a/src/vault.cr b/src/vault.cr new file mode 100644 index 0000000..36ddd94 --- /dev/null +++ b/src/vault.cr @@ -0,0 +1,38 @@ +module GX +class Vault + getter name : String + getter encrypted_path : String + getter mount_dir : String + + def initialize(@name, @encrypted_path, mount_name : String) + home_dir = ENV["HOME"] || raise "Home directory not found" + @mount_dir = File.join(home_dir, "mnt/#{mount_name}") + end + + def mounted? : Bool + `mount`.includes?("#{encrypted_path} on #{mount_dir}") + end + + def mount + Dir.mkdir_p(mount_dir) unless Dir.exists?(mount_dir) + + if mounted? + puts "Already mounted. Skipping.".colorize(:yellow) + else + input = STDIN + output = STDOUT + error = STDERR + process = Process.new("gocryptfs", ["-idle", "15m", encrypted_path, mount_dir], input: input, output: output, error: error) + unless process.wait.success? + puts "Error mounting the vault".colorize(:red) + return + end + puts "Vault #{name} is now available on #{mount_dir}".colorize(:green) + end + end + def unmount + `fusermount -u #{mount_dir}` + puts "Vault #{name} is now closed.".colorize(:green) + end +end +end