Module: LcpRuby::AssetCopier

Defined in:
lib/lcp_ruby/asset_copier.rb

Overview

Copies a bundled asset tree (the curated docs, or an example app) into a target directory, skipping generated/dev artifacts. Rails-free.

The reject list here is the single source of truth: the gemspec packaging glob mirrors it (so the same artifacts are never packaged), and ‘LcpRuby::CLI::RunCommand` reuses AssetCopier.copy to materialize an example app.

Constant Summary collapse

REJECT_DIRS =

Directory names rejected anywhere in the tree.

%w[tmp log storage node_modules .git .playwright-mcp].freeze
REJECT_BASENAMES =

Basenames rejected at any nesting level (e.g. ERD artifacts).

%w[erd.dot erd.pdf].freeze
SQLITE_SUFFIX_RE =

Matches ‘foo.sqlite3` plus the WAL/SHM/journal session files SQLite writes next to an open DB (`.sqlite3-wal`, `.sqlite3-shm`, `.sqlite3-journal`). Aligned with the gemspec packaging reject regex.

/\.sqlite3(?:-shm|-wal|-journal)?\z/.freeze

Class Method Summary collapse

Class Method Details

.copy(src, dst) ⇒ Object

Copy every file under src into dst, preserving structure and skipping the reject list. Creates dst as needed. Dotfiles are excluded (matching the gemspec packaging glob, which also skips them). Returns the list of copied relative paths.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/lcp_ruby/asset_copier.rb', line 43

def copy(src, dst)
  src = File.expand_path(src)
  dst = File.expand_path(dst)
  copied = []

  Dir.glob("**/*", base: src).each do |rel|
    abs = File.join(src, rel)
    next unless File.file?(abs)
    next if reject?(rel)

    target = File.join(dst, rel)
    FileUtils.mkdir_p(File.dirname(target))
    FileUtils.cp(abs, target)
    copied << rel
  end

  copied
end

.reject?(relative_path) ⇒ Boolean

True if a path (relative to the source root) should be skipped. The rules mirror the gemspec packaging reject regex so ‘lcp examples copy` / `lcp run` materialize the same set of files as the gem ships.

Returns:

  • (Boolean)


27
28
29
30
31
32
33
34
35
36
37
# File 'lib/lcp_ruby/asset_copier.rb', line 27

def reject?(relative_path)
  segments = relative_path.split(File::SEPARATOR)
  basename = segments.last

  return true if segments.any? { |s| REJECT_DIRS.include?(s) }
  return true if REJECT_BASENAMES.include?(basename)
  # SQLite artifacts inside any `db/` directory, at any nesting depth.
  return true if basename.match?(SQLITE_SUFFIX_RE) && segments[0..-2].include?("db")

  false
end