1  """ 
  2  The B{0install whatchanged} command-line interface. 
  3  """ 
  4   
  5   
  6   
  7   
  8  from __future__ import print_function 
  9   
 10  import os 
 11   
 12  from zeroinstall import _, SafeException 
 13  from zeroinstall.cmd import UsageError 
 14   
 15  syntax = "APP-NAME" 
 16   
 18          parser.add_option("", "--full", help=_("show diff of the XML"), action='store_true') 
  19   
 20 -def handle(config, options, args): 
  21          """@type args: [str]""" 
 22          if len(args) != 1: 
 23                  raise UsageError() 
 24   
 25          name = args[0] 
 26          app = config.app_mgr.lookup_app(name, missing_ok = False) 
 27          history = app.get_history() 
 28   
 29          if not history: 
 30                  raise SafeException(_("Invalid application: no selections found! Try '0install destroy {name}'").format(name = name)) 
 31   
 32          import time 
 33   
 34          last_checked = app.get_last_checked() 
 35          if last_checked is not None: 
 36                  print(_("Last checked    : {date}").format(date = time.ctime(last_checked))) 
 37   
 38          last_attempt = app.get_last_check_attempt() 
 39          if last_attempt is not None: 
 40                  print(_("Last attempted update: {date}").format(date = time.ctime(last_attempt))) 
 41   
 42          print(_("Last update     : {date}").format(date = history[0])) 
 43          current_sels = app.get_selections(snapshot_date = history[0]) 
 44   
 45          if len(history) == 1: 
 46                  print(_("No previous history to compare against.")) 
 47                  print(_("Use '0install select {name}' to see the current selections.").format(name = name)) 
 48                  return 
 49   
 50          print(_("Previous update : {date}").format(date = history[1])) 
 51   
 52          def get_selections_path(date): 
 53                  return os.path.join(app.path, 'selections-{date}.xml'.format(date = date)) 
  54   
 55          print() 
 56   
 57          if options.full: 
 58                  import difflib, sys 
 59                  def load_lines(date): 
 60                          with open(get_selections_path(date), 'r') as stream: 
 61                                  return stream.readlines() 
 62                  old_lines = load_lines(history[1]) 
 63                  new_lines = load_lines(history[0]) 
 64                  for line in difflib.unified_diff(old_lines, new_lines, fromfile = history[1], tofile = history[0]): 
 65                          sys.stdout.write(line) 
 66          else: 
 67                  changes = show_changes(app.get_selections(snapshot_date = history[1]).selections, current_sels.selections) 
 68                  if not changes: 
 69                          print(_("No changes to versions (use --full to see all changes).")) 
 70   
 71          print() 
 72          print(_("To run using the previous selections, use:")) 
 73          print("0install run {path}".format(path = get_selections_path(history[1]))) 
 74   
 76          """@type old_selections: dict 
 77          @type new_selections: dict 
 78          @rtype: bool""" 
 79          changes = False 
 80   
 81          for iface, old_sel in old_selections.items(): 
 82                  new_sel = new_selections.get(iface, None) 
 83                  if new_sel is None: 
 84                          print(_("No longer used: %s") % iface) 
 85                          changes = True 
 86                  elif old_sel.version != new_sel.version: 
 87                          print(_("%s: %s -> %s") % (iface, old_sel.version, new_sel.version)) 
 88                          changes = True 
 89   
 90          for iface, new_sel in new_selections.items(): 
 91                  if iface not in old_selections: 
 92                          print(_("%s: new -> %s") % (iface, new_sel.version)) 
 93                          changes = True 
 94           
 95          return changes 
  96   
 98          """@type completion: L{zeroinstall.cmd._Completion} 
 99          @type args: [str] 
100          @type cword: int""" 
101          if len(args) != 1: return 
102          completion.expand_apps() 
 103