class Dr::GitPackage
Public Class Methods
new(name, repo)
click to toggle source
Calls superclass method
# File lib/dr/gitpackage.rb, line 67 def initialize(name, repo) super name, repo @git_dir = "#{repo.location}/packages/#{name}/source" @default_branch = get_current_branch end
setup(repo, git_addr, default_branch, force=false)
click to toggle source
# File lib/dr/gitpackage.rb, line 14 def self.setup(repo, git_addr, default_branch, force=false) Dir.mktmpdir do |tmp| git_cmd = "git clone --mirror --branch #{default_branch} " + "#{git_addr} #{tmp}/git" ShellCmd.new git_cmd, :tag => "git", :show_out => true FileUtils.mkdir_p "#{tmp}/src" log :info, "Extracting the sources" git_cmd ="git --git-dir #{tmp}/git --bare archive " + "--format tar #{default_branch} | tar x -C #{tmp}/src" ShellCmd.new git_cmd, :tag => "git", :show_out => true unless File.exists? "#{tmp}/src/debian/control" log :err, "The debian packaging files not found in the repository" raise "Adding a package from #{git_addr} failed" end src_name = nil File.open "#{tmp}/src/debian/control", "r" do |f| f.each_line do |line| match = line.match(/^Source: (.+)$/) if match src_name = match.captures[0] break end end end unless src_name log :err, "Couldn't identify the source package" raise "Adding a package from #{git_addr} failed" end pkg_dir = "#{repo.location}/packages/#{src_name}" if File.exists? pkg_dir log :warn, "The package already exists. Add -f to insert it anyway." raise "Adding failed" end log :info, "Adding #{src_name.style "pkg-name"} to the repository" FileUtils.mkdir_p "#{pkg_dir}" log :info, "Setting up builds directory" FileUtils.mkdir_p "#{pkg_dir}/builds" log :info, "Setting up the source directory" FileUtils.mv "#{tmp}/git", "#{pkg_dir}/source" log :info, "The #{src_name.style "pkg-name"} package added successfully" end end
Public Instance Methods
build(branch=nil, force=false)
click to toggle source
# File lib/dr/gitpackage.rb, line 141 def build(branch=nil, force=false) branch = @default_branch unless branch version = nil orig_rev, curr_rev = update_from_origin branch unless curr_rev log :err, "Branch #{branch.fg "blue"} not found in #{@name.style "pkg-name"}" raise "The requested branch doesn't exist in the repository!" end log :info, "Branch #{branch.fg "blue"}, revision #{curr_rev[0..7].fg "blue"}" unless force history.each do |v| metadata = @repo.get_build_metadata @name, v if metadata.has_key?("revision") && metadata["revision"] == curr_rev msg = "This revision of #{@name.style "pkg-name"} has already " + "been built and is available as #{v.to_s.style "version"}" log :info, msg return v end end end Dir.mktmpdir do |src_dir| checkout branch, src_dir version_string = get_version "#{src_dir}/debian/changelog" unless version_string log :err, "Couldn't get the version string from the changelog" raise "The changelog format doesn't seem be right" end version = PkgVersion.new version_string log :info, "Source version: #{version.source.style "version"}" version.add_build_tag while build_exists? version version.increment! end log :info, "Build version: #{version.to_s.style "version"}" log :info, "Updating changelog" now = Time.new.strftime("%a, %-d %b %Y %T %z") ch_entry = "#{@name} (#{version}) kano; urgency=low\n" ch_entry << "\n" ch_entry << " * Package rebuilt, updated to revision #{curr_rev[0..7]}.\n" ch_entry << "\n" ch_entry << " -- Team Kano <dev@kano.me> #{now}\n\n" changelog = "" File.open "#{src_dir}/debian/changelog", "r" do |f| changelog = f.read end File.open "#{src_dir}/debian/changelog", "w" do |f| f.write ch_entry f.write changelog end repo_arches = @repo.get_architectures pkg_arches = get_architectures("#{src_dir}/debian/control") arches = case when pkg_arches.include?("any") repo_arches when pkg_arches.include?("all") ["all"] else repo_arches & pkg_arches end if repo_arches.length == 0 log :err, "#{@name.style "pkg-name"} cannot be build for any of " + "the architectures supported by this repository" raise "Unable to build the package for this repository" end benv = :default src_meta = get_configuration if src_meta.has_key? :build_environment benv = src_meta[:build_environment].to_sym end arches.each do |arch| @repo.buildroot(arch, benv).open do |br| log :info, "Building the #{@name.style "pkg-name"} package " + "version #{version.to_s.style "version"} for #{arch}" # Moving to the proper directory build_dir_name = "#{@name}-#{version.upstream}" build_dir = "#{br}/#{build_dir_name}" FileUtils.cp_r src_dir, build_dir # Make orig tarball all_files = Dir["#{build_dir}/*"] + Dir["#{build_dir}/.*"] excluded_files = ['.', '..', '.git', 'debian'] selected_files = all_files.select { |path| !excluded_files.include?(File.basename(path)) } files = selected_files.map { |f| "\"#{File.basename f}\"" }.join " " log :info, "Creating orig source tarball" tar = "tar cz -C #{build_dir} " + "-f #{br}/#{@name}_#{version.upstream}.orig.tar.gz " + "#{files}" ShellCmd.new tar, :tag => "tar" apt = "sudo chroot #{br} apt-get update" deps = <<-EOS sudo chroot #{br} <<EOF dpkg-source -b "/#{build_dir_name}" mk-build-deps *.dsc -i -t "apt-get --no-install-recommends -y" rm -rf #{@name}-build-deps_* EOF EOS build = <<-EOS sudo chroot #{br} <<EOF cd /#{build_dir_name} debuild -i -uc -us -b EOF EOS log :info, "Updating the sources lists" ShellCmd.new apt, :tag => "apt-get", :show_out => true log :info, "Installing build dependencies" ShellCmd.new deps, :tag => "mk-build-deps", :show_out => true log :info, "Building the package" ShellCmd.new build, :tag => "debuild", :show_out => true debs = Dir["#{br}/*.deb"] expected_pkgs = get_subpackage_names "#{src_dir}/debian/control" expected_pkgs.each do |subpkg_name| includes = debs.inject(false) do |r, n| r || ((/^#{br}\/#{subpkg_name}_#{version.to_s omit_epoch=true}/ =~ n) != nil) end unless includes log :err, "Subpackage #{subpkg_name} did not build properly" raise "Building #{name} failed" end end build_dir = "#{@repo.location}/packages/#{@name}/builds/#{version}" FileUtils.mkdir_p build_dir debs.each do |pkg| FileUtils.cp pkg, build_dir deb_filename = File.basename(pkg) log :info, "Signing the #{deb_filename.style "subpkg-name"} package" @repo.sign_deb "#{build_dir}/#{deb_filename}" end log :info, "Writing package metadata" File.open "#{build_dir}/.metadata", "w" do |f| YAML.dump({"branch" => branch, "revision" => curr_rev}, f) end log :info, "The #{@name.style "pkg-name"} package was " + "built successfully." end end end version end
get_configuration()
click to toggle source
# File lib/dr/gitpackage.rb, line 124 def get_configuration md_file = "#{@repo.location}/packages/#{@name}/metadata" if File.exists? md_file Utils::symbolise_keys YAML.load_file md_file else {} end end
reinitialise_repo(git_addr=nil, branch=nil)
click to toggle source
# File lib/dr/gitpackage.rb, line 74 def reinitialise_repo(git_addr=nil, branch=nil) git_addr ||= get_repo_url branch ||= @default_branch log :info, "Re-downloading the source repository of " + "#{@name.style "pkg-name"}" Dir.mktmpdir do |tmp| git_cmd = "git clone --mirror --branch #{branch} " + "#{git_addr} #{tmp}/git" ShellCmd.new git_cmd, :tag => "git", :show_out => true src_dir = "#{tmp}/src" FileUtils.mkdir_p src_dir checkout branch, src_dir, "#{tmp}/git" unless File.exists? "#{src_dir}/debian/control" log :err, "The debian packaging files not found in the repository" raise "Adding a package from #{git_addr} failed" end src_name = nil File.open "#{tmp}/src/debian/control", "r" do |f| f.each_line do |line| match = line.match(/^Source: (.+)$/) if match src_name = match.captures[0] break end end end unless src_name log :err, "Couldn't identify the source package" raise "Adding a package from #{git_addr} failed" end unless src_name == @name log :err, "The name of the package in the repo has changed" raise "Adding a package from #{git_addr} failed" end src_dir = "#{@repo.location}/packages/#{@name}/source" FileUtils.rm_rf src_dir FileUtils.mv "#{tmp}/git", "#{src_dir}" end @default_branch = branch end
set_configuration(config)
click to toggle source
# File lib/dr/gitpackage.rb, line 133 def set_configuration(config) # TODO: Some validation needed md_file = "#{@repo.location}/packages/#{@name}/metadata" File.open(md_file, "w") do |f| YAML.dump Utils::stringify_symbols(config), f end end
tag_release(tag_name, revision, options={})
click to toggle source
# File lib/dr/gitpackage.rb, line 305 def tag_release(tag_name, revision, options={}) url = get_repo_url log :info, "Tagging #{@name.style "pkg-name"} package for " + "#{tag_name.fg "yellow"} release" gh_repo = case url when /git\@github.com\:/i then url.split(":")[1].gsub(/\.git$/, "").strip when /github.com\//i then url.split("/")[-2..-1].join("/").gsub(/\.git$/, "").strip else nil end if gh_repo == nil git_cmd = "git --git-dir #{@git_dir} tag #{tag}" git = ShellCmd.new git_cmd, :tag => "git", :show_out => false, :raise_on_error => false if git.status == 128 log :warn, "Tag #{tag_name.fg "yellow"} already exists." return end git_cmd = "git --git-dir #{@git_dir} push origin --tags" git = ShellCmd.new git_cmd, :show_out => false return end title = options["title"] || "Kano OS #{tag_name}" summary = options["summary"] || "https://github.com/KanoComputing/peldins/wiki/Changelog-#{tag_name}" token = ENV["GITHUB_API_TOKEN"] client = Octokit::Client.new :access_token => token releases = client.releases gh_repo ri = releases.index { |r| r[:tag_name] == tag_name } if ri == nil client.create_release gh_repo, tag_name, :target_commitish => revision, :name => title, :body => summary else log :warn, "The #{tag_name.fg "yellow"} release exists already for #{@name.style "pkg-name"}." end end
Private Instance Methods
checkout(branch, dir, override_git_dir=@git_dir)
click to toggle source
# File lib/dr/gitpackage.rb, line 433 def checkout(branch, dir, override_git_dir=@git_dir) log :info, "Extracting the sources" git_cmd ="git --git-dir #{override_git_dir} --bare archive " + "--format tar #{branch} | tar x -C #{dir}" ShellCmd.new git_cmd, :tag => "git", :show_out => true end
get_architectures(control_file)
click to toggle source
# File lib/dr/gitpackage.rb, line 403 def get_architectures(control_file) arches = [] File.open control_file, "r" do |f| f.each_line do |l| m = l.match(/^Architecture: (.+)/) arches += m.captures[0].chomp.split(" ") if m end end arches.uniq end
get_current_branch()
click to toggle source
# File lib/dr/gitpackage.rb, line 415 def get_current_branch git_cmd = ShellCmd.new "git --git-dir #{@git_dir} --bare branch", { :tag => "git" } git_cmd.out.chomp.lines.grep(/^\*/)[0][2..-1].chomp end
get_repo_url()
click to toggle source
# File lib/dr/gitpackage.rb, line 373 def get_repo_url git_cmd = "git --git-dir #{@git_dir} config --get remote.origin.url" git = ShellCmd.new git_cmd, :tag => "git" git.out.strip end
get_rev(branch)
click to toggle source
# File lib/dr/gitpackage.rb, line 422 def get_rev(branch) git_cmd = "git --git-dir #{@git_dir} --bare rev-parse #{branch} 2>/dev/null" git = ShellCmd.new git_cmd, :tag => "git", :expect => [0, 128] if git.status.exitstatus == 0 git.out.chomp else nil end end
get_subpackage_names(control_file)
click to toggle source
# File lib/dr/gitpackage.rb, line 390 def get_subpackage_names(control_file) packages = [] File.open control_file, "r" do |f| f.each_line do |l| if /^Package: / =~ l packages.push l.split(" ")[1] end end end packages end
get_version(changelog_file)
click to toggle source
# File lib/dr/gitpackage.rb, line 379 def get_version(changelog_file) File.open changelog_file, "r" do |f| f.each_line do |l| version = l.match /^#{@name} \(([^\)]+)\) .+;/ return version.captures[0] if version end end nil end
update_from_origin(branch)
click to toggle source
# File lib/dr/gitpackage.rb, line 355 def update_from_origin(branch) log :info, "Pulling changes from origin" original_rev = get_rev branch begin git_cmd = "git --git-dir #{@git_dir} --bare fetch origin" ShellCmd.new git_cmd, :tag => "git", :show_out => true rescue Exception => e log :err, "Unable to pull from origin" raise e end current_rev = get_rev branch [original_rev, current_rev] end