Class: Depot::ArchivePackage

Inherits:
Object
  • Object
show all
Defined in:
lib/depot/packages/archive.rb

Defined Under Namespace

Classes: FormatError

Constant Summary collapse

DESKTOP_PATH =
%r{\A(?:\./)?(.+/)?[^/]+\.desktop\z}
HICOLOR_ICON_PATH =
%r{/icons/hicolor/([^/]+)/apps/([^/]+)\.(png|svg|xpm)\z}i
IMAGE_EXT =
/\.(png|svg|xpm)\z/i
SCRIPT_EXT =
/\.(sh|bash|run|pl|py|rb)\z/i
SOURCE_MARKERS =
%w[configure Makefile CMakeLists.txt meson.build setup.py package.json Cargo.toml go.mod].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ ArchivePackage

Returns a new instance of ArchivePackage.



16
17
18
# File 'lib/depot/packages/archive.rb', line 16

def initialize(path)
  @path = path
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



14
15
16
# File 'lib/depot/packages/archive.rb', line 14

def path
  @path
end

Instance Method Details

#clean_membersObject



46
47
48
# File 'lib/depot/packages/archive.rb', line 46

def clean_members
  members.map { |entry| clean_entry(entry) }
end

#common_rootObject



84
85
86
87
# File 'lib/depot/packages/archive.rb', line 84

def common_root
  roots = clean_members.reject(&:empty?).map { |entry| entry.split("/", 2).first }.uniq
  roots.length == 1 ? roots.first : nil
end

#desktop_entriesObject



50
51
52
# File 'lib/depot/packages/archive.rb', line 50

def desktop_entries
  clean_members.select { |entry| entry.end_with?(".desktop") }
end

#display_nameObject



35
36
37
38
39
40
# File 'lib/depot/packages/archive.rb', line 35

def display_name
  root = common_root
  return titleize(root) if root && root != "."

  titleize(File.basename(path).sub(/\.(tar\.gz|tgz|tar\.xz|txz|tar\.zst|tzst)\z/i, ""))
end

#executable_candidatesObject



66
67
68
69
70
# File 'lib/depot/packages/archive.rb', line 66

def executable_candidates
  clean_members.reject { |entry| entry.end_with?("/") }
               .select { |entry| executable_name?(entry) }
               .first(24)
end

#extract_to(destination) ⇒ Object

Raises:



100
101
102
103
104
105
# File 'lib/depot/packages/archive.rb', line 100

def extract_to(destination)
  FileUtils.mkdir_p(destination)
  assert_safe_entries!
  stdout, stderr, status = Open3.capture3("tar", *tar_options, "-xf", path, "-C", destination)
  raise FormatError, "Could not extract archive: #{stderr.empty? ? stdout : stderr}" unless status.success?
end

#formatObject



26
27
28
29
30
31
32
33
# File 'lib/depot/packages/archive.rb', line 26

def format
  case File.basename(path)
  when /\.t(?:ar\.)?gz\z/i, /\.tgz\z/i then "tar.gz"
  when /\.tar\.xz\z/i, /\.txz\z/i then "tar.xz"
  when /\.tar\.zst\z/i, /\.tzst\z/i then "tar.zst"
  else "archive"
  end
end

#icon_entriesObject



62
63
64
# File 'lib/depot/packages/archive.rb', line 62

def icon_entries
  clean_members.select { |entry| entry.match?(HICOLOR_ICON_PATH) }
end

#image_entriesObject



58
59
60
# File 'lib/depot/packages/archive.rb', line 58

def image_entries
  clean_members.select { |entry| entry.match?(IMAGE_EXT) }
end

#membersObject



42
43
44
# File 'lib/depot/packages/archive.rb', line 42

def members
  @members ||= list_archive
end

#primary_desktop_entryObject



54
55
56
# File 'lib/depot/packages/archive.rb', line 54

def primary_desktop_entry
  desktop_entries.min_by { |entry| desktop_score(entry) }
end

#read_entry(entry) ⇒ Object

Raises:



89
90
91
92
93
94
95
96
97
98
# File 'lib/depot/packages/archive.rb', line 89

def read_entry(entry)
  wanted = clean_entry(entry)
  candidate = members.find { |member| clean_entry(member) == wanted }
  raise FormatError, "Could not find #{entry} in archive" unless candidate

  stdout, stderr, status = Open3.capture3("tar", *tar_options, "-xOf", path, candidate)
  raise FormatError, "Could not read #{entry}: #{stderr.empty? ? stdout : stderr}" unless status.success?

  stdout
end

#script_entriesObject



72
73
74
75
76
# File 'lib/depot/packages/archive.rb', line 72

def script_entries
  clean_members.reject { |entry| entry.end_with?("/") }
               .select { |entry| File.basename(entry).match?(SCRIPT_EXT) || File.basename(entry).match?(/\Ainstall/i) }
               .first(24)
end

#source_markersObject



78
79
80
81
82
# File 'lib/depot/packages/archive.rb', line 78

def source_markers
  clean_members.map { |entry| File.basename(entry) }
               .select { |name| SOURCE_MARKERS.include?(name) }
               .uniq
end

#valid?Boolean

Returns:

  • (Boolean)


20
21
22
23
24
# File 'lib/depot/packages/archive.rb', line 20

def valid?
  tar_name? && !members.empty?
rescue FormatError
  false
end