diff --git a/.tool-versions b/.tool-versions index b8cd6d8..4991363 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -crystal 0.31.1 +crystal 0.32.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c05c3b..36a8fed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.3.2 + +* Make compatible with Crystal 0.32.1 and 0.31.1 + ## 0.3.1 ### Changes diff --git a/README.md b/README.md index 005d0d1..538970a 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,10 @@ git checkout crystal -v # Install dependencies shards -# Build app +# Build app for Crystal 0.32.1 / MacOS crystal build src/snipline_cli.cr -o snipcli --release -o snipcli +# Build app for Crystal 0.31.1 / Linux (Alpine) +crystal build src/snipline_cli.cr -o snipcli --release -o snipcli -Dstatic_linux ./snipcli --version ``` diff --git a/shard.yml b/shard.yml index 32b95cc..0bf4e15 100644 --- a/shard.yml +++ b/shard.yml @@ -1,5 +1,5 @@ name: cli -version: 0.3.1 +version: 0.3.2 authors: - Mitchell Stanley @@ -8,7 +8,7 @@ targets: cli2: main: src/cli.cr -crystal: 0.31.1 +crystal: < 0.33 license: MIT diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7792aa4..7664eda 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: snipcli -version: 0.3.1 +version: 0.3.2 summary: Shell Snippet organiser description: > Snipcli is a commandline interface for managing shell commands. Sync commands with your Snipline account or use in guest mode. Snipline lets you dynamically change command parameters easily so you never have to remember how to build a command. diff --git a/spec/services/migrator_spec.cr b/spec/services/migrator_spec.cr index 634c8b8..05049ac 100644 --- a/spec/services/migrator_spec.cr +++ b/spec/services/migrator_spec.cr @@ -17,7 +17,7 @@ describe SniplineCli::Services::Migrator do it "should import any previously created json snippets" do # File.write("./snippets.json", File.read("./spec/fixtures/snippets.json")) FileUtils.cp({"./spec/fixtures/snippets.json"}, "./") - File.exists?(File.expand_path(SniplineCli.config.get("general.file"))).should eq(true) + File.exists?(File.expand_path(SniplineCli.config.get("general.file"), home: true)).should eq(true) SniplineCli::Services::Migrator.run DB.open "sqlite3:./test.db" do |db| db.scalar("select count(*) from snippets").should eq(2) diff --git a/src/snipline_cli.cr b/src/snipline_cli.cr index b66fcda..d8c4eea 100644 --- a/src/snipline_cli.cr +++ b/src/snipline_cli.cr @@ -7,6 +7,7 @@ require "sqlite3" require "crecto" require "./snipline_cli/config" +require "./snipline_cli/helpers/*" require "./snipline_cli/exceptions/*" require "./snipline_cli/parsers/*" require "./snipline_cli/models/*" @@ -21,12 +22,12 @@ module Repo config do |conf| conf.adapter = Crecto::Adapters::SQLite3 - conf.database = File.expand_path(SniplineCli.config.get("general.db")) + conf.database = SniplineCli::Helpers.expand_path(SniplineCli.config.get("general.db")) end end module SniplineCli - VERSION = "0.3.1" + VERSION = "0.3.2" def self.config Config.config diff --git a/src/snipline_cli/commands/init.cr b/src/snipline_cli/commands/init.cr index 6c65d45..cc7d607 100644 --- a/src/snipline_cli/commands/init.cr +++ b/src/snipline_cli/commands/init.cr @@ -1,4 +1,5 @@ require "toml" +require "../helpers/expand_path" module SniplineCli class Command < Admiral::Command @@ -7,6 +8,8 @@ module SniplineCli # This command generates a config file in the requested location. # By default this location is ~/.config/snipline/config.toml class Init < Admiral::Command + include SniplineCli::Helpers + define_help description: "Initialise Snipline CLI without logging in" def run @@ -27,11 +30,11 @@ module SniplineCli TOML CreateConfigDirectory.run(SniplineCli.config_file) - File.write(File.expand_path(SniplineCli.config_file), toml_contents, mode: "w") - puts "Configuration saved to #{File.expand_path(SniplineCli.config_file).colorize.mode(:bold)}" - unless File.exists?(File.expand_path(config.get("general.db"))) - File.write(File.expand_path(config.get("general.db")), "", mode: "w") - puts "Created SQLite file in #{File.expand_path(config.get("general.db")).colorize.mode(:bold)}" + File.write(expand_path(SniplineCli.config_file), toml_contents, mode: "w") + puts "Configuration saved to #{expand_path(SniplineCli.config_file).colorize.mode(:bold)}" + unless File.exists?(expand_path(config.get("general.db"))) + File.write(expand_path(config.get("general.db")), "", mode: "w") + puts "Created SQLite file in #{expand_path(config.get("general.db")).colorize.mode(:bold)}" end puts "" puts "Run #{"snipcli new".colorize.mode(:bold)} to create your first snippet" diff --git a/src/snipline_cli/commands/login.cr b/src/snipline_cli/commands/login.cr index 5bdd5d7..e341a47 100644 --- a/src/snipline_cli/commands/login.cr +++ b/src/snipline_cli/commands/login.cr @@ -1,4 +1,5 @@ require "toml" +require "../helpers/expand_path" module SniplineCli class Command < Admiral::Command @@ -8,6 +9,7 @@ module SniplineCli # By default this location is ~/.config/snipline/config.toml class Login < Admiral::Command include SniplineCli::Models + include SniplineCli::Helpers define_help description: "Log-in into your Snipline account" def run @@ -60,8 +62,8 @@ module SniplineCli TOML CreateConfigDirectory.run(SniplineCli.config_file) - File.write(File.expand_path(SniplineCli.config_file), toml_contents, mode: "w") - puts "Configuration saved to #{File.expand_path(SniplineCli.config_file).colorize.mode(:bold)}" + File.write(expand_path(SniplineCli.config_file), toml_contents, mode: "w") + puts "Configuration saved to #{expand_path(SniplineCli.config_file).colorize.mode(:bold)}" puts "To fetch your snippets run #{"snipcli sync".colorize.mode(:bold)}" end rescue ex : Crest::NotFound diff --git a/src/snipline_cli/commands/new.cr b/src/snipline_cli/commands/new.cr index 91793e3..20505bc 100644 --- a/src/snipline_cli/commands/new.cr +++ b/src/snipline_cli/commands/new.cr @@ -1,4 +1,5 @@ require "toml" +require "../helpers/expand_path" module SniplineCli class Command < Admiral::Command @@ -7,11 +8,13 @@ module SniplineCli # This command generates a config file in the requested location. # By default this location is ~/.config/snipline/config.toml class New < Admiral::Command + include SniplineCli::Helpers + define_help description: "Create a new Snippet" def run config = SniplineCli.config - unless File.exists?(File.expand_path("#{config.get("general.db")}")) + unless File.exists?(expand_path("#{config.get("general.db")}")) abort("Database does not exist - Have you tried running #{"snipcli init".colorize.mode(:bold)}?".colorize.back(:red).on(:red)) end Migrator.run @@ -21,7 +24,7 @@ module SniplineCli temp_file = TempSnippetEditorFile.new temp_file.create loop do - system("#{ENV["EDITOR"]} #{File.expand_path("#{config.get("general.temp_dir")}/temp.toml")}") + system("#{ENV["EDITOR"]} #{expand_path("#{config.get("general.temp_dir")}/temp.toml")}") snippet_attributes = temp_file.read snippet = Snippet.new diff --git a/src/snipline_cli/config.cr b/src/snipline_cli/config.cr index d952f44..20af812 100644 --- a/src/snipline_cli/config.cr +++ b/src/snipline_cli/config.cr @@ -1,5 +1,6 @@ require "toml" require "file_utils" +require "./helpers/*" module SniplineCli # SniplineCli::Config is for easily retreiving configuration throughout the codebase. @@ -11,13 +12,14 @@ module SniplineCli # config.get("api.url") # ``` class Config + include SniplineCli::Helpers # Constant that creates a fresh version of itself - for use with self.config. INSTANCE = Config.new # When a new instance is created the config file is read and parsed. def initialize - if File.exists?(File.expand_path(SniplineCli.config_file)) - config_file = File.read(File.expand_path(SniplineCli.config_file)) + if File.exists?(expand_path(SniplineCli.config_file)) + config_file = File.read(expand_path(SniplineCli.config_file)) toml = TOML.parse(config_file) @api = toml["api"].as(Hash(String, TOML::Type)) @general = toml["general"].as(Hash(String, TOML::Type)) diff --git a/src/snipline_cli/helpers/expand_path.cr b/src/snipline_cli/helpers/expand_path.cr new file mode 100644 index 0000000..4183f5a --- /dev/null +++ b/src/snipline_cli/helpers/expand_path.cr @@ -0,0 +1,13 @@ +require "file" + +module SniplineCli::Helpers + extend self + + def expand_path(path) + {% if flag?(:static_linux) %} + File.expand_path(path) + {% else %} + File.expand_path(path, home: true) + {% end %} + end +end diff --git a/src/snipline_cli/services/edit_snippet.cr b/src/snipline_cli/services/edit_snippet.cr index f9a446f..320a582 100644 --- a/src/snipline_cli/services/edit_snippet.cr +++ b/src/snipline_cli/services/edit_snippet.cr @@ -1,3 +1,5 @@ +require "../helpers/*" + module SniplineCli module Services # LoadSnippets fetches all the snippets from the `snippet.json` file and parses them. @@ -13,7 +15,7 @@ module SniplineCli temp_file = TempSnippetEditorFile.new(snippet) temp_file.create loop do - system("#{ENV["EDITOR"]} #{File.expand_path("#{config.get("general.temp_dir")}/temp.toml")}") + system("#{ENV["EDITOR"]} #{SniplineCli::Helpers.expand_path("#{config.get("general.temp_dir")}/temp.toml")}") snippet_attributes = temp_file.read snippet.name = snippet_attributes.name snippet.real_command = snippet_attributes.real_command.strip diff --git a/src/snipline_cli/services/load_snippets.cr b/src/snipline_cli/services/load_snippets.cr index 91de8d7..2486fde 100644 --- a/src/snipline_cli/services/load_snippets.cr +++ b/src/snipline_cli/services/load_snippets.cr @@ -1,5 +1,9 @@ +require "../helpers/*" + module SniplineCli module Services + include SniplineCli::Helpers + # LoadSnippets fetches all the snippets from the `snippet.json` file and parses them. # # ```crystal @@ -10,7 +14,7 @@ module SniplineCli config = SniplineCli.config log = SniplineCli.log log.info("Looking through file #{config.get("general.db")}") - unless File.readable?(File.expand_path(config.get("general.db"))) + unless File.readable?(expand_path(config.get("general.db"))) log.warn("Could not read #{config.get("general.db")}") abort("Run #{"snipline-cli sync".colorize(:green)} first") end diff --git a/src/snipline_cli/services/migrator.cr b/src/snipline_cli/services/migrator.cr index f6c4b76..9f7ef3a 100644 --- a/src/snipline_cli/services/migrator.cr +++ b/src/snipline_cli/services/migrator.cr @@ -2,14 +2,15 @@ require "db" require "sqlite3" require "json" require "crecto" +require "../helpers/*" module SniplineCli::Services # Keeps the database structure up to date class Migrator def self.run config = SniplineCli.config - File.write(File.expand_path(config.get("general.db")), "", mode: "w") unless File.exists?(File.expand_path(config.get("general.db"))) - DB.open "sqlite3:#{File.expand_path(config.get("general.db"))}" do |db| + File.write(expand_path(config.get("general.db")), "", mode: "w") unless File.exists?(expand_path(config.get("general.db"))) + DB.open "sqlite3:#{expand_path(config.get("general.db"))}" do |db| db.exec "create table if not exists snippets ( local_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, cloud_id TEXT NULL, @@ -31,9 +32,9 @@ module SniplineCli::Services end # Import 0.2.0 snippets from JSON file - if File.exists?(File.expand_path(config.get("general.file"))) + if File.exists?(expand_path(config.get("general.file"))) # Get the snippets - json = File.read(File.expand_path(config.get("general.file"))) + json = File.read(expand_path(config.get("general.file"))) # import into DB p "Importing JSON snippets into SQLite Database" Array(SnippetParser).from_json(json).each do |snippet_json| @@ -61,7 +62,7 @@ module SniplineCli::Services Repo.insert(changeset) end end - File.delete(File.expand_path(config.get("general.file"))) + File.delete(expand_path(config.get("general.file"))) end end end diff --git a/src/snipline_cli/services/store_snippets.cr b/src/snipline_cli/services/store_snippets.cr index f31b0ab..e8ee98d 100644 --- a/src/snipline_cli/services/store_snippets.cr +++ b/src/snipline_cli/services/store_snippets.cr @@ -1,18 +1,22 @@ require "json" +require "../helpers/*" + module SniplineCli::Services # For saving Snippets locally. class StoreSnippets + include SniplineCli::Helpers + # Takes an array of snippets and saves them to the `snippet.json` file. def store(snippets) config = SniplineCli.config - directory = File.dirname(File.expand_path(config.get("general.file"))) + directory = File.dirname(expand_path(config.get("general.file"))) unless File.directory?(directory) puts "Creating #{directory} directory" - Dir.mkdir(File.expand_path(directory)) + Dir.mkdir(expand_path(directory)) end - File.write(File.expand_path(config.get("general.file")), snippets, mode: "w") - unless File.writable?(File.expand_path(config.get("general.file"))) + File.write(expand_path(config.get("general.file")), snippets, mode: "w") + unless File.writable?(expand_path(config.get("general.file"))) raise Exception.new("Sync Failed: File not writable (#{config.get("general.file")}") end end diff --git a/src/snipline_cli/services/temp_snippet_editor_file.cr b/src/snipline_cli/services/temp_snippet_editor_file.cr index 732b78b..e6cc076 100644 --- a/src/snipline_cli/services/temp_snippet_editor_file.cr +++ b/src/snipline_cli/services/temp_snippet_editor_file.cr @@ -1,8 +1,11 @@ require "toml" +require "../helpers/*" module SniplineCli::Services # Provides the users preferred text editor with a template for editing and adding new snippets. class TempSnippetEditorFile + include SniplineCli::Helpers + property snippet : Snippet | Nil property template = %<# Welcome to the terminal-based snippet editor @@ -44,12 +47,12 @@ sync_to_cloud = #{SniplineCli.config.get("api.token") == "" ? "false" : "true"} def create config = SniplineCli.config - File.write(File.expand_path("#{config.get("general.temp_dir")}/temp.toml"), @template) + File.write(expand_path("#{config.get("general.temp_dir")}/temp.toml"), @template) end def read config = SniplineCli.config - toml = TOML.parse(File.read(File.expand_path("#{config.get("general.temp_dir")}/temp.toml"))) + toml = TOML.parse(File.read(expand_path("#{config.get("general.temp_dir")}/temp.toml"))) SnippetAttributeParser.new( name: toml["name"].as(String), real_command: toml["real_command"].as(String), @@ -71,14 +74,14 @@ sync_to_cloud = #{SniplineCli.config.get("api.token") == "" ? "false" : "true"} def sync_to_cloud? config = SniplineCli.config - toml = TOML.parse(File.read(File.expand_path("#{config.get("general.temp_dir")}/temp.toml"))) + toml = TOML.parse(File.read(expand_path("#{config.get("general.temp_dir")}/temp.toml"))) toml["sync_to_cloud"].as(Bool) end def delete config = SniplineCli.config - if File.exists?(File.expand_path("#{config.get("general.temp_dir")}/temp.toml")) - File.delete(File.expand_path("#{config.get("general.temp_dir")}/temp.toml")) + if File.exists?(expand_path("#{config.get("general.temp_dir")}/temp.toml")) + File.delete(expand_path("#{config.get("general.temp_dir")}/temp.toml")) end end end