Skip to content

Commit

Permalink
Destroy method from mosop#8
Browse files Browse the repository at this point in the history
  • Loading branch information
AndiLavera committed Aug 22, 2020
1 parent 337c0cc commit 75cf458
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/lib/file_tree.cr
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
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.
macro directory(dir)
{{ 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)
Expand All @@ -28,13 +36,26 @@ 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 << destroy_file_entries
renderer.destroy(@skip_on_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.
def rendered_file_entries
file_entries
end

# :nodoc:
def destroy_file_entries
file_entries
end

# :nodoc:
def ____collect_files(files)
end
Expand Down
85 changes: 85 additions & 0 deletions src/lib/renderer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ module Teeplate
# :nodoc:
getter data_entries = [] of AsDataEntry

# :nodoc:
getter? pending_destroy = false

# :nodoc:
getter entries = [] of RenderingEntry

Expand Down Expand Up @@ -97,6 +100,88 @@ module Teeplate
rescue ex : Quit
@quitted = true
end
end

# 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(should_destroy?(entry))
end
elsif should_destroy_all?(@entries)
@entries.each do |entry|
entry.destroy(should_skip_on_destroy?(entry, skip))
end
end
rescue ex : Quit
@quitted = true
end
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
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|
STDOUT.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

# 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
17 changes: 17 additions & 0 deletions src/lib/rendering_entry.cr
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ module Teeplate
end
end

# :nodoc:
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

# :nodoc:
def set_perm
if perm = @data.perm? && File.file?(out_path)
Expand Down Expand Up @@ -132,6 +146,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
Expand Down Expand Up @@ -223,8 +238,10 @@ module Teeplate
begin
if !GIT.empty?
Process.new(GIT, ["diff", "--no-index", "--", out_path, "-"], shell: true, input: r, output: w2, error: Process::Redirect::Inherit).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: w2, error: Process::Redirect::Inherit).wait
# Process.new(DIFF, ["-u", out_path, "-"], shell: true, input: r, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit).wait
else
w2.puts "No diff command is installed."
end
Expand Down

0 comments on commit 75cf458

Please sign in to comment.