head	1.26;
access;
symbols
	RELEASE_2_4_6:1.23
	RELEASE_2_4_5:1.23
	RELEASE_2_4_3:1.19
	RELEASE_2_4_2:1.19
	RELEASE_2_4_1:1.19
	RELEASE_2_4_0:1.19
	RELEASE_2_3_2:1.18
	RELEASE_2_3_1:1.17
	STABLE_2_3:1.17.0.2
	RELEASE_2_3_0:1.16
	RELEASE_2_2_6:1.9.2.6
	RELEASE_2_2_5:1.9.2.3
	RELEASE_2_2_4:1.12
	RELEASE_2_2_3:1.9.2.1
	STABLE_2_2:1.9.0.2
	RELEASE_2_2_2:1.9
	RELEASE_2_2_1:1.9
	RELEASE_2_2_0:1.9
	RELEASE_2_1_3_3:1.1.1.1.2.2
	RELEASE_2_1_7:1.7
	RELEASE_2_1_6:1.4
	RELEASE_2_1_3_2:1.1.1.1.2.1
	RELEASE_2_1_5:1.4
	RELEASE_2_1_3_1:1.1.1.1.0.4
	STABLE:1.1.1.1.0.2
	PKGTOOLS_2_1_4:1.3
	PKGTOOLS_2_1_3:1.1.1.1
	sem:1.1.1;
locks; strict;
comment	@# @;


1.26
date	2011.08.19.00.57.22;	author stas;	state dead;
branches;
next	1.25;

1.25
date	2009.10.26.12.26.10;	author stas;	state Exp;
branches;
next	1.24;

1.24
date	2008.07.17.00.26.38;	author sem;	state Exp;
branches;
next	1.23;

1.23
date	2008.07.01.13.32.07;	author sem;	state Exp;
branches;
next	1.22;

1.22
date	2008.06.30.23.55.15;	author sem;	state Exp;
branches;
next	1.21;

1.21
date	2008.06.30.23.29.02;	author sem;	state Exp;
branches;
next	1.20;

1.20
date	2008.06.17.11.17.02;	author sem;	state Exp;
branches;
next	1.19;

1.19
date	2008.01.26.16.38.15;	author sem;	state Exp;
branches;
next	1.18;

1.18
date	2008.01.08.11.32.27;	author sem;	state Exp;
branches;
next	1.17;

1.17
date	2007.03.02.07.48.18;	author sem;	state Exp;
branches;
next	1.16;

1.16
date	2007.02.26.16.00.25;	author sem;	state Exp;
branches;
next	1.15;

1.15
date	2007.02.26.13.39.02;	author sem;	state Exp;
branches;
next	1.14;

1.14
date	2007.02.26.12.51.33;	author sem;	state Exp;
branches;
next	1.13;

1.13
date	2007.02.26.09.58.13;	author sem;	state Exp;
branches;
next	1.12;

1.12
date	2007.02.23.16.02.59;	author sem;	state Exp;
branches;
next	1.11;

1.11
date	2007.02.22.13.36.34;	author sem;	state Exp;
branches;
next	1.10;

1.10
date	2007.02.16.10.11.40;	author sem;	state Exp;
branches;
next	1.9;

1.9
date	2006.11.06.16.24.02;	author sem;	state Exp;
branches
	1.9.2.1;
next	1.8;

1.8
date	2006.10.15.11.33.56;	author sem;	state Exp;
branches;
next	1.7;

1.7
date	2006.08.14.17.13.30;	author sem;	state Exp;
branches;
next	1.6;

1.6
date	2006.08.13.11.15.21;	author sem;	state Exp;
branches;
next	1.5;

1.5
date	2006.08.12.19.07.50;	author sem;	state Exp;
branches;
next	1.4;

1.4
date	2006.06.30.20.09.28;	author sem;	state Exp;
branches;
next	1.3;

1.3
date	2006.06.17.09.27.21;	author sem;	state Exp;
branches;
next	1.2;

1.2
date	2006.06.14.11.52.38;	author sem;	state Exp;
branches;
next	1.1;

1.1
date	2006.06.13.12.59.00;	author sem;	state Exp;
branches
	1.1.1.1;
next	;

1.9.2.1
date	2007.02.22.14.00.36;	author sem;	state Exp;
branches;
next	1.9.2.2;

1.9.2.2
date	2007.02.24.12.32.10;	author sem;	state Exp;
branches;
next	1.9.2.3;

1.9.2.3
date	2007.02.26.10.00.40;	author sem;	state Exp;
branches;
next	1.9.2.4;

1.9.2.4
date	2007.02.26.12.52.26;	author sem;	state Exp;
branches;
next	1.9.2.5;

1.9.2.5
date	2007.02.26.13.45.07;	author sem;	state Exp;
branches;
next	1.9.2.6;

1.9.2.6
date	2007.02.27.11.30.31;	author sem;	state Exp;
branches;
next	1.9.2.7;

1.9.2.7
date	2007.02.27.17.58.46;	author sem;	state Exp;
branches;
next	1.9.2.8;

1.9.2.8
date	2007.03.02.07.47.33;	author sem;	state Exp;
branches;
next	;

1.1.1.1
date	2006.06.13.12.59.00;	author sem;	state Exp;
branches
	1.1.1.1.2.1
	1.1.1.1.4.1;
next	;

1.1.1.1.2.1
date	2006.07.01.06.31.30;	author sem;	state Exp;
branches;
next	1.1.1.1.2.2;

1.1.1.1.2.2
date	2006.08.23.09.24.27;	author sem;	state Exp;
branches;
next	;

1.1.1.1.4.1
date	2006.06.30.20.27.42;	author sem;	state Exp;
branches;
next	1.1.1.1.4.2;

1.1.1.1.4.2
date	2006.06.30.20.28.35;	author sem;	state Exp;
branches;
next	1.1.1.1.4.3;

1.1.1.1.4.3
date	2006.07.01.06.24.56;	author sem;	state Exp;
branches;
next	;


desc
@@


1.26
log
@- The project data has moved to github (https://github.com/stass/pkgtools).
@
text
@#!/usr/bin/env ruby
# -*- ruby -*-
#
# Copyright (c) 2000-2004 Akinori MUSHA
# Copyright (c) 2005,2006 KOMATSU Shinichiro
# Copyright (c) 2006-2008 Sergey Matveychuk <sem@@FreeBSD.org>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD: projects/pkgtools/bin/pkgdb,v 1.25 2009-10-26 12:26:10 stas Exp $
#

MYREVISION = %w$Rev: 52 $[1]
MYDATE = %w$Date: 2008/07/01 13:32:07 $[1]
MYNAME = File.basename($0)

require "optparse"
require "pkgtools"

COLUMNSIZE = 30
NEXTLINE = "\n%*s" % [5 + COLUMNSIZE, '']

def init_global
  $fix_db = false
  $force = false
  $automatic = false
  $check_lost = false;
  $interactive = false;
  $noconfig = false
  $omit_check = false;
  $quiet = false
  $quieter = false
  #$sanity_check = true
  $temp_dir = ""
  $update_db = false
  $origins = Hash.new
end

def main(argv)
  usage = <<-"EOF"
usage: #{MYNAME} [-hafFfiLOQQquv] [-c pkgname] [-o pkgname] [-s /old_pkgname/new_pkgname/] [file ...]
    EOF

  banner = <<-"EOF"
#{MYNAME} #{Version} (#{MYDATE})

#{usage}
  EOF

  dry_parse = true

  OptionParser.new(banner, COLUMNSIZE) do |opts|
    opts.def_option("-h", "--help", "Show this message") {
      print opts
      exit 0
    }

    opts.def_option("-c", "--collate=PKGNAME", "Show files installed by the given packge#{NEXTLINE}that have been overwritten by other packages") { |pkgname|
      pkgname = $pkgdb.strip(pkgname, true)

      begin
	pkg = PkgInfo.new(pkgname)

	pkg.files.each do |path|
	  owners = $pkgdb.which_m(path) or
	    raise PkgDB::DBError, "The file #{path} is not properly recorded as installed"

	  i = owners.index(pkgname) or
	    raise PkgDB::DBError, "The file #{path} is not properly recorded as installed by #{pkgname}"

	  if i != owners.size - 1
	    print "#{path}: "
	    print "overwritten by: " if $verbose
	    puts owners[(i + 1)..-1].join(' ')
	  end
	end
      rescue => e
	STDERR.puts e.message
      end unless dry_parse
    }

    opts.def_option("-f", "--force", "Force;#{NEXTLINE}Specified with -u, update database#{NEXTLINE}regardless of timestamps#{NEXTLINE}Specified with -F, fix held packages too") { |v|
      $force = v
    }

    opts.def_option("-F", "--fix", "Fix the package database interactively") { |v|
      $fix_db = v
      $interactive = true if ! $automatic
    }

    opts.def_option("-a", "--auto", "Turn on automatic mode when -F is also specified") { |v|
      $automatic = v
      $interactive = false if $fix_db
    }

    opts.def_option("--autofix", "Shorthand of --auto --fix (-aF)") {
      $automatic = $fix_db = true
    }

    opts.def_option("-i", "--interactive",
		    "Turn on interactive mode") { |v|
      $interactive = v
    }

    opts.def_option("-L", "--fix-lost", "Check and restore lost dependencies#{NEXTLINE}against the ports tree") { |v|
      $check_lost = v
    }

    opts.def_option("-o", "--origin=PKGNAME[=ORIGIN]", "Look up or change the origin of the given#{NEXTLINE}package") { |arg|
      pkgname, origin = arg.split('=', 2)
      spkgname = $pkgdb.strip(pkgname, true)
      unless dry_parse
	if spkgname
	  print spkgname, ": " if $verbose
	  print $pkgdb.origin(spkgname) || '?'

	  if origin
	    print " -> #{origin}\n"

	    modify_origin(spkgname, origin)
	  else
	    print "\n"
	  end
	else
	  print pkgname, ": " if $verbose
	  puts '?'
	end
      end
    }

    opts.def_option("-O", "--omit-check", "Specified with -F, turn off checks#{NEXTLINE}dependencies against the ports tree. Useful#{NEXTLINE}if you need a speed-up") { |v|
      $omit_check = v
    }

    opts.def_option("-Q", "--quiet", "Do not write anything to stdout;#{NEXTLINE}Specified twice, stderr neither") {
      if !$quiet
	STDOUT.reopen(open('/dev/null', 'w')) unless dry_parse
	$quiet = true
      elsif !$quieter
	STDERR.reopen(open('/dev/null', 'w')) unless dry_parse
	$quieter = true
      end
    }

    opts.def_option("-q", "--noconfig", "Do not read pkgtools.conf") { |v|
      $noconfig = v
    }

    opts.def_option("-s", "--substitute=/OLD/NEW/", "Substitute all the dependencies recorded#{NEXTLINE}as OLD with NEW") { |expr|
      if expr.empty?
	warning_message "Illegal expression: " + expr
	print opts
	exit 64
      end

      break if dry_parse

      sep = expr.slice!(0,1)

      oldpkgname, newpkgname = expr.split(sep)

      if $verbose
	progress_message "Replacing dependencies: #{oldpkgname} -> #{newpkgname}"
      end

      if newpkgname.nil? || newpkgname.empty? ||
	  oldpkgname.nil? || oldpkgname.empty?
	raise OptionParser::ParseError, "requires non-empty pkgnames"
      end

      update_pkgdep(oldpkgname, newpkgname)

      automatic = $automatic
      $automatic = true

      fix_db_init()
      fix_db_phase2()

      $automatic = automatic
    }

    opts.def_option("-u", "--update", "Update the package database") { |v|
      $update_db = v
    }

    opts.def_option("-v", "--verbose", "Be verbose") { |v|
      $verbose = v
    }

    opts.def_tail_option '
Environment Variables [default]:
    PKGTOOLS_CONF            configuration file [$PREFIX/etc/pkgtools.conf]
    PKG_DBDIR                packages DB directory [/var/db/pkg]
    PORTSDIR                 ports directory [/usr/ports]
    PORTS_DBDIR              ports db directory [$PORTSDIR]
    PORTS_INDEX              ports index file [$PORTSDIR/INDEX]'

    if argv.empty?
      print opts
      return 0
    end

    begin
      init_global
      init_pkgtools_global

      dry_parse = false

      rest = opts.order(*argv)

      unless $noconfig
	init_global
	load_config
      else
	argv = rest
      end

      opts.order!(argv)

      if $update_db
	progress_message "Updating the pkgdb"

	$pkgdb.update_db($force)
	$pkgdb.open_db	# let it check the DB version
      end

      check_lost_deps() if $check_lost

      fix_db() if $fix_db

      list = []
      
      opts.order(*argv) do |arg|
	if arg[0,1] == '/' || File.exist?(arg)
	  path = arg
	else
	  path = `which #{arg}`.chomp

	  if not File.exist?(path)
	    STDERR.puts "#{arg}: not found"
	    next
	  end
	end

	print "#{path}: " if $verbose

	if owners = $pkgdb.which_m(path)
	  puts owners.join(' ')
	else
	  puts '?'
	end
      end
    rescue OptionParser::ParseError => e
      STDERR.puts "#{MYNAME}: #{e}", usage
      exit 64
    rescue => e
      STDERR.puts e.message
      exit 1
    end
  end

  0
end

def get_real_run_deps(pkgname)
  unless $origins.has_key?(pkgname)
    origin = PkgInfo::new(pkgname).origin
    make_env = config_make_env(origin, pkgname)
    make_args = config_make_args(origin, pkgname)

    make_env.unshift("env") if !make_env.empty?

    puts "Disclose depends for #{pkgname}" if $verbose

    $origins[pkgname] = Hash.new
    `cd #{$portsdb.portdir(origin)} && #{shelljoin(*make_env)} make #{shelljoin(*make_args)} package-depends-list`.map { |line|
      a = line.chomp.split(/ /)
      $origins[pkgname].store(a[0], a[2])
    }.compact
  end
  $origins[pkgname]
end

def check_lost_deps()
  fix_db_init()
  stty_sane if $interactive

  puts "Look for lost dependencies:"

  $pkgnames.each do |pkgname|
    # Ignore bsdpan- pseudo ports
    if /^bsdpan-/ =~ pkgname
      puts "#{pkgname}: ignored"
      next 
    end
    deps = $pkgdb.pkgdep(pkgname, true) or return
    real_deps = get_real_run_deps(pkgname)

    print "#{pkgname}: "

    lost = real_deps.values - deps.values
    # Remove dependencies which exist in ALT_PKGDEP
    lost.delete_if { |origin| alt_dep('', origin) }

    if ! lost.empty?
      puts "found"
      lost.each do |origin|
	puts "  #{origin}"
      end
      if $interactive
	next if not prompt_yesno("Fix?", true)
      end
      dep = ""
      lost.each do |origin|
	real_deps.each do |d,o|
	  if o == origin
	    dep = d
	    break
	  end
	end
	modify_pkgdep(pkgname, dep, :add, origin)
      end
      puts "-> Fixed."
    else
      puts "ok"
    end
  end
end

def fix_db
  progress_message "Checking the package registry database"

  if ! File.owned?($pkgdb_dir) && Process.uid > 0
    if $force
      warning_message "You do not own #{$pkgdb_dir}. (proceeding anyway)"
    else
      warning_message "You do not own #{$pkgdb_dir}. (use -f to force or run as root)"
      exit 1
    end
  end

  stty_sane if $interactive

  fix_db_init()
  fix_db_phase1()
  fix_db_phase2()

  $pkgdb.unmark_fixme
end

def fix_db_init()
  $pkgnames = $pkgdb.installed_pkgs

  $req_hash = {}	# a hash of pkgname => { dependent1 => true , ... } pairs
  $fix_hash = {}	# a hash of pkgname => ans pairs
  $all_list = []	# an array of pkgnames, with which a user answered "all"
end

def fix_db_phase1()
  # fix missing or stale origins
  org_hash = {}		# a hash of origin => [pkg1, pkg2, ...] pairs

  deleted = []

  $pkgnames.each do |pkgname|
    puts "Checking the origin of #{pkgname}" if $verbose

    pkg = PkgInfo.new(pkgname)

    case origin = fix_origin(pkg)
    when nil
      deleted << pkgname
    when false
      # skipped
    else
      if org_hash.key?(origin)
	org_hash[origin] << pkg
      else
	org_hash[origin] = [pkg]
      end
    end
  end

  $pkgnames -= deleted

  unless $automatic
    # fix origin duplicates
    puts "Checking for origin duplicates" if $verbose

    fix_duplicates(org_hash).each do |pkg|
      $pkgnames.delete(pkg.fullname)
    end
  end

  $pkgnames.each do |pkgname|
    puts "Checking #{pkgname}" if $verbose

    # check and fix dependencies
    fix_dependencies(pkgname)
  end
end

def fix_db_phase2()
  # reconstruct all the +REQUIRED_BY files
  puts "Regenerating +REQUIRED_BY files" if $verbose

  tsort = TSort.new
  indep_pkgnames = []

  $pkgnames.each do |pkgname|
    req_file = $pkgdb.pkg_required_by(pkgname)

    if $req_hash.key?(pkgname)
      req_by = $req_hash[pkgname].keys

      req_by.each { |req|
	tsort.add(req, pkgname)
      }

      File.open(req_file, "w") do |f|
	f.puts(*req_by.sort)
      end
    else
      indep_pkgnames << pkgname
      File.unlink(req_file) if File.exist?(req_file)
    end
  end

  # unlink cyclic dependencies
  puts "Checking for cyclic dependencies" if $verbose

  fix_cycles(tsort)
end

def fix_origin(pkg)
  pkgname = pkg.fullname
  origin = pkg.origin

  if origin
    if $portsdb.exist?(origin, true)
      return origin
    end

    puts "Stale origin: '#{origin}': perhaps moved or obsoleted."
  else
    puts "Missing origin: #{pkgname}"
  end

  special_guess = nil

  if !origin && /^bsdpan-(.*)/ =~ pkg.name and
      ports = $portsdb.glob("p5-#{$1}") and !ports.empty?
    special_guess = ports.first.origin
  end

  if origin and trace = $portsdb.moved.trace(origin)
    trace_element = trace.shift

    printf "-> The port '%s' was %s on %s because:\n\t\"%s\"\n",
      origin,
      trace_element.to ? "moved to '#{trace_element.to}'" : "removed",
      trace_element.date,
      trace_element.why

    trace.each do |trace_element|
      printf "  then %s on %s because:\n\t\"%s\"\n",
	trace_element.to ? "to '#{trace_element.to}'" : "removed",
	trace_element.date,
	trace_element.why
    end

    special_guess = trace_element.to || :delete
  end

  if special_guess
    origin = special_guess
  else
    if config_held?(pkg) && !$force
      puts "-> Ignored. (the package is held; specify -f to force)"
      return false
    end

    if prompt_yesno("Skip this for now?", true)
      if !$automatic || $verbose
	puts "To skip it without asking in future, please list it in HOLD_PKGS."
      end

      return false
    end

    if origin && prompt_yesno("Browse CVSweb for the port's history?", false)
      Dir.chdir($ports_dir) {
	xsystem(PkgDB::command(:portcvsweb), File.join(origin, "Makefile"))
      }
    end

    guess = guess_origin(pkg)

    confirm_port(guess) and origin = guess
  end

  origin ||= input_port('New origin?')

  case origin
  when :abort
    puts "Abort."
    exit
  when :skip
    puts "Skipped."
    return false
  when :delete
    if $automatic
      puts "Skipped. (running in non-interactive mode; specify -i to ask)"    
      return false
    end

    if pkg.required?
      puts "-> Hint:  #{pkgname} is required by the following package(s):"

      pkg.required_by.each do |req|
	puts "\t#{req}"
      end
    else
      puts "-> Hint: #{pkgname} is not required by any other package"
    end

    puts "-> Hint: checking for overwritten files..."

    possible_successors = []

    pkg.files.each do |path|
      owners = $pkgdb.which_m(path) or
	raise PkgDB::DBError, "#{path} is not properly recorded as installed - please run pkgdb -fu"

      i = owners.index(pkgname) or
	raise PkgDB::DBError, "#{path} is not properly recorded as installed by #{pkgname} - please run pkgdb -fu"

      if i != owners.size - 1
	overwriters = owners[(i + 1)..-1]

	puts "\t#{path}: overwritten by: #{overwriters.join(' ')}"	#

	possible_successors |= overwriters
      end
    end

    if possible_successors.empty?
      puts " -> No files installed by #{pkgname} have been overwritten by other packages."
    else
      puts " -> The package may have been succeeded by some of the following package(s):"
      possible_successors.each do |s|
	puts "\t#{s}"
      end

      if prompt_yesno("Unregister #{pkgname} keeping the installed files intact?", false)
	puts "--> Unregistering #{pkgname}"

	if xsystem('/bin/rm', '-rf', pkg.pkgdir)
	  $pkgdb.update_db

	  puts "--> Done."
	  return nil
	else
	  puts "--> Failed."
	  return false
	end
      end
    end

    if prompt_yesno("Deinstall #{pkgname} ?", false)
      # pkg_deinstall will update the pkgdb
      $pkgdb.close_db

      if xsystem(PkgDB::command(:pkg_deinstall), pkgname)
	puts "--> Done."
	return nil
      else
	puts "--> Failed."
	return false
      end
    end
  else
    begin
      modify_origin(pkgname, origin)

      puts "Fixed. (-> #{origin})"
    rescue => e
      puts e.message
    end
  end

  origin
end

def guess_origin(pkg)
  pkgname = pkg.fullname

  print "Guessing... "
  STDOUT.flush

  guess = $portsdb.glob(pkg.name).max { |a, b|
    matchlen(pkgname, a.pkgname.to_s) <=> matchlen(pkgname, b.pkgname.to_s)
  }

  if guess
    puts ''

    return guess.origin
  else
    puts "no idea."
  end

  nil
rescue => e
  puts e.message

  nil
end

def fix_dependencies(pkgname)
  deps = $pkgdb.pkgdep(pkgname, true) or return

  deps.each do |dep, origin|
    unless $pkgnames.include?(dep)
      puts "Stale dependency: #{pkgname} -> #{dep} (#{origin}):"
      if !$omit_check && !get_real_run_deps(pkgname).values.include?(origin)
        # Ignore dependencies which exist in ALG_PKGDEP
	unless alt_dep(dep, origin)
	  puts "-> Deleted. (irrelevant)"
	  modify_pkgdep(pkgname, dep, :delete)
	  next
	end
      end

      if config_held?(pkgname) && !$force
	puts "-> Ignored. (the package is held; specify -f to force)"
	next
      end

      fix = $fix_hash[dep]
      fix_score = nil

      if fix.nil?
	fix, fix_score = guess_dep(dep, origin)
      end

      fix = query_dep_fix(dep, fix, fix_score)

      next if fix == :skip

      if fix == :install
	xsystem(PkgDB::command(:portinstall), origin)
	fix = dep
      end

      begin
	modify_pkgdep(pkgname, dep, fix)

	case fix
	when :delete
	  puts "Deleted."
	else
	  puts "Fixed. (-> #{fix})"
	end

	$fix_hash[dep] = fix unless fix_score == 100
	dep = fix
      rescue => e
	puts e.message
      end
    end

    if fix != :delete
      ($req_hash[dep] ||= {})[pkgname] = true
    end
  end
end

def tracing_deorigin(origin)
  total = $pkgdb.deorigin(origin) || []

  if trace = $portsdb.moved.trace(origin)
    trace.each do |trace_element|
      pkgnames = $pkgdb.deorigin(trace_element.to) and total |= pkgnames
    end
  end

  if total.empty?
    nil
  else
    total
  end
end

def guess_dep(dep, origin)
  if origin
    pkgnames = tracing_deorigin(origin) || alt_dep(dep, origin) || $pkgnames
  else
    pkgnames = alt_dep(dep) || $pkgnames
  end

  if pkgnames.size == 1
    return pkgnames.first, 100
  end

  pkg = PkgInfo.new(dep)
  pkgname = pkg.fullname

  prefixes = PortsDB::LANGUAGE_SPECIFIC_CATEGORIES.values
  prefix_re = prefixes.join('|')
  pkgname_re = /^(#{prefix_re})?(.+?)((?:\+[^+\-]+)+)?(-[^\-]+)$/

  pkg_prefix, pkg_base, pkg_suffix, pkg_version =
    pkgname_re.match(pkgname)[1..-1]

  calc_score = proc { |name|
    score = 0

    name_prefix, name_base, name_suffix, name_version =
      pkgname_re.match(name)[1..-1]

    if name_prefix != pkg_prefix
      score -= 1
    elsif pkg_prefix
      score += 5
    end

    if name_suffix != pkg_suffix
      score -= 1

      if name_suffix && pkg_suffix
	n = [pkg_suffix.size, name_suffix.size].max

	score += 20 * matchlen(name_suffix, pkg_suffix) / n
      end
    elsif pkg_suffix
      score += 20
    end

    if name_base == pkg_base
      score += 50

      score += 5 * matchlen(name_version, pkg_version)
    else
      n = matchlen(name_base, pkg_base)

      if n >= 3
	score += 5 * n
      else
	score = 0
      end
    end

    if score < 0
      score = 0
    end

    score
  }

  full = calc_score.call(pkgname)

  score, name = pkgnames.map { |name|
    score = calc_score.call(name) * 100 / full

    [score, name]
  }.max

  if score.nonzero?
    return name, score
  else
    return nil, nil
  end
rescue => e
  puts e.message

  return nil, nil
end

def query_dep_fix(dep, fix, fix_score)
  if fix
    if fix_score && fix_score >= 100
      return fix
    end

    if $automatic
      puts "Skipped. (running in non-interactive mode; specify -i to ask)"    
      return :skip
    end

    skip = (fix == :skip)

    if $all_list.include?(dep)
      if skip
	puts "Skipped."
	return :skip
      else
	return fix
      end
    end

    default_ans = true

    case fix
    when :skip
      prompt = "Skip this?"
    when :delete
      prompt = "Delete this?"
    else
      if fix_score
	prompt = "#{fix} (score:#{fix_score}%) ?"
	default_ans = fix_score >= 80
      else
	prompt = "#{fix} ?"
      end
    end

    ans = prompt_yesnoall(prompt, default_ans)

    if ans == :all
      $all_list << dep
    end

    if ans
      if skip
	return :skip
      else
	return fix
      end
    end
  else
    if $automatic
      puts "Skipped. (running in non-interactive mode; specify -i to ask)"    
      return :skip
    end
  end

  install_stale = prompt_yesnoall('Install stale dependency?', true)
  if install_stale
    return :install
  end

  fix = input_pkg('New dependency?', true)

  case fix
  when :abort
    puts "Abort."
    exit
  when :skip
    puts "Skipped."
    $fix_hash[dep] = :skip
    return :skip
  when :skip_all
    $fix_hash[dep] = :skip
    $all_list << dep
    return :skip
  when :delete_all
    $all_list << dep
    return :delete
  end

  return fix
end

def fix_cycles(tsort)
  skip_all = false

  tsort.tsort! do |cycle|
    puts "Cyclic dependencies: #{cycle.join(' -> ')} -> (#{cycle[0]})"

    if $automatic
      puts "Skipped. (running in non-interactive mode; specify -i to ask)"    
      next
    end

    i = nil

    loop do
      ans = skip_all || \
	cycle.size == 1 ? cycle[0] : input_pkg('Unlink which dependency?', false, cycle)

      case ans
      when :abort
	puts "Abort."
	exit
      else
	i = cycle.index(ans)

	if cycle[i + 1].nil?
	  a, b = cycle.last, cycle.first
	else
	  a, b = cycle[i], cycle[i + 1]
	end

	if prompt_yesno("Unlink #{a} -> #{b} ?", true)
	  file = $pkgdb.pkg_contents(a)

	  next if not File.exist?(file)
	  File.open(file, "r+") do |f|
	    lines = []
	    pkgdeps = { b => true }
	    deporigin = nil

	    f.each do |line|
	      case line
	      when /^@@pkgdep\s+(\S+)/
		deporigin = :keep

		pkgdep = $1

		if pkgdeps.key?(pkgdep)	# remove duplicates
		  deporigin = :delete
		  next
		end

		pkgdeps[pkgdep] = true

		lines << line
	      when /^@@comment\s+DEPORIGIN:(\S+)/
		case deporigin
		when :keep
		  lines << line
		else # :delete, nil
		  # no output
		end
		
		deporigin = nil
	      else
		lines << line

		deporigin = nil
	      end
	    end

	    f.rewind
	    f.print(*lines)
	    f.truncate f.pos
	  end

	  file = $pkgdb.pkg_required_by(b)

	  filter_file(shelljoin('grep', '-v', "^#{Regexp.quote(a)}$"), file)

	  puts 'Done.'
	  break
	end
      end
    end

    i
  end
end

def fix_duplicates(org_hash)
  all_deleted = []

  $pkgdb.close_db

  org_hash.each do |origin, pkgs|
    next if pkgs.size < 2

    pkgs.sort!
    n = pkgs.size

    puts "Duplicated origin: #{origin} - " + pkgs.collect { |pkg| pkg.fullname }.join(' ')

    prompt_yesno("Unregister any of them?", false) or next

    deleted = []

    pkgs.each do |pkg|
      pkgname = pkg.fullname

      if n == 1
	# automatically keep one package record at least
	puts "  -> #{pkgname} is kept."
	break
      end

      prompt_yesno("  Unregister #{pkgname} keeping the installed files intact?", false) or next

      deleted << pkg

      n -= 1
    end

    unless deleted.empty?
      biggest = (pkgs - deleted)[-1]

      deleted.each do |pkg|
	oldpkgdir = pkg.pkgdir
	oldpkgname = pkg.fullname

	newpkgdir = biggest.pkgdir
	newpkgname = biggest.fullname

	contents = $pkgdb.pkg_contents(oldpkgname)
	backup = $pkgdb.pkg_contents(newpkgname) + '.' + oldpkgname

	puts "  --> Saving the #{oldpkgname}'s +CONTENTS file as #{backup}"
	xsystem('/bin/cp', '-pf', contents, backup) or next

	puts "  --> Unregistering #{oldpkgname}"
	xsystem('/bin/rm', '-rf', oldpkgdir) or next

	puts "  --> Done."

	all_deleted << pkg
      end
    end
  end

  $pkgdb.update_db unless all_deleted.empty?

  all_deleted
end

def input_pkg(message = 'Which package?', fullspec = false, pkgnames = $pkgnames)
  flags = OPTIONS_HISTORY |
    (fullspec ? OPTIONS_SKIP | OPTIONS_DELETE | OPTIONS_ALL : OPTIONS_NONE)

  choose_from_options(message, pkgnames, flags)
end

def input_port(message = 'Which port?')
  loop do
    input = input_file(message + ' (? to help): ', $ports_dir, true)

    if input.nil?
      print "\n"
      return :delete
    end

    input.strip!

    case input
    when '.'
      return :abort
    when '?'
      print <<-EOF
[Enter] to skip, [Ctrl]+[D] to unregister or deinstall,
[.][Enter] to abort, [Tab] to complete
      EOF
      next
    when ''
      if prompt_yesno("Skip this?", true)
	return :skip
      end

      next
    else
      input = $portsdb.strip(input)

      confirm_port(input) and return input
    end
  end

  # not reached
end

def confirm_port(origin)
  if origin
    pkgname = $portsdb.exist?(origin)

    if !pkgname
      return prompt_yesno("#{origin}: Not found.  Force it?", false)
    end

    return prompt_yesno("#{origin} (#{pkgname}): Change the origin to this?", true)
  end

  puts "Not in due form <category/portname>: #{origin}"

  false
end

if $0 == __FILE__
  set_signal_handlers

  exit(main(ARGV) || 1)
end
@


1.25
log
@- Fix support for origins in ALT_PKGDEP.
- Do not skip package processing if its name matches ALT_PKGDEP contents.

PR:		ports/138356
Submitted by:	Dan Lukes <dan@@obluda.cz>
@
text
@d31 1
a31 1
# $FreeBSD$
@


1.24
log
@Adapt to ruby 1.9
@
text
@d31 2
d649 5
a653 5
	next if alt_dep(dep)

	puts "-> Deleted. (irrelevant)"
	modify_pkgdep(pkgname, dep, :delete)
	next
@


1.23
log
@Ignore errors if +CONTENTS file was removed (with a port) when we updating.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2008/06/30 23:55:15 $[1]
d77 1
a77 2
    opts.def_option("-c", "--collate=PKGNAME", "Show files installed by the given packge#{NEXTLINE}that have been overwritten by other packages") {
      |pkgname|
d101 2
a102 2
    opts.def_option("-f", "--force", "Force;#{NEXTLINE}Specified with -u, update database#{NEXTLINE}regardless of timestamps#{NEXTLINE}Specified with -F, fix held packages too") {
      |$force|
d105 2
a106 2
    opts.def_option("-F", "--fix", "Fix the package database interactively") {
      |$fix_db|
d110 2
a111 2
    opts.def_option("-a", "--auto", "Turn on automatic mode when -F is also specified") {
      |$automatic|
d120 2
a121 2
		    "Turn on interactive mode") {
      |$interactive|
d124 2
a125 2
    opts.def_option("-L", "--fix-lost", "Check and restore lost dependencies#{NEXTLINE}against the ports tree") {
      |$check_lost|
d128 1
a128 2
    opts.def_option("-o", "--origin=PKGNAME[=ORIGIN]", "Look up or change the origin of the given#{NEXTLINE}package") {
      |arg|
d150 2
a151 2
    opts.def_option("-O", "--omit-check", "Specified with -F, turn off checks#{NEXTLINE}dependencies against the ports tree. Useful#{NEXTLINE}if you need a speed-up") {
      |$omit_check|
d164 2
a165 2
    opts.def_option("-q", "--noconfig", "Do not read pkgtools.conf") {
      |$noconfig|
d168 1
a168 2
    opts.def_option("-s", "--substitute=/OLD/NEW/", "Substitute all the dependencies recorded#{NEXTLINE}as OLD with NEW") {
      |expr|
d201 2
a202 2
    opts.def_option("-u", "--update", "Update the package database") {
      |$update_db|
d205 2
a206 2
    opts.def_option("-v", "--verbose", "Be verbose") {
      |$verbose|
@


1.22
log
@Fix `if not` with `if !`
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2008/06/30 23:29:02 $[1]
d920 1
@


1.21
log
@Do not show 'You do not own pkgdir' for root.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2008/06/17 11:17:02 $[1]
d355 1
a355 1
  if not File.owned?($pkgdb_dir) && Process.uid > 0
@


1.20
log
@Fix a type in a comment: ALG_PKGDEP -> ALT_PKGDEP
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2008/01/26 16:38:15 $[1]
d355 1
a355 1
  if not File.owned?($pkgdb_dir)
@


1.19
log
@Remove empty +REQUIRED_BY file.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2008/01/08 11:32:27 $[1]
d324 1
a324 1
    # Remove dependencies which exist in ALG_PKGDEP
@


1.18
log
@New year in COPYRIGHTS
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/03/02 07:48:18 $[1]
d447 1
@


1.17
log
@- Ignore bsdpan- pseudo ports when fixing dependencies.
@
text
@d6 1
a6 1
# Copyright (c) 2006,2007 Sergey Matveychuk <sem@@FreeBSD.org>
d33 1
a33 1
MYDATE = %w$Date: 2007/02/26 16:00:25 $[1]
@


1.16
log
@- Move alt_dep() from pkgdb to pkgtools.rb
- Use alt_dep() in portupgrade to test if dependency installed
- Add numbers (divicible by 100) in progress bar for pkgdb
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/26 13:39:02 $[1]
d313 5
@


1.15
log
@Don't check file existing when pkg_which(1).
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/26 12:51:33 $[1]
a694 42
def alt_dep(dep, origin = nil)
  hash = config_value(:ALT_PKGDEP) or return nil

  hash.each do |pat, alt|
    begin
      pat = parse_pattern(pat)
    rescue RegexpError => e
      warning_message e.message.capitalize
      next
    end

    # pattern allowed both in origin and pkgname
    if pat.index('/')
      next if !origin || !File.fnmatch?(pat, origin)
    elsif !File.fnmatch?(pat, dep)
      next
    end

    case alt
    when :delete, :skip
      return [alt]
    else
      begin
	alt = parse_pattern(alt)
      rescue RegexpError => e
	warning_message e.message.capitalize
	next
      end

      pkgnames = $pkgdb.glob(alt, false)

      if pkgnames.empty?
	return nil
      else
	return pkgnames
      end
    end
  end

  nil
end

@


1.14
log
@Wrong -Oo option parsing
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/26 09:58:13 $[1]
d256 1
a256 1
	if File.exist?(arg)
@


1.13
log
@When -F or -L, pass depends if they are exist in ALT_PKGDEP.
It fixes issues with ghostscript-afpl vs. ghostscript-gnu, apache, etc.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/23 16:02:59 $[1]
d153 1
a153 1
      $omit_check = false
@


1.12
log
@* Fix a bug when some dependencies could lost.

* -L to allow users fix dependencies those was lost with the bug
  mentioned above.

* -i turns interactive mode on.

* Add -O option to turn off dependencies check instead of -d option,
  that turned it on.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/22 13:36:34 $[1]
d319 3
d642 4
a645 1
      if !$omit_check && !get_real_run_deps(pkgname).include?(origin)
@


1.11
log
@Update COPYRIGHTS
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/16 10:11:40 $[1]
d46 2
a47 1
  $check_depends = false;
d49 1
d60 1
a60 1
usage: #{MYNAME} [-hadfFfjQQquv] [-c pkgname] [-o pkgname] [-s /old_pkgname/new_pkgname/] [file ...]
a101 4
    opts.def_option("-d", "--check-depends", "When do fixing the package DB (-F), check#{NEXTLINE}depends against a current ports tree") {
      |$check_depends|
    }

d108 1
d113 1
d120 9
d152 3
a154 3
#    opts.def_option("-O", "--omit-check", "Omit sanity checks for dependencies.") {
#      $sanity_check = false
#    }
d249 3
a251 3
      if $fix_db
	fix_db()
      end
d287 57
d356 1
a356 3
  if $interactive
    stty_sane
  end
a632 15
def get_real_run_deps(pkgname)
  unless $origins.has_key?(pkgname)
    origin = PkgInfo::new(pkgname).origin
    make_env = config_make_env(origin, pkgname)
    make_args = config_make_args(origin, pkgname)

    make_env.unshift("env") if !make_env.empty?

    $origins[pkgname] = `cd #{$portsdb.portdir(origin)} && #{shelljoin(*make_env)} make #{shelljoin(*make_args)} run-depends-list`.map { |line|
      $portsdb::strip(line.chomp, true)
    }.compact
  end
  $origins[pkgname]
end

d639 1
a639 1
      unless $check_depends && get_real_run_deps(pkgname).include?(origin)
@


1.10
log
@Hide smartness of pkgdb -F with option -d. Becouse it makes things slower.
@
text
@d5 2
a6 2
# Copyright (c) 2005, 2006 KOMATSU Shinichiro
# Copyright (c) 2006 Sergey Matveychuk <sem@@FreeBSD.org>
d33 1
a33 1
MYDATE = %w$Date: 2006/11/06 16:24:02 $[1]
@


1.9
log
@Improve pkgdb -F - respect OPTIONS and pkgtools.conf settings.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2006/10/15 11:33:56 $[1]
d46 1
d53 1
d58 1
a58 1
usage: #{MYNAME} [-hafFQQquv] [-c pkgname] [-o pkgname] [-s /old_pkgname/new_pkgname/] [file ...]
d100 4
d570 12
a581 9
  origin = PkgInfo::new(pkgname).origin
  make_env = config_make_env(origin, pkgname)
  make_args = config_make_args(origin, pkgname)

  make_env.unshift("env") if !make_env.empty?

  `cd #{$portsdb.portdir(origin)} && #{shelljoin(*make_env)} make #{shelljoin(*make_args)} run-depends-list`.map { |line|
    $portsdb::strip(line.chomp, true)
  }.compact
d590 1
a590 1
      unless get_real_run_deps(pkgname).include?(origin)
@


1.9.2.1
log
@Merge patches from HEAD
@
text
@d5 2
a6 2
# Copyright (c) 2005,2006 KOMATSU Shinichiro
# Copyright (c) 2006,2007 Sergey Matveychuk <sem@@FreeBSD.org>
d33 1
a33 1
MYDATE = %w$Date: 2007/02/22 13:36:34 $[1]
a45 1
  $check_depends = false;
a51 1
  $origins = Hash.new
d56 1
a56 1
usage: #{MYNAME} [-hadfFfjQQquv] [-c pkgname] [-o pkgname] [-s /old_pkgname/new_pkgname/] [file ...]
a97 4
    opts.def_option("-d", "--check-depends", "When do fixing the package DB (-F), check#{NEXTLINE}depends against a current ports tree") {
      |$check_depends|
    }

d564 9
a572 12
  unless $origins.has_key?(pkgname)
    origin = PkgInfo::new(pkgname).origin
    make_env = config_make_env(origin, pkgname)
    make_args = config_make_args(origin, pkgname)

    make_env.unshift("env") if !make_env.empty?

    $origins[pkgname] = `cd #{$portsdb.portdir(origin)} && #{shelljoin(*make_env)} make #{shelljoin(*make_args)} run-depends-list`.map { |line|
      $portsdb::strip(line.chomp, true)
    }.compact
  end
  $origins[pkgname]
d581 1
a581 1
      unless $check_depends && get_real_run_deps(pkgname).include?(origin)
@


1.9.2.2
log
@Merge from HEAD to 2.2.4 version + new language categories
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/22 14:00:36 $[1]
d46 1
a46 2
  $check_lost = false;
  $interactive = false;
a47 1
  $omit_check = false;
d58 1
a58 1
usage: #{MYNAME} [-hafFfiLOQQquv] [-c pkgname] [-o pkgname] [-s /old_pkgname/new_pkgname/] [file ...]
a109 1
      $interactive = true if ! $automatic
a113 1
      $interactive = false if $fix_db
a119 9
    opts.def_option("-i", "--interactive",
		    "Turn on interactive mode") {
      |$interactive|
    }

    opts.def_option("-L", "--fix-lost", "Check and restore lost dependencies#{NEXTLINE}against the ports tree") {
      |$check_lost|
    }

d143 3
a145 3
    opts.def_option("-O", "--omit-check", "Specified with -F, turn off checks#{NEXTLINE}dependencies against the ports tree. Useful#{NEXTLINE}if you need a speed-up") {
      $omit_check = false
    }
d240 3
a242 3
      check_lost_deps() if $check_lost

      fix_db() if $fix_db
a277 57
def get_real_run_deps(pkgname)
  unless $origins.has_key?(pkgname)
    origin = PkgInfo::new(pkgname).origin
    make_env = config_make_env(origin, pkgname)
    make_args = config_make_args(origin, pkgname)

    make_env.unshift("env") if !make_env.empty?

    puts "Disclose depends for #{pkgname}" if $verbose

    $origins[pkgname] = Hash.new
    `cd #{$portsdb.portdir(origin)} && #{shelljoin(*make_env)} make #{shelljoin(*make_args)} package-depends-list`.map { |line|
      a = line.chomp.split(/ /)
      $origins[pkgname].store(a[0], a[2])
    }.compact
  end
  $origins[pkgname]
end

def check_lost_deps()
  fix_db_init()
  stty_sane if $interactive

  puts "Look for lost dependencies:"

  $pkgnames.each do |pkgname|
    deps = $pkgdb.pkgdep(pkgname, true) or return
    real_deps = get_real_run_deps(pkgname)

    print "#{pkgname}: "

    lost = real_deps.values - deps.values
    if ! lost.empty?
      puts "found"
      lost.each do |origin|
	puts "  #{origin}"
      end
      if $interactive
	next if not prompt_yesno("Fix?", true)
      end
      dep = ""
      lost.each do |origin|
	real_deps.each do |d,o|
	  if o == origin
	    dep = d
	    break
	  end
	end
	modify_pkgdep(pkgname, dep, :add, origin)
      end
      puts "-> Fixed."
    else
      puts "ok"
    end
  end
end

d290 3
a292 1
  stty_sane if $interactive
d569 15
d590 1
a590 1
      if !$omit_check && !get_real_run_deps(pkgname).include?(origin)
@


1.9.2.3
log
@Merge from HEAD: When -F or -L, pass depends if they are exist in ALT_PKGDEP.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/26 09:58:13 $[1]
a322 3
    # Remove dependencies which exist in ALG_PKGDEP
    lost.delete_if { |origin| alt_dep('', origin) }

d643 1
a643 4
      if !$omit_check && !get_real_run_deps(pkgname).values.include?(origin)
        # Ignore dependencies which exist in ALG_PKGDEP
	next if alt_dep(dep)

@


1.9.2.4
log
@Wrong -O option parsing
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/26 10:00:40 $[1]
d157 1
a157 1
      |$omit_check|
@


1.9.2.5
log
@Merge from HEAD: Don't check file existence when pkg_which(1) use
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/26 13:39:02 $[1]
d260 1
a260 1
	if arg[0,1] == '/' || File.exist?(arg)
@


1.9.2.6
log
@Fix a bug when pkgdb -L and -F required in ALT_PKGDEP only origins.
package globs are very helpfull there.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/26 13:45:07 $[1]
a701 4
  if dep == ''
    dep = $pkgdb.deorigin(origin)
  end

@


1.9.2.7
log
@A litttle fix to be on a safe side
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/27 11:30:31 $[1]
d703 1
a703 1
    dep = $pkgdb.deorigin(origin).to_s
@


1.9.2.8
log
@- Ignore bsdpan- pseudo ports when fix dependencies.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2007/02/27 17:58:46 $[1]
a316 5
    # Ignore bsdpan- pseudo ports
    if /^bsdpan-/ =~ pkgname
      puts "#{pkgname}: ignored"
      next 
    end
@


1.8
log
@Change system() call with xsystem() that checks an error code.
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2006/08/14 17:13:30 $[1]
d563 12
d581 5
@


1.7
log
@Fix alt_dep() in pkgdb: if there was not match in a first pattern the function
exited. It should go to a next key instead.

Submitted by:	skv
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2006/08/13 11:15:21 $[1]
d436 1
a436 1
	system(PkgDB::command(:portcvsweb), File.join(origin, "Makefile"))
d501 1
a501 1
	if system('/bin/rm', '-rf', pkg.pkgdir)
d517 1
a517 1
      if system(PkgDB::command(:pkg_deinstall), pkgname)
d587 1
a587 1
	system(PkgDB::command(:portinstall), origin)
d977 1
a977 1
	system('/bin/cp', '-pf', contents, backup) or next
d980 1
a980 1
	system('/bin/rm', '-rf', oldpkgdir) or next
@


1.6
log
@Adjust Copyright notices
@
text
@d33 1
a33 1
MYDATE = %w$Date: 2006/08/12 19:07:50 $[1]
d627 1
a627 1
      return nil if !origin || !File.fnmatch?(pat, origin)
d629 1
a629 1
      return nil
@


1.5
log
@Make pkgdb don't remove +REQUIRED_BY file if it empty.
@
text
@a4 1
# All rights reserved.
d6 2
d33 1
a33 1
MYDATE = %w$Date: 2006/06/30 20:09:28 $[1]
@


1.4
log
@Get back second init_global. It's necessary for doubled options like -DD.
Really it's needed only for portupgrade and portsclean, but be consistent.
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006/06/17 09:27:21 $[1]
a367 2

      File.unlink(req_file) if File.exist?(req_file)
a918 4
	  if File.zero?(file)
	    File.unlink(file)
	  end

@


1.3
log
@- Allow origins in ALT_PKGDEP. This announced in pkgtools.conf
  but did not work really.

Submited by:	skv
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006/06/14 11:52:38 $[1]
d218 1
@


1.2
log
@- Refactoring:
  * Get rid of warnings with ruby --debug
  * Rework ugly init_pkgtools_global call. Now it's more consistent.
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006/06/13 12:59:00 $[1]
d614 1
a614 1
def alt_dep(dep)
d625 17
a641 11
    if File.fnmatch?(pat, dep)
      case alt
      when :delete, :skip
	return [alt]
      else
	begin
	  alt = parse_pattern(alt)
	rescue RegexpError => e
	  warning_message e.message.capitalize
	  next
	end
d643 1
a643 1
	pkgnames = $pkgdb.glob(alt, false)
d645 4
a648 5
	if pkgnames.empty?
	  return nil
	else
	  return pkgnames
	end
d674 1
a674 1
    pkgnames = tracing_deorigin(origin) || alt_dep(dep) || $pkgnames
@


1.1
log
@Initial revision
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006-01-01 15:26:59 +0900 (Sun, 01 Jan 2006) $[1]
d49 1
d211 1
a217 1
	init_global
@


1.1.1.1
log
@Initial import
@
text
@@


1.1.1.1.2.1
log
@MFD: Allow origins in ALT_PKGDEP
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006/06/30 20:28:35 $[1]
d613 1
a613 1
def alt_dep(dep, origin = nil)
d624 11
a634 6
    # pattern allowed both in origin and pkgname
    if pat.index('/')
      return nil if !origin || !File.fnmatch?(pat, origin)
    elsif !File.fnmatch?(pat, dep)
       return nil
    end
d636 1
a636 10
    case alt
    when :delete, :skip
      return [alt]
    else
      begin
	alt = parse_pattern(alt)
      rescue RegexpError => e
	warning_message e.message.capitalize
	next
      end
d638 5
a642 6
      pkgnames = $pkgdb.glob(alt, false)

      if pkgnames.empty?
	return nil
      else
	return pkgnames
d668 1
a668 1
    pkgnames = tracing_deorigin(origin) || alt_dep(dep, origin) || $pkgnames
@


1.1.1.1.2.2
log
@MFD: Fix alt_dep() in pkgdb
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006/08/14 17:13:30 $[1]
d626 1
a626 1
      next if !origin || !File.fnmatch?(pat, origin)
d628 1
a628 1
      next
@


1.1.1.1.4.1
log
@MFD: Allow origins in ALT_PKGDEP
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006/06/13 12:59:00 $[1]
d613 1
a613 1
def alt_dep(dep, origin = nil)
d624 11
a634 6
    # pattern allowed both in origin and pkgname
    if pat.index('/')
      return nil if !origin || !File.fnmatch?(pat, origin)
    elsif !File.fnmatch?(pat, dep)
       return nil
    end
d636 1
a636 10
    case alt
    when :delete, :skip
      return [alt]
    else
      begin
	alt = parse_pattern(alt)
      rescue RegexpError => e
	warning_message e.message.capitalize
	next
      end
d638 5
a642 6
      pkgnames = $pkgdb.glob(alt, false)

      if pkgnames.empty?
	return nil
      else
	return pkgnames
@


1.1.1.1.4.2
log
@Complete last MFD
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006/06/30 20:27:42 $[1]
d673 1
a673 1
    pkgnames = tracing_deorigin(origin) || alt_dep(dep, origin) || $pkgnames
@


1.1.1.1.4.3
log
@Roll back last changes. They was committed in a wrong branch.
@
text
@d32 1
a32 1
MYDATE = %w$Date: 2006/06/13 12:59:00 $[1]
d613 1
a613 1
def alt_dep(dep)
d624 17
a640 11
    if File.fnmatch?(pat, dep)
      case alt
      when :delete, :skip
	return [alt]
      else
	begin
	  alt = parse_pattern(alt)
	rescue RegexpError => e
	  warning_message e.message.capitalize
	  next
	end
d642 1
a642 1
	pkgnames = $pkgdb.glob(alt, false)
d644 4
a647 5
	if pkgnames.empty?
	  return nil
	else
	  return pkgnames
	end
d673 1
a673 1
    pkgnames = tracing_deorigin(origin) || alt_dep(dep) || $pkgnames
@


