From b69bf86ade6fe5e830aa39222da7eadf52538b55 Mon Sep 17 00:00:00 2001 From: Aaron Stillwell Date: Thu, 11 Jan 2018 00:24:27 +0000 Subject: [PATCH 1/7] Initial implementation of destroy as per issue #8 --- src/lib/file_tree.cr | 8 ++++++++ src/lib/renderer.cr | 35 +++++++++++++++++++++++++++++++++++ src/lib/rendering_entry.cr | 10 ++++++++++ 3 files changed, 53 insertions(+) diff --git a/src/lib/file_tree.cr b/src/lib/file_tree.cr index a4bf0c7..d10aee7 100644 --- a/src/lib/file_tree.cr +++ b/src/lib/file_tree.cr @@ -28,6 +28,14 @@ module Teeplate renderer end + # Destroy the rendered files. + def destroy(out_dir, force : Bool = false, interactive : Bool = false, interact : Bool = false, list : Bool = false, color : Bool = false, per_entry : Bool = false, quit : Bool = true) + renderer = Renderer.new(out_dir, force: force, interact: interactive || interact, list: list, color: color, per_entry: per_entry, quit: quit) + renderer << rendered_file_entries + renderer.destroy + renderer + end + # Returns file entries to be rendered. # # This method just returns the `#file_entries` method's result. To filter entries, override this method. diff --git a/src/lib/renderer.cr b/src/lib/renderer.cr index d137385..5d1ca52 100644 --- a/src/lib/renderer.cr +++ b/src/lib/renderer.cr @@ -41,6 +41,9 @@ module Teeplate # :nodoc: getter data_entries = [] of AsDataEntry + # :nodoc: + getter? pending_destroy = false + # :nodoc: getter entries = [] of RenderingEntry @@ -97,5 +100,37 @@ module Teeplate @quitted = true end end + + # :nodoc: + def destroy + @pending_destroy = true + begin + @entries.each(&.destroy) if should_destroy? + rescue ex : Quit + @quitted = true + end + end + + # Confirm whether or not the user wishes to destroy the files if in interactive mode. + def should_destroy? + if @interactive + STDOUT.puts "Remove the following files (y/n)?" + + @entries.each do |entry| + puts entry.out_path + end + + loop do + case input = ::STDIN.gets.to_s.strip.downcase + when "y" + return true + when "n" + return false + end + end + end + + true + end end end diff --git a/src/lib/rendering_entry.cr b/src/lib/rendering_entry.cr index a569ccc..a5992b3 100644 --- a/src/lib/rendering_entry.cr +++ b/src/lib/rendering_entry.cr @@ -91,6 +91,15 @@ module Teeplate end end + # :nodoc: + def destroy + begin + File.delete out_path + rescue + STDOUT.puts "#{out_path} not found, nothing to destroy" + end + end + # :nodoc: def set_perm if perm = @data.perm? && File.file?(out_path) @@ -125,6 +134,7 @@ module Teeplate return :keep if !@renderer.interactive? || @renderer.keeps_all? return modifies?("#{local_path} is a symlink...", diff: false) if File.symlink?(out_path) return :modify if appends? + return :destroy if @renderer.pending_destroy? return :none if identical? modifies?("#{local_path} already exists...", diff: true) end From 6dd1d653d4649a1733a824cfbb2ccb5405f8968e Mon Sep 17 00:00:00 2001 From: Aaron Stillwell Date: Sun, 14 Jan 2018 20:57:00 +0000 Subject: [PATCH 2/7] Implemented correct destroy prompt behaviour Also includes destroyed/skipped messages --- src/lib/file_tree.cr | 7 ++++- src/lib/renderer.cr | 52 +++++++++++++++++++++++++------------- src/lib/rendering_entry.cr | 3 ++- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/lib/file_tree.cr b/src/lib/file_tree.cr index d10aee7..13790a8 100644 --- a/src/lib/file_tree.cr +++ b/src/lib/file_tree.cr @@ -31,7 +31,7 @@ module Teeplate # Destroy the rendered files. def destroy(out_dir, force : Bool = false, interactive : Bool = false, interact : Bool = false, list : Bool = false, color : Bool = false, per_entry : Bool = false, quit : Bool = true) renderer = Renderer.new(out_dir, force: force, interact: interactive || interact, list: list, color: color, per_entry: per_entry, quit: quit) - renderer << rendered_file_entries + renderer << destroy_file_entries renderer.destroy renderer end @@ -43,6 +43,11 @@ module Teeplate file_entries end + # :nodoc: + def destroy_file_entries + file_entries + end + # :nodoc: def ____collect_files(files) end diff --git a/src/lib/renderer.cr b/src/lib/renderer.cr index 5d1ca52..a456c17 100644 --- a/src/lib/renderer.cr +++ b/src/lib/renderer.cr @@ -105,32 +105,50 @@ module Teeplate def destroy @pending_destroy = true begin - @entries.each(&.destroy) if should_destroy? + if @interactive + @entries.each do |entry| + entry.destroy if should_destroy?(entry) + end + else + @entries.each(&.destroy) if should_destroy_all?(@entries) + end rescue ex : Quit @quitted = true end end - - # Confirm whether or not the user wishes to destroy the files if in interactive mode. - def should_destroy? - if @interactive - STDOUT.puts "Remove the following files (y/n)?" - @entries.each do |entry| - puts entry.out_path - end + # Confirm whether the user wants to destroy a singe file. + def should_destroy?(entry : RenderingEntry) + STDOUT.puts "Destroy #{entry.out_path}? (y/n)" - loop do - case input = ::STDIN.gets.to_s.strip.downcase - when "y" - return true - when "n" - return false - end + loop do + case input = ::STDIN.gets.to_s.strip.downcase + when "y" + return true + when "n" + return false end end + end + + # Confirm whether or not the user wishes to destroy multiple files. + def should_destroy_all?(entries : Array(RenderingEntry)) + return should_destroy?(entries.first) if entries.size == 1 + + STDOUT.puts "Destroy all the following files? (y/n)" + + entries.each do |entry| + puts entry.out_path + end - true + loop do + case input = ::STDIN.gets.to_s.strip.downcase + when "y" + return true + when "n" + return false + end + end end end end diff --git a/src/lib/rendering_entry.cr b/src/lib/rendering_entry.cr index a5992b3..41fefb1 100644 --- a/src/lib/rendering_entry.cr +++ b/src/lib/rendering_entry.cr @@ -95,8 +95,9 @@ module Teeplate def destroy begin File.delete out_path + list_if_any "destroyed ", :red rescue - STDOUT.puts "#{out_path} not found, nothing to destroy" + list_if_any "skipped ", :yellow end end From ec60e5fb87e09b473e35f5dd57ee3294eadbdb04 Mon Sep 17 00:00:00 2001 From: Faustino Aguilar Date: Tue, 6 Feb 2018 20:19:22 -0500 Subject: [PATCH 3/7] Add Crystal 0.24.1 compatibility --- shard.yml | 6 +++--- src/lib.cr | 2 +- src/lib/file_entry_collector.cr | 7 +++---- src/lib/file_tree/macros/directory.cr | 8 +++----- src/lib/rendering_entry.cr | 4 ++-- src/{ => teeplate}/version.cr | 1 - 6 files changed, 12 insertions(+), 16 deletions(-) rename src/{ => teeplate}/version.cr (50%) diff --git a/shard.yml b/shard.yml index 589d303..943d1c4 100644 --- a/shard.yml +++ b/shard.yml @@ -4,12 +4,12 @@ version: 0.4.5 authors: - mosop -crystal: 0.21.1 +crystal: 0.24.1 development_dependencies: have_files: - github: mosop/have_files - version: ~> 0.3.3 + github: amberframework/have_files + version: ~> 0.4.0 stdio: github: mosop/stdio version: ~> 0.1.2 diff --git a/src/lib.cr b/src/lib.cr index 5403244..8a8a753 100644 --- a/src/lib.cr +++ b/src/lib.cr @@ -2,6 +2,6 @@ require "base64" require "colorize" require "ecr/macros" require "process" -require "./version" +require "./teeplate/*" require "./lib/as_data_entry" require "./lib/*" diff --git a/src/lib/file_entry_collector.cr b/src/lib/file_entry_collector.cr index 9d59a72..478aefc 100644 --- a/src/lib/file_entry_collector.cr +++ b/src/lib/file_entry_collector.cr @@ -8,10 +8,8 @@ module Teeplate def each_file(abs, rel, &block : String, String ->) Dir.open(abs) do |d| - d.each do |entry| - if entry != "." && entry != ".." - each_file abs, rel, entry, &block - end + d.each_child do |entry| + each_file abs, rel, entry, &block end end end @@ -27,6 +25,7 @@ module Teeplate end @entries : Array(AsDataEntry)? + def entries @entries ||= begin a = [] of AsDataEntry diff --git a/src/lib/file_tree/macros/directory.cr b/src/lib/file_tree/macros/directory.cr index 8991867..5c56640 100644 --- a/src/lib/file_tree/macros/directory.cr +++ b/src/lib/file_tree/macros/directory.cr @@ -2,10 +2,8 @@ require "base64" def each_file(abs, rel, &block : String, String ->) Dir.open(abs) do |d| - d.each do |entry| - if entry != "." && entry != ".." - each_file abs, rel, entry, &block - end + d.each_child do |entry| + each_file abs, rel, entry, &block end end end @@ -39,7 +37,7 @@ end def pack_blob(sb, abs, rel) STDOUT << "\n____files << ::Teeplate::Base64Data.new(\"#{rel}\", " io = IO::Memory.new - File.open(abs){|f| IO.copy(f, io)} + File.open(abs) { |f| IO.copy(f, io) } if io.size > 0 STDOUT << "#{io.size}_u64, <<-EOS\n" Base64.encode io, STDOUT diff --git a/src/lib/rendering_entry.cr b/src/lib/rendering_entry.cr index a569ccc..977cf38 100644 --- a/src/lib/rendering_entry.cr +++ b/src/lib/rendering_entry.cr @@ -200,9 +200,9 @@ module Teeplate end begin if !GIT.empty? - Process.new(GIT, ["diff", "--no-index", "--", out_path, "-"], shell: true, input: r, output: true, error: true).wait + Process.new(GIT, ["diff", "--no-index", "--", out_path, "-"], shell: true, input: r, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit).wait elsif !DIFF.empty? - Process.new(DIFF, ["-u", out_path, "-"], shell: true, input: r, output: true, error: true).wait + Process.new(DIFF, ["-u", out_path, "-"], shell: true, input: r, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit).wait else STDOUT.puts "No diff command is installed." end diff --git a/src/version.cr b/src/teeplate/version.cr similarity index 50% rename from src/version.cr rename to src/teeplate/version.cr index 199502e..92ab4fc 100644 --- a/src/version.cr +++ b/src/teeplate/version.cr @@ -1,3 +1,2 @@ module Teeplate - VERSION = "0.4.5" end From d49cb244ab19924b7739f837e653b113f680b302 Mon Sep 17 00:00:00 2001 From: Faustino Aguilar Date: Tue, 6 Feb 2018 20:27:32 -0500 Subject: [PATCH 4/7] Bumped version number to v0.5.0 --- shard.yml | 2 +- src/teeplate/version.cr | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/shard.yml b/shard.yml index 943d1c4..c5230c5 100644 --- a/shard.yml +++ b/shard.yml @@ -1,5 +1,5 @@ name: teeplate -version: 0.4.5 +version: 0.5.0 authors: - mosop diff --git a/src/teeplate/version.cr b/src/teeplate/version.cr index 92ab4fc..1143ece 100644 --- a/src/teeplate/version.cr +++ b/src/teeplate/version.cr @@ -1,2 +1,3 @@ module Teeplate + VERSION = "0.5.0" end From 0139d7407cc5761800fd43646ce61ba5a20f905b Mon Sep 17 00:00:00 2001 From: Aaron Stillwell Date: Sat, 17 Mar 2018 19:25:12 +0000 Subject: [PATCH 5/7] Implemented skip_on_destroy method --- src/lib/file_tree.cr | 11 +++++++++- src/lib/renderer.cr | 44 ++++++++++++++++++++++++++++++++------ src/lib/rendering_entry.cr | 14 +++++++----- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/lib/file_tree.cr b/src/lib/file_tree.cr index 13790a8..7930ba9 100644 --- a/src/lib/file_tree.cr +++ b/src/lib/file_tree.cr @@ -1,6 +1,10 @@ module Teeplate # Collects template files from a local directory. abstract class FileTree + + # Array of paths to skip when performing destroy + @skip_on_destroy = [] of String + # Collects and embeds template files. # # It runs another macro process that collects template files and embeds the files as code. @@ -8,6 +12,11 @@ module Teeplate {{ run(__DIR__ + "/file_tree/macros/directory", dir.id) }} end + # Skip directory/file at the given path. The path is relative to the out_dir. + def skip_on_destroy(path) + @skip_on_destroy.push(path) + end + @file_entries : Array(AsDataEntry)? # Returns collected file entries. def file_entries : Array(AsDataEntry) @@ -32,7 +41,7 @@ module Teeplate def destroy(out_dir, force : Bool = false, interactive : Bool = false, interact : Bool = false, list : Bool = false, color : Bool = false, per_entry : Bool = false, quit : Bool = true) renderer = Renderer.new(out_dir, force: force, interact: interactive || interact, list: list, color: color, per_entry: per_entry, quit: quit) renderer << destroy_file_entries - renderer.destroy + renderer.destroy(@skip_on_destroy) renderer end diff --git a/src/lib/renderer.cr b/src/lib/renderer.cr index a456c17..218fc6d 100644 --- a/src/lib/renderer.cr +++ b/src/lib/renderer.cr @@ -101,16 +101,21 @@ module Teeplate end end - # :nodoc: - def destroy + # Destroy templates. + # + # If passing paths as skip, these paths will be skipped in the destroy process, and thus will remain on the + # file system + def destroy(skip : Array(String)?) @pending_destroy = true begin if @interactive @entries.each do |entry| - entry.destroy if should_destroy?(entry) + entry.destroy(should_destroy?(entry)) + end + elsif should_destroy_all?(@entries) + @entries.each do |entry| + entry.destroy(should_skip_on_destroy?(entry, skip)) end - else - @entries.each(&.destroy) if should_destroy_all?(@entries) end rescue ex : Quit @quitted = true @@ -138,7 +143,7 @@ module Teeplate STDOUT.puts "Destroy all the following files? (y/n)" entries.each do |entry| - puts entry.out_path + STDOUT.puts entry.out_path end loop do @@ -150,5 +155,32 @@ module Teeplate end end end + + # Determine whether a file should be skipped upon performing #destroy, based on the + # provided array of paths to skip. + def should_skip_on_destroy?(file : RenderingEntry, skip : Array(String)?) : Bool + skip_file = false + + skip_path_parts : Array(String)? + entry_path_parts : Array(String)? + entry_path_parts = file.out_path.split("/") + + skip.each do |skip_path| + skip_path_parts = skip_path.split("/") + + skip_path_parts.unshift(entry_path_parts.first) + skip_path_parts.each_with_index do |part, i| + if i + 1 > entry_path_parts.size + skip_file = false + break + end + skip_file = part.downcase == entry_path_parts[i].downcase + end + + break if skip_file + end + + skip_file + end end end diff --git a/src/lib/rendering_entry.cr b/src/lib/rendering_entry.cr index 41fefb1..62421d1 100644 --- a/src/lib/rendering_entry.cr +++ b/src/lib/rendering_entry.cr @@ -92,11 +92,15 @@ module Teeplate end # :nodoc: - def destroy - begin - File.delete out_path - list_if_any "destroyed ", :red - rescue + def destroy(skip? = false) + unless skip? + begin + File.delete out_path + list_if_any "destroyed ", :red + rescue + list_if_any "skipped ", :yellow + end + else list_if_any "skipped ", :yellow end end From cb092e7663a209a9f7677b1b91dba5949d24046d Mon Sep 17 00:00:00 2001 From: Faustino Aguilar Date: Sun, 18 Mar 2018 12:24:49 -0500 Subject: [PATCH 6/7] Triggering Travis --- src/lib/file_tree.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/file_tree.cr b/src/lib/file_tree.cr index 7930ba9..de127e9 100644 --- a/src/lib/file_tree.cr +++ b/src/lib/file_tree.cr @@ -1,3 +1,4 @@ +# Trying to trigger a Travis CI build, remove this line after that :) module Teeplate # Collects template files from a local directory. abstract class FileTree From 4e2743c3bc97ae6e8d4ccac84117e23eca9aadb9 Mon Sep 17 00:00:00 2001 From: Faustino Aguilar Date: Sun, 18 Mar 2018 12:29:22 -0500 Subject: [PATCH 7/7] Remove line --- src/lib/file_tree.cr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/file_tree.cr b/src/lib/file_tree.cr index de127e9..7930ba9 100644 --- a/src/lib/file_tree.cr +++ b/src/lib/file_tree.cr @@ -1,4 +1,3 @@ -# Trying to trigger a Travis CI build, remove this line after that :) module Teeplate # Collects template files from a local directory. abstract class FileTree