Class: Clacky::TrashDirectory

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/utils/trash_directory.rb

Overview

Manages global trash directory at ~/.clacky/trash Organizes trash by project directory using path hash

Constant Summary collapse

GLOBAL_TRASH_ROOT =
File.join(Dir.home, ".clacky", "trash")

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project_root = Dir.pwd) ⇒ TrashDirectory

Returns a new instance of TrashDirectory.



14
15
16
17
18
19
20
21
# File 'lib/clacky/utils/trash_directory.rb', line 14

def initialize(project_root = Dir.pwd)
  @project_root = File.expand_path(project_root)
  @project_hash = generate_project_hash(@project_root)
  @trash_dir = File.join(GLOBAL_TRASH_ROOT, @project_hash)
  @backup_dir = File.join(@trash_dir, "backups")
  
  setup_directories
end

Instance Attribute Details

#backup_dirObject (readonly)

Returns the value of attribute backup_dir.



12
13
14
# File 'lib/clacky/utils/trash_directory.rb', line 12

def backup_dir
  @backup_dir
end

#project_rootObject (readonly)

Returns the value of attribute project_root.



12
13
14
# File 'lib/clacky/utils/trash_directory.rb', line 12

def project_root
  @project_root
end

#trash_dirObject (readonly)

Returns the value of attribute trash_dir.



12
13
14
# File 'lib/clacky/utils/trash_directory.rb', line 12

def trash_dir
  @trash_dir
end

Class Method Details

.all_projectsObject

Get all project directories that have trash



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/clacky/utils/trash_directory.rb', line 67

def self.all_projects
  return [] unless Dir.exist?(GLOBAL_TRASH_ROOT)
  
  projects = []
  Dir.glob(File.join(GLOBAL_TRASH_ROOT, "*", ".project_metadata.json")).each do ||
    begin
       = JSON.parse(File.read())
      projects << {
        project_root: ['project_root'],
        project_name: ['project_name'],
        project_hash: ['project_hash'],
        trash_dir: File.dirname(),
        last_accessed: ['last_accessed']
      }
    rescue StandardError
      # Skip corrupted metadata
    end
  end
  
  projects.sort_by { |p| p[:last_accessed] }.reverse
end

.cleanup_orphaned_projectsObject

Clean up trash directories for non-existent projects



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/clacky/utils/trash_directory.rb', line 95

def self.cleanup_orphaned_projects
  return 0 unless Dir.exist?(GLOBAL_TRASH_ROOT)
  
  cleaned_count = 0
  all_projects.each do |project|
    unless Dir.exist?(project[:project_root])
      # Project no longer exists, optionally remove trash
      # For safety, we'll just mark it as orphaned
      orphan_file = File.join(project[:trash_dir], '.orphaned')
      File.write(orphan_file, "Original project path no longer exists: #{project[:project_root]}\n")
      cleaned_count += 1
    end
  end
  
  cleaned_count
end

.for_project(project_root) ⇒ Object

Get trash directory for a specific project



90
91
92
# File 'lib/clacky/utils/trash_directory.rb', line 90

def self.for_project(project_root)
  new(project_root)
end

Instance Method Details

#create_project_metadataObject

Create or update metadata about this project



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/clacky/utils/trash_directory.rb', line 49

def 
   = File.join(@trash_dir, '.project_metadata.json')
  
   = {
    project_root: @project_root,
    project_name: File.basename(@project_root),
    project_hash: @project_hash,
    created_at: File.exist?() ? JSON.parse(File.read())['created_at'] : Time.now.iso8601,
    last_accessed: Time.now.iso8601
  }
  
  File.write(, JSON.pretty_generate())
rescue StandardError => e
  # Log warning but don't block operation
  warn "Warning: Could not create project metadata: #{e.message}"
end

#generate_project_hash(path) ⇒ Object

Generate a unique hash for project path



24
25
26
27
28
29
30
# File 'lib/clacky/utils/trash_directory.rb', line 24

def generate_project_hash(path)
  # Use MD5 hash of the absolute path, take first 16 chars for readability
  hash = Digest::MD5.hexdigest(path)[0..15]
  # Also include a readable suffix based on project name
  project_name = File.basename(path).gsub(/[^a-zA-Z0-9_-]/, '_')[0..20]
  "#{hash}_#{project_name}"
end

#setup_directoriesObject

Setup trash and backup directories with proper structure



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/clacky/utils/trash_directory.rb', line 33

def setup_directories
  [@trash_dir, @backup_dir].each do |dir|
    FileUtils.mkdir_p(dir) unless Dir.exist?(dir)

    # Create .gitignore file to avoid trash files being committed
    gitignore_path = File.join(dir, '.gitignore')
    unless File.exist?(gitignore_path)
      File.write(gitignore_path, "*\n!.gitignore\n")
    end
  end

  # Create project metadata file
  
end