diff --git a/app/models/package_manager/opam.rb b/app/models/package_manager/opam.rb new file mode 100644 index 000000000..fc48424b3 --- /dev/null +++ b/app/models/package_manager/opam.rb @@ -0,0 +1,75 @@ +module PackageManager + class Opam < Base + HAS_VERSIONS = false + HAS_DEPENDENCIES = false + BIBLIOTHECARY_SUPPORT = false + BIBLIOTHECARY_PLANNED = true + URL = 'https://opam.ocaml.org' + COLOR = '#3be133' + + def self.project_names + get_html("https://opam.ocaml.org/packages/").css('tbody tr').map{|tr| tr.css('a').first.try(:text)} + end + + def self.project(name) + { + name: name, + page: get_html("https://opam.ocaml.org/packages/#{name}/") + } + end + + def self.mapping(project) + { + name: project[:name], + keywords_array: extract_keywords(project[:page]), + description: extract_description(project[:page]), + licenses: extract_licenses(project[:page]), + homepage: extract_homepage(project[:page]), + repository_url: extract_repository_url(project[:page]) + } + end + + def self.extract_keywords(page) + list_str = find_attribute(page, 'Tags') + list_str ? generate_list(list_str) : [] + end + + def self.extract_description(page) + page.css('.well h4').try(:text) + end + + def self.extract_licenses(page) + find_attribute(page, 'License') + end + + def self.extract_homepage(page) + find_attribute(page, 'Homepage') + end + + def self.extract_repository_url(page) + repository_url = find_attribute(page, 'Issue Tracker') + repository_url.chomp('/issues') if repository_url + end + + def self.find_attribute(page, name) + tr = page.css('.table tr').select { |t| t.css('th').text == name }.first + tr.css('td').text if tr + end + + def self.generate_list(list_str) + list_str.split(/,\s|\sand\s/) + end + + def self.formatted_name + 'opam' + end + + def self.package_link(project, _version = nil) + "https://opam.ocaml.org/packages/#{project}/" + (_version ? "#{project}.#{_version}" : "") + end + + def self.install_instructions(project, version = nil) + "opam install #{project}" + (version ? ".#{version}" : "") + end + end +end \ No newline at end of file diff --git a/lib/tasks/download.rake b/lib/tasks/download.rake index d177041fd..79a65d414 100644 --- a/lib/tasks/download.rake +++ b/lib/tasks/download.rake @@ -197,6 +197,11 @@ namespace :download do PackageManager::NPM.import end + desc 'Download all Opam packages' + task opam: :environment do + PackageManager::Opam.import + end + desc 'Download recent Packagist packages asynchronously' task packagist: :environment do PackageManager::Packagist.import_recent_async diff --git a/spec/models/package_manager/opam_spec.rb b/spec/models/package_manager/opam_spec.rb new file mode 100644 index 000000000..f05a2a543 --- /dev/null +++ b/spec/models/package_manager/opam_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' + +describe PackageManager::Opam do + let(:project) { create(:project, name: 'foo', platform: described_class.name) } + + it "has formatted name of 'opam'" do + expect(described_class.formatted_name).to eq('opam') + end + + describe '#package_link' do + it 'returns a link to project website' do + expect(described_class.package_link(project)).to eq("https://opam.ocaml.org/packages/foo/") + end + + it 'handles version' do + expect(described_class.package_link(project, '2.0.0')).to eq("https://opam.ocaml.org/packages/foo/foo.2.0.0") + end + end + + describe '#install_instructions' do + it 'returns a command to install the project' do + expect(described_class.install_instructions(project)).to eq("opam install foo") + end + + it 'handles version' do + expect(described_class.install_instructions(project, '2.0.0')).to eq("opam install foo.2.0.0") + end + end + +end \ No newline at end of file