Class: Ace::Support::Items::Molecules::FolderMover

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/support/items/molecules/folder_mover.rb

Overview

Generic folder mover for item directories. Handles special folder name normalization, archive date partitioning, and cross-filesystem atomic moves.

Instance Method Summary collapse

Constructor Details

#initialize(root_dir) ⇒ FolderMover

Returns a new instance of FolderMover.

Parameters:

  • root_dir (String)

    Root directory for items



16
17
18
# File 'lib/ace/support/items/molecules/folder_mover.rb', line 16

def initialize(root_dir)
  @root_dir = root_dir
end

Instance Method Details

#move(item, to:, date: nil) ⇒ String

Move an item folder to a target location.

Parameters:

  • item (#path)

    Item with a path attribute (directory to move)

  • to (String)

    Target folder name (short or full, e.g., “maybe”, “_archive”)

  • date (Time, nil) (defaults to: nil)

    Date used to compute archive partition (default: Time.now)

Returns:

  • (String)

    New path of the item directory



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ace/support/items/molecules/folder_mover.rb', line 26

def move(item, to:, date: nil)
  if Atoms::SpecialFolderDetector.virtual_filter?(to)
    raise ArgumentError, "Cannot move to virtual filter '#{to}' — it is not a physical folder"
  end

  normalized = Atoms::SpecialFolderDetector.normalize(to)

  target_parent = if normalized == "_archive"
    partition = Atoms::DatePartitionPath.compute(date || Time.now)
    File.expand_path(File.join(@root_dir, normalized, partition))
  else
    File.expand_path(File.join(@root_dir, normalized))
  end

  validate_path_traversal!(target_parent)
  FileUtils.mkdir_p(target_parent)

  folder_name = File.basename(item.path)
  new_path = File.join(target_parent, folder_name)

  # Same-location no-op check
  return item.path if File.expand_path(item.path) == File.expand_path(new_path)

  atomic_move(item.path, new_path)
end

#move_to_root(item) ⇒ String

Move an item back to root (remove from special folder).

Parameters:

  • item (#path)

    Item with a path attribute

Returns:

  • (String)

    New path of the item directory



56
57
58
59
60
61
62
63
64
# File 'lib/ace/support/items/molecules/folder_mover.rb', line 56

def move_to_root(item)
  folder_name = File.basename(item.path)
  new_path = File.join(@root_dir, folder_name)

  # Same-location no-op check
  return item.path if File.expand_path(item.path) == File.expand_path(new_path)

  atomic_move(item.path, new_path)
end