diff --git a/lib/creator.rb b/lib/creator.rb index fd94061..8e937c3 100644 --- a/lib/creator.rb +++ b/lib/creator.rb @@ -1,124 +1,128 @@ # Copyright (C) 2013 Cornelius Schumacher # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. class Creator def initialize settings, name @settings = settings @settings.offline = true @name = name @dir = File.join settings.manifest_path, name end def is_new? return !File.exists?( @dir ) end - + def validate_directory if !File.exists? @dir raise "Unable to find manifest directory '#{@dir}'" end end def update version, release_date filename = File.join @settings.manifest_path, @name, "#{@name}.#{release_date}.manifest" - + mh = ManifestHandler.new @settings mh.read_remote m = mh.manifest @name m.version = version m.release_date = release_date - + File.open( filename, "w" ) do |file| file.puts m.to_json end end def create_dir FileUtils.mkdir_p File.join(@settings.manifest_path,@name) end def create_manifest version, release_date m = ManifestRelease.new m.name = @name m.version = version m.release_date = release_date if version == "edge" m.maturity = "edge" else m.maturity = "stable" end m.platforms = [ "Linux" ] m end def write_manifest manifest - filename = File.join @settings.manifest_path, @name, @name + filename = manifest_basename if manifest.release_date filename += ".#{manifest.release_date}" end filename += ".manifest" File.open( filename, "w" ) do |file| file.puts manifest.to_json end end - + + def manifest_basename + File.join @settings.manifest_path, @name, @name + end + def create_generic_manifest m = ManifestGeneric.new m.name = @name m.display_name = @name.capitalize m.platforms = [ "Linux" ] m end def create_generic create_dir m = create_generic_manifest write_manifest m end - + def create version, release_date create_dir m = create_manifest version, release_date write_manifest m end def create_kf5 version, release_date create_dir m = create_manifest version, release_date m["authors"] = [ "The KDE Community" ] m["licenses"] = [ "LGPLv2.1+" ] vcs = "https://projects.kde.org/projects/kde/kdelibs/repository/revisions/frameworks/show/tier1/" vcs += @name m["urls"] = { "vcs" => vcs, "homepage" => "http://community.kde.org/Frameworks" } - + m["packages"] = { "source" => "http://anongit.kde.org/kdelibs/kdelibs-latest.tar.gz" } write_manifest m end end diff --git a/lib/kde_frameworks_creator.rb b/lib/kde_frameworks_creator.rb index 9bb43d7..9f61f98 100644 --- a/lib/kde_frameworks_creator.rb +++ b/lib/kde_frameworks_creator.rb @@ -1,200 +1,205 @@ # Copyright (C) 2014 Cornelius Schumacher # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. class KdeFrameworksCreator attr_reader :warnings, :errors - + def initialize @frameworks = Hash.new @warnings = [] @errors = [] end - + def parse_checkout dir_name, options = {} @warnings = [] @errors = [] Dir.entries( dir_name ).each do |entry| next if entry =~ /^\./ next if entry == "kapidox" next if entry == "kde4support" next if !File.exist?(File.join(dir_name, entry, ".git")) - + @frameworks[entry] = {} parse_readme File.join(dir_name,entry), options parse_metainfo File.join(dir_name,entry) parse_authors File.join(dir_name,entry) end end def frameworks @frameworks.keys end - + def framework name f = @frameworks[name] raise InqludeError.new("Unable to read '#{name}'") if !f f end - + def parse_readme path, options = {} @errors = [] if !@errors - + name = extract_name( path ) framework = @frameworks[name] || {} framework["link_home_page"] = "http://api.kde.org/frameworks-api/frameworks5-apidocs/#{name}/html/index.html" framework["link_mailing_list"] = "https://mail.kde.org/mailman/listinfo/kde-frameworks-devel" framework["link_git_repository"] = "https://projects.kde.org/projects/frameworks/#{name}/repository" state = nil File.open(File.join(path,"README.md")).each_line do |line| if line =~ /^# (.*)/ framework["title"] = $1 state = :parse_summary next elsif line =~ /^## Introduction/ - framework["introduction"] = "" + framework["introduction"] = "" state = :parse_introduction next elsif line =~ /^## Links/ state = :parse_links next end if state == :parse_summary if line =~ /^##/ state = nil else if !line.strip.empty? framework["summary"] = line.strip end end end - + if state == :parse_introduction if line =~ /^##/ framework["introduction"].strip! state = nil else framework["introduction"] += line end end - + if state == :parse_links if line =~ /^##/ state = nil else if line =~ /- (.*): (.*)/ link_name = $1 url = $2 link_name = link_name.downcase.gsub(/ /,"_") if url =~ /<(.*)>/ url = $1 end framework["link_#{link_name}"] = url end end end end - + required_fields = [] [ "title", "introduction", "link_home_page" ].each do |field| if !options[:ignore_errors] || !options[:ignore_errors].include?(field) required_fields.push field end end - + required_fields.each do |field| if !framework.has_key?(field) || framework[field].strip.empty? @errors.push( { :name => name, :issue => "missing_" + field } ) end end @frameworks[name] = framework end - + def parse_metainfo path name = extract_name( path ) metainfo_path = File.join(path,"metainfo.yaml") if ( !File.exists?( metainfo_path ) ) @errors.push( { :name => name, :issue => "missing_file", :details => "metainfo.yaml" } ) return end metainfo = YAML.load_file(metainfo_path) framework = @frameworks[name] || {} framework["summary"] = metainfo["description"] @frameworks[name] = framework end def parse_authors path name = extract_name( path ) authors_path = File.join(path,"AUTHORS") if ( !File.exists?( authors_path ) ) @warnings.push( { :name => name, :issue => "missing_file", :details => "AUTHORS" } ) return end - + authors = [] File.open(authors_path).each_line do |line| if line =~ /(.* <.*@.*>)/ authors.push $1 end end framework = @frameworks[name] || {} framework["authors"] = authors - + @frameworks[name] = framework end def extract_name path path.split("/").last end - + def create_manifests output_dir settings = Settings.new settings.manifest_path = output_dir @frameworks.each do |name,framework| creator = Creator.new settings, name - manifest = creator.create_generic_manifest + generic_manifest_filename = creator.manifest_basename + ".manifest" + if File.exist?(generic_manifest_filename) + manifest = Manifest.parse_file(creator.manifest_basename + ".manifest") + else + manifest = creator.create_generic_manifest + end fill_in_data framework, manifest creator.create_dir creator.write_manifest manifest end end - + def fill_in_data framework, manifest manifest.display_name = framework["title"] manifest.summary = framework["summary"] manifest.description = framework["introduction"] manifest.urls.vcs = framework["link_git_repository"] manifest.urls.homepage = framework["link_home_page"] manifest.urls.mailing_list = framework["link_mailing_list"] manifest.licenses = [ "LGPLv2.1+" ] manifest.authors = [ "The KDE Community" ] manifest.group = "kde-frameworks" end end diff --git a/spec/data/karchive-generic-with-topics.manifest b/spec/data/karchive-generic-with-topics.manifest new file mode 100644 index 0000000..786eec8 --- /dev/null +++ b/spec/data/karchive-generic-with-topics.manifest @@ -0,0 +1,25 @@ +{ + "$schema": "http://inqlude.org/schema/generic-manifest-v1#", + "name": "karchive", + "display_name": "KArchive", + "summary": "Reading, creating, and manipulating file archives", + "urls": { + "homepage": "https://projects.kde.org/projects/frameworks/karchive", + "vcs": "https://projects.kde.org/projects/frameworks/karchive/repository", + "mailing_list": "https://mail.kde.org/mailman/listinfo/kde-frameworks-devel" + }, + "licenses": [ + "LGPLv2.1+" + ], + "description": "KArchive provides classes for easy reading, creation and manipulation of\n\"archive\" formats like ZIP and TAR.\n\nIf also provides transparent compression and decompression of data, like the\nGZip format, via a subclass of QIODevice.", + "authors": [ + "The KDE Community" + ], + "platforms": [ + "Linux" + ], + "group": "kde-frameworks", + "topics": [ + "Data" + ] +} diff --git a/spec/unit/kde_frameworks_creator_spec.rb b/spec/unit/kde_frameworks_creator_spec.rb index 44b6282..72e8653 100644 --- a/spec/unit/kde_frameworks_creator_spec.rb +++ b/spec/unit/kde_frameworks_creator_spec.rb @@ -1,301 +1,324 @@ require File.expand_path('../spec_helper', __FILE__) describe KdeFrameworksCreator do - + include GivenFilesystemSpecHelpers describe "#framework" do it "raises error on invalid name" do c = KdeFrameworksCreator.new expect{c.framework("invalid-name")}.to raise_error(InqludeError) end end - + describe "#fill_in_data" do it "fills in all data" do c = Creator.new Settings.new, "karchive" manifest = c.create_generic_manifest k = KdeFrameworksCreator.new framework = { "title" => "KArchive", "introduction" => "The intro", "link_git_repository" => "http://git.kde.org/karchive" } k.fill_in_data framework, manifest - + expect( manifest.display_name ).to eq "KArchive" expect( manifest.description ).to eq "The intro" expect( manifest.urls.vcs ).to eq "http://git.kde.org/karchive" end end context "parse git checkout" do - + use_given_filesystem context "multi-directory checkout" do before(:each) do @checkout_path = given_directory do given_directory "karchive" do given_directory(".git") given_dummy_file "README.md" given_dummy_file "AUTHORS" end given_directory "threadweaver" do given_directory(".git") given_dummy_file "README.md" given_dummy_file "AUTHORS" end given_directory "kconfig" do given_directory(".git") given_dummy_file "README.md" given_dummy_file "AUTHORS" end end end it "parses checkout" do c = KdeFrameworksCreator.new c.parse_checkout @checkout_path expect( c.frameworks.sort ).to eq ["karchive", "kconfig", "threadweaver"] end it "generates manifests" do c = KdeFrameworksCreator.new c.parse_checkout @checkout_path output_dir = given_directory - + c.create_manifests output_dir - + expect( File.exists? File.join(output_dir,"karchive", "karchive.manifest") ).to be true expect( File.exists? File.join(output_dir,"threadweaver", "threadweaver.manifest") ).to be true expect( File.exists? File.join(output_dir,"kconfig", "kconfig.manifest") ).to be true end end it "skips non checkout directories" do c = KdeFrameworksCreator.new checkout_path = given_directory do given_directory("empty") end c.parse_checkout checkout_path expect(c.frameworks.count).to eq 0 end it "parses README" do c = KdeFrameworksCreator.new - + framework_path = given_directory "karchive" do given_directory(".git") given_file "README.md", :from => "karchive.readme" end - + c.parse_readme framework_path karchive = c.framework("karchive") - + expect( c.errors.count ).to eq 0 - + expect(karchive["title"]).to eq "KArchive" expect(karchive["introduction"]).to eq "KArchive provides classes for easy reading, creation and manipulation of\n\"archive\" formats like ZIP and TAR.\n\nIf also provides transparent compression and decompression of data, like the\nGZip format, via a subclass of QIODevice." expect(karchive["link_mailing_list"]).to eq "https://mail.kde.org/mailman/listinfo/kde-frameworks-devel" expect(karchive["link_git_repository"]).to eq "https://projects.kde.org/projects/frameworks/karchive/repository" expect(karchive["link_home_page"]).to eq "http://api.kde.org/frameworks-api/frameworks5-apidocs/karchive/html/index.html" expect(karchive["summary"]).to eq "Reading, creation, and manipulation of file archives" end it "parses metainfo.yaml" do c = KdeFrameworksCreator.new framework_path = given_directory "karchive" do given_file "metainfo.yaml", from: "karchive.metainfo.yaml" end c.parse_metainfo framework_path expect(c.errors.empty?).to be(true) karchive = c.framework("karchive") expect(karchive["summary"]).to eq "File compression" end it "parses AUTHORS" do c = KdeFrameworksCreator.new - + framework_path = given_directory "karchive" do given_file "AUTHORS", :from => "karchive.authors" end c.parse_authors framework_path - + karchive = c.framework("karchive") - + expect(karchive["authors"]).to eq [ "Mario Bensi ", "David Faure " ] end - + it "generates warnings for missing files" do c = KdeFrameworksCreator.new checkout_path = given_directory do given_directory "ki18n" do given_directory(".git") given_dummy_file "metainfo.yaml" given_dummy_file "README.md" end end - + c.parse_checkout checkout_path - + expect( c.warnings.count ).to eq 1 expect( c.warnings.first[:name] ).to eq "ki18n" expect( c.warnings.first[:issue] ).to eq "missing_file" expect( c.warnings.first[:details] ).to eq "AUTHORS" end it "generates errors for missing fields" do c = KdeFrameworksCreator.new checkout_path = given_directory do given_directory "ki18n" do given_directory(".git") given_dummy_file "README.md" end end - + c.parse_checkout checkout_path - + f = c.framework("ki18n") - + expect( c.errors.count ).to eq 3 - + error_hash = {} c.errors.each do |error| error_hash[error[:issue]] = error end - + expect( error_hash.has_key? "missing_title" ).to be true expect( error_hash.has_key? "missing_introduction" ).to be true end - + it "generates error for missing summary" do c = KdeFrameworksCreator.new checkout_path = given_directory do given_directory "kservice" do given_directory(".git") given_file "README.md", :from => "kservice.readme" end end - + c.parse_checkout checkout_path - + f = c.framework("kservice") - + expect( f["title"] ).to eq "KService" expect( f["summary"] ).to be nil - + expect( c.errors.count ).to eq 2 end - + it "optionally doesn't generate error for missing summary" do c = KdeFrameworksCreator.new checkout_path = given_directory do given_directory "kservice" do given_directory(".git") given_file "README.md", :from => "kservice.readme" end end - + c.parse_checkout checkout_path, :ignore_errors => [ "link_home_page" ] - + f = c.framework("kservice") - + expect( f["title"] ).to eq "KService" expect( f["summary"] ).to be nil - + expect( c.errors.count ).to eq 2 end - + context "karchive as full example" do before(:each) do @checkout_path = given_directory do given_directory "karchive" do given_directory(".git") given_file "README.md", :from => "karchive.readme" given_file "AUTHORS", :from => "karchive.authors" given_file "metainfo.yaml", from: "karchive.metainfo.yaml" end end end - + it "parses framework from checkout" do c = KdeFrameworksCreator.new c.parse_checkout @checkout_path - + karchive = c.framework("karchive") expect(karchive["title"]).to eq "KArchive" expect(karchive["summary"]).to eq "File compression" expect(karchive["link_git_repository"]).to eq "https://projects.kde.org/projects/frameworks/karchive/repository" expect(karchive["authors"]).to eq [ "Mario Bensi ", "David Faure " ] end it "generates manifest" do c = KdeFrameworksCreator.new c.parse_checkout @checkout_path output_dir = given_directory - + c.create_manifests output_dir - + expect( File.exists? File.join(output_dir,"karchive", "karchive.manifest") ).to be true - + manifest = Manifest.parse_file File.join(output_dir,"karchive", "karchive.manifest") - + expect( manifest.name ).to eq "karchive" expect( manifest.display_name ).to eq "KArchive" expect( manifest.urls.vcs ).to eq "https://projects.kde.org/projects/frameworks/karchive/repository" expect( manifest.urls.homepage ).to eq "http://api.kde.org/frameworks-api/frameworks5-apidocs/karchive/html/index.html" expect( manifest.description ).to eq "KArchive provides classes for easy reading, creation and manipulation of\n\"archive\" formats like ZIP and TAR.\n\nIf also provides transparent compression and decompression of data, like the\nGZip format, via a subclass of QIODevice." expect( manifest.urls.mailing_list ).to eq "https://mail.kde.org/mailman/listinfo/kde-frameworks-devel" expect( manifest.summary ).to eq "File compression" end - + it "overwrites existing manifests" do c = KdeFrameworksCreator.new c.parse_checkout @checkout_path output_dir = given_directory - + c.create_manifests output_dir - + expect( File.exists? File.join(output_dir,"karchive", "karchive.manifest") ).to be true c.create_manifests output_dir - + expect( File.exists? File.join(output_dir,"karchive", "karchive.manifest") ).to be true end + + it "preserves topics from generic manifest" do + c = KdeFrameworksCreator.new + + c.parse_checkout @checkout_path + + manifest_file = nil + output_dir = given_directory do + given_directory "karchive" do + manifest_file = given_file "karchive.manifest", :from => "karchive-generic-with-topics.manifest" + end + end + + manifest = JSON.parse(File.read(manifest_file)) + expect(manifest.has_key?("topics")).to be(true) + expect(manifest["topics"].first).to eq("Data") + + c.create_manifests output_dir + + manifest = JSON.parse(File.read(manifest_file)) + expect(manifest.has_key?("topics")).to be(true) + expect(manifest["topics"].first).to eq("Data") + end end end end