Class: Cask::DesktopFileParser Private

Inherits:
Object
  • Object
show all
Defined in:
cask/desktop_file_parser.rb

Overview

This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

Reads and edits freedesktop.org desktop entry files, keeping their comments and layout. Ref: https://specifications.freedesktop.org/desktop-entry/latest/

Instance Method Summary collapse

Constructor Details

#initialize(contents) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:



24
25
26
# File 'cask/desktop_file_parser.rb', line 24

def initialize(contents)
  @lines = T.let(contents.scrub.lines(chomp: true), T::Array[String])
end

Instance Method Details

#desktop_entry? ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Whether the first group is [Desktop Entry], as the spec requires of desktop entries.

Returns:

  • (Boolean)


30
31
32
# File 'cask/desktop_file_parser.rb', line 30

def desktop_entry?
  @lines.find { |line| line.strip.present? && !line.start_with?("#") }&.strip == "[#{DESKTOP_ENTRY_GROUP}]"
end

#get(key) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

The value of key in the [Desktop Entry] group, with escape sequences resolved.

Parameters:

Returns:



36
37
38
39
# File 'cask/desktop_file_parser.rb', line 36

def get(key)
  each_value(key) { |value, group| return value if group == DESKTOP_ENTRY_GROUP }
  nil
end

#replace_program(program, environment:) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Point every Exec and TryExec at program, keeping the arguments and environment variables of each Exec and setting environment with env, e.g. for program: "<target>" and environment: { "DESKTOPINTEGRATION" => "1" }:

Input:  Exec=env GDK_BACKEND=x11 UBUNTU_MENUPROXY=0 audacity %F
Output: Exec=env DESKTOPINTEGRATION=1 GDK_BACKEND=x11 UBUNTU_MENUPROXY=0 <target> %F

Raises ArgumentError if an Exec has unmatched quotes.

Parameters:



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'cask/desktop_file_parser.rb', line 58

def replace_program(program, environment:)
  update("TryExec") { program }
  update("Exec") do |exec|
    words = Shellwords.split(exec)
    # Variables can be set with or without a leading `env`.
    words.shift if words.first == "env"
    variables = words.take_while { |word| word.match?(/\A[A-Za-z_]\w*=/) }
    # Skip the program itself, which is replaced.
    arguments = words.drop(variables.length + 1)
    # `environment` takes precedence over the same variables in `exec`.
    variables.reject! { |variable| environment.key?(variable.split("=", 2).fetch(0)) }
    variables.unshift(*environment.map { |name, value| "#{name}=#{value}" })
    # `%` starts a field code like `%U`, so a literal one in `program` must be doubled.
    ["env", *variables, program.gsub("%", "%%"), *arguments].map do |word|
      # Quote only what needs it, as some launchers split `Exec` on spaces and keep the quotes.
      next word unless word.match?(EXEC_RESERVED_CHARACTERS)

      # Surround with quotes and precede `"`, `` ` ``, `$` and `\` with `\`.
      "\"#{word.gsub(/["`$\\]/) { |character| "\\#{character}" }}\""
    end.join(" ")
  end
end

#update(key, &block) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Replace the value of key in every group that sets it with the block's result.

Parameters:



43
44
45
46
47
48
49
# File 'cask/desktop_file_parser.rb', line 43

def update(key, &block)
  each_value(key) do |value, _group, index|
    # Reverse of the escape sequences `each_value` resolves.
    value = yield(value).gsub(/[\\\n\t\r]/, "\\" => "\\\\", "\n" => "\\n", "\t" => "\\t", "\r" => "\\r")
    @lines[index] = "#{key}=#{value}"
  end
end