Class: Licensed::Source::Cabal
- Inherits:
-
Object
- Object
- Licensed::Source::Cabal
- Defined in:
- lib/licensed/source/cabal.rb
Instance Method Summary collapse
-
#cabal_files ⇒ Object
Returns an array of the local directory cabal package files.
-
#cabal_packages ⇒ Object
Return an array of the top-level cabal packages for the current app.
- #dependencies ⇒ Object
- #enabled? ⇒ Boolean
-
#ghc? ⇒ Boolean
Returns whether the ghc cli tool is available.
-
#ghc_pkg_field_command(id, fields, *args) ⇒ Object
Runs a ‘ghc-pkg field` command for a given set of fields and arguments Automatically includes ghc package DB locations in the command.
-
#ghc_version ⇒ Object
Returns the ghc cli tool version.
-
#initialize(config) ⇒ Cabal
constructor
A new instance of Cabal.
-
#package_db_args ⇒ Object
Returns an array of ghc package DB locations as specified in the app configuration.
-
#package_dependencies(id, full_id = true) ⇒ Object
Returns an array of dependency package names for the cabal package given by ‘id`.
-
#package_dependencies_command(id, full_id) ⇒ Object
Returns the output of running ‘ghc-pkg field depends` for a package id Optionally allows for interpreting the given id as an installed package id (`–ipid`).
-
#package_docs_dirs(package) ⇒ Object
Returns the packages document directory and search root directory as an array.
-
#package_ids ⇒ Object
Returns a ‘Set` of the package ids for all cabal dependencies.
-
#package_info(id) ⇒ Object
Returns package information as a hash for the given id.
-
#package_info_command(id) ⇒ Object
Returns the output of running ‘ghc-pkg field` to obtain package information.
-
#realized_ghc_package_path(path) ⇒ Object
Returns a ghc package path with template markers replaced by live data.
-
#recursive_dependencies(package_names, results = Set.new) ⇒ Object
Recursively finds the dependencies for each cabal package.
-
#safe_homepage(homepage) ⇒ Object
Returns a homepage url that enforces https and removes url fragments.
- #type ⇒ Object
Constructor Details
#initialize(config) ⇒ Cabal
Returns a new instance of Cabal.
7 8 9 |
# File 'lib/licensed/source/cabal.rb', line 7 def initialize(config) @config = config end |
Instance Method Details
#cabal_files ⇒ Object
Returns an array of the local directory cabal package files
160 161 162 |
# File 'lib/licensed/source/cabal.rb', line 160 def cabal_files @cabal_files ||= Dir.glob(File.join(@config.pwd, "*.cabal")) end |
#cabal_packages ⇒ Object
Return an array of the top-level cabal packages for the current app
152 153 154 155 156 157 |
# File 'lib/licensed/source/cabal.rb', line 152 def cabal_packages cabal_files.map do |f| name_match = File.read(f).match(/^name:\s*(.*)$/) name_match[1] if name_match end.compact end |
#dependencies ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/licensed/source/cabal.rb', line 19 def dependencies @dependencies ||= package_ids.map do |id| package = package_info(id) path, search_root = package_docs_dirs(package) Dependency.new(path, { "type" => type, "name" => package["name"], "version" => package["version"], "summary" => package["synopsis"], "homepage" => safe_homepage(package["homepage"]), "search_root" => search_root }) end end |
#enabled? ⇒ Boolean
15 16 17 |
# File 'lib/licensed/source/cabal.rb', line 15 def enabled? @config.enabled?(type) && cabal_packages.any? && ghc? end |
#ghc? ⇒ Boolean
Returns whether the ghc cli tool is available
171 172 173 |
# File 'lib/licensed/source/cabal.rb', line 171 def ghc? @ghc ||= Licensed::Shell.tool_available?("ghc") end |
#ghc_pkg_field_command(id, fields, *args) ⇒ Object
Runs a ‘ghc-pkg field` command for a given set of fields and arguments Automatically includes ghc package DB locations in the command
127 128 129 |
# File 'lib/licensed/source/cabal.rb', line 127 def ghc_pkg_field_command(id, fields, *args) Licensed::Shell.execute("ghc-pkg", "field", id, fields.join(","), *args, *package_db_args) end |
#ghc_version ⇒ Object
Returns the ghc cli tool version
165 166 167 168 |
# File 'lib/licensed/source/cabal.rb', line 165 def ghc_version return unless ghc? @version ||= Licensed::Shell.execute("ghc", "--numeric-version") end |
#package_db_args ⇒ Object
Returns an array of ghc package DB locations as specified in the app configuration
133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/licensed/source/cabal.rb', line 133 def package_db_args return [] unless @config["cabal"] Array(@config["cabal"]["ghc_package_db"]).map do |path| next "--#{path}" if %w(global user).include?(path) path = realized_ghc_package_path(path) path = File.(path, @config.pwd) next unless File.exist?(path) "--package-db=#{path}" end.compact end |
#package_dependencies(id, full_id = true) ⇒ Object
Returns an array of dependency package names for the cabal package given by ‘id`
90 91 92 93 94 |
# File 'lib/licensed/source/cabal.rb', line 90 def package_dependencies(id, full_id = true) package_dependencies_command(id, full_id).gsub("depends:", "") .split .map(&:strip) end |
#package_dependencies_command(id, full_id) ⇒ Object
Returns the output of running ‘ghc-pkg field depends` for a package id Optionally allows for interpreting the given id as an installed package id (`–ipid`)
99 100 101 102 103 104 105 106 107 |
# File 'lib/licensed/source/cabal.rb', line 99 def package_dependencies_command(id, full_id) fields = %w(depends) if full_id ghc_pkg_field_command(id, fields, "--ipid") else ghc_pkg_field_command(id, fields) end end |
#package_docs_dirs(package) ⇒ Object
Returns the packages document directory and search root directory as an array
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/licensed/source/cabal.rb', line 37 def package_docs_dirs(package) unless package["haddock-html"] # default to a local vendor directory if haddock-html property # isn't available return [File.join(@config.pwd, "vendor", package["name"]), nil] end html_dir = package["haddock-html"] data_dir = package["data-dir"] return [html_dir, nil] unless data_dir # only allow data directories that are ancestors of the html directory unless Pathname.new(html_dir).fnmatch?(File.join(data_dir, "**")) data_dir = nil end [html_dir, data_dir] end |
#package_ids ⇒ Object
Returns a ‘Set` of the package ids for all cabal dependencies
65 66 67 68 |
# File 'lib/licensed/source/cabal.rb', line 65 def package_ids deps = cabal_packages.flat_map { |n| package_dependencies(n, false) } recursive_dependencies(deps) end |
#package_info(id) ⇒ Object
Returns package information as a hash for the given id
110 111 112 113 114 115 116 117 |
# File 'lib/licensed/source/cabal.rb', line 110 def package_info(id) package_info_command(id).lines.each_with_object({}) do |line, info| key, value = line.split(":", 2).map(&:strip) next unless key && value info[key] = value end end |
#package_info_command(id) ⇒ Object
Returns the output of running ‘ghc-pkg field` to obtain package information
120 121 122 123 |
# File 'lib/licensed/source/cabal.rb', line 120 def package_info_command(id) fields = %w(name version synopsis homepage haddock-html data-dir) ghc_pkg_field_command(id, fields, "--ipid") end |
#realized_ghc_package_path(path) ⇒ Object
Returns a ghc package path with template markers replaced by live data
147 148 149 |
# File 'lib/licensed/source/cabal.rb', line 147 def realized_ghc_package_path(path) path.gsub("<ghc_version>", ghc_version) end |
#recursive_dependencies(package_names, results = Set.new) ⇒ Object
Recursively finds the dependencies for each cabal package. Returns a ‘Set` containing the package names for all dependencies
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/licensed/source/cabal.rb', line 72 def recursive_dependencies(package_names, results = Set.new) return [] if package_names.nil? || package_names.empty? new_packages = Set.new(package_names) - results.to_a return [] if new_packages.empty? results.merge new_packages dependencies = new_packages.flat_map { |n| package_dependencies(n) } .compact return results if dependencies.empty? results.merge recursive_dependencies(dependencies, results) end |
#safe_homepage(homepage) ⇒ Object
Returns a homepage url that enforces https and removes url fragments
57 58 59 60 61 62 |
# File 'lib/licensed/source/cabal.rb', line 57 def safe_homepage(homepage) return unless homepage # use https and remove url fragment homepage.gsub(/http:/, "https:") .gsub(/#[^?]*\z/, "") end |
#type ⇒ Object
11 12 13 |
# File 'lib/licensed/source/cabal.rb', line 11 def type "cabal" end |