zypper:
authorMartin Vidner <mvidner@suse.cz>
Mon, 25 Sep 2006 12:06:09 +0000 (12:06 +0000)
committerMartin Vidner <mvidner@suse.cz>
Mon, 25 Sep 2006 12:06:09 +0000 (12:06 +0000)
 more option parsing
 less verbose by default
 implemented service-delete
 moo!
common with zmart:
 added Settings.verbose, cerr_v, cerr_vv for progress reporting
 more logging in service-add

tools/zmart/zmart-sources.cc
tools/zmart/zmart-sources.h
tools/zmart/zmart.cc
tools/zmart/zmart.h
tools/zmart/zypper.cc

index 9b71bc2..8788cfc 100644 (file)
@@ -141,7 +141,9 @@ std::string timestamp ()
 
 void add_source_by_url( const zypp::Url &url, std::string alias  )
 {
+  cerr_vv << "Constructing SourceManager" << endl;
   SourceManager_Ptr manager = SourceManager::sourceManager();
+  cerr_vv << "Restoring SourceManager" << endl;
   manager->restore ("/", true /*use_cache*/);
 
   list<SourceManager::SourceId> sourceIds;
@@ -154,7 +156,9 @@ void add_source_by_url( const zypp::Url &url, std::string alias  )
    
   // more products?
   // try
+  cerr_vv << "Creating source" << endl;
   Source_Ref source = SourceFactory().createFrom( url, path, alias, cache, is_base );
+  cerr_vv << "Adding source" << endl;
   SourceManager::SourceId sourceId = manager->addSource( source );
 
   //if (enableSource)
@@ -175,5 +179,82 @@ void add_source_by_url( const zypp::Url &url, std::string alias  )
       cout << source.alias() << " (" << source.url() << ")" << endl;
     }
 
+    cerr_vv << "Storing source data" << endl;
     manager->store( "/", true /*metadata_cache*/ );
 }
+
+template<typename T>
+ostream& operator << (ostream& s, const vector<T>& v) {
+  std::copy (v.begin(), v.end(), ostream_iterator<T> (s, ", "));
+  return s;
+}
+
+//! remove a source, identified in any way: alias, url, id
+// may throw:
+void remove_source( const std::string anystring )
+{
+  cerr_vv << "Constructing SourceManager" << endl;
+  SourceManager_Ptr manager = SourceManager::sourceManager();
+  cerr_vv << "Restoring SourceManager" << endl;
+  manager->restore ("/", true /*use_cache*/);
+
+  SourceManager::SourceId sid;
+  zypp::str::strtonum (anystring, sid);
+  if (sid > 0) {
+    cerr_v << "removing source " << sid << endl;
+    try {
+      manager->findSource (sid);
+    }
+    catch (const Exception & ex) {
+      ZYPP_CAUGHT (ex);
+      cerr << str::form ("Source %lu not found", sid) << endl;
+    }
+    manager->removeSource (sid);
+  }
+  else {
+    bool is_url = false;
+    // could it be a URL?
+    cerr_vv << "Registered schemes: " << Url::getRegisteredSchemes () << endl;
+    string::size_type pos = anystring.find (':');
+    if (pos != string::npos) {
+      string scheme (anystring, 0, pos);
+      if (Url::isRegisteredScheme (scheme)) {
+       is_url = true;
+       cerr_vv << "Looks like a URL" << endl;
+
+       Url url;
+       try {
+         url = Url (anystring);
+       }
+       catch ( const Exception & excpt_r ) {
+         ZYPP_CAUGHT( excpt_r );
+         cerr << "URL is invalid: " << excpt_r.asUserString() << endl;
+       }
+       if (url.isValid ()) {
+         try {
+           manager->findSourceByUrl (url);
+         }
+         catch (const Exception & ex) {
+           ZYPP_CAUGHT (ex);
+           cerr << str::form ("Source %s not found", url.asString().c_str()) << endl;
+         }
+         manager->removeSourceByUrl (url);
+       }
+      }
+    }
+
+    if (!is_url) {
+      try {
+       manager->findSource (anystring);
+      }
+      catch (const Exception & ex) {
+       ZYPP_CAUGHT (ex);
+       cerr << str::form ("Source %s not found", anystring.c_str()) << endl;
+      }
+      manager->removeSource (anystring);       // by alias
+    }
+  }
+
+  cerr_vv << "Storing source data" << endl;
+  manager->store( "/", true /*metadata_cache*/ );
+}
index c4901e6..f87bea7 100644 (file)
@@ -15,6 +15,7 @@
 void init_system_sources();
 void include_source_by_url( const zypp::Url &url );
 void add_source_by_url( const zypp::Url &url, std::string alias );
+void remove_source( const std::string anystring );
 void list_system_sources();
 
 #endif
index e3048aa..1d63c38 100644 (file)
@@ -27,6 +27,8 @@ ZYpp::Ptr God;
 RuntimeData gData;
 Settings gSettings;
 
+ostream no_stream(NULL);
+
 RpmCallbacks rpm_callbacks;
 SourceCallbacks source_callbacks;
 MediaCallbacks media_callbacks;
index 4becec0..85fd991 100644 (file)
@@ -1,4 +1,4 @@
-/*---------------------------------------------------------------------\
+/*-----------------------------------------------------------*- c++ -*-\
 |                          ____ _   __ __ ___                          |
 |                         |__  / \ / / . \ . \                         |
 |                           / / \ V /|  _/  _/                         |
@@ -33,6 +33,7 @@ struct Settings
 {
   Settings()
   : previous_token(RANDOM_TOKEN),
+  verbose(0),  
   previous_code(-1),
   disable_system_sources(false),
   disable_system_resolvables(false)
@@ -40,6 +41,7 @@ struct Settings
 
   std::list<zypp::Url> additional_sources;
   std::string previous_token;
+  int verbose;
   int previous_code;
   std::string command;
   bool disable_system_sources;
@@ -59,5 +61,15 @@ struct RuntimeData
   std::vector<std::string> packages_to_install; 
 };
 
+extern RuntimeData gData;
+extern Settings gSettings;
+extern std::ostream no_stream;
+
+#define COND_STREAM(STREAM,LEVEL) ((gSettings.verbose >= LEVEL)? STREAM: no_stream)
+#define cerr_v COND_STREAM(cerr,1)
+#define cout_v COND_STREAM(cout,1)
+#define cerr_vv COND_STREAM(cerr,2)
+#define cout_vv COND_STREAM(cout,2)
+
 #endif
 
index 4e66a6b..6716e59 100644 (file)
@@ -29,16 +29,16 @@ using namespace boost;
 using namespace zypp;
 using namespace zypp::detail;
 
-ZYpp::Ptr God;
+ZYpp::Ptr God = NULL;
 RuntimeData gData;
 Settings gSettings;
-int verbose = 0;
 
-/*
+ostream no_stream(NULL);
+
 RpmCallbacks rpm_callbacks;
 SourceCallbacks source_callbacks;
 MediaCallbacks media_callbacks;
-*/
+
 typedef map<string, list<string> > parsed_opts;
 
 string longopts2optstring (const struct option *longopts) {
@@ -99,6 +99,8 @@ parsed_opts parse_options (int argc, char **argv,
       list<string>& value = result[mapidx];
       if (optarg)
        value.push_back (optarg);
+      else
+       value.push_back ("");
       break;
     }
   }
@@ -106,11 +108,12 @@ parsed_opts parse_options (int argc, char **argv,
 }
 
 static struct option global_options[] = {
-  {"help", no_argument, 0, 'h'},
-  {"verbose", no_argument, 0, 'v'},
-  {"version", no_argument, 0, 'V'},
-  {"req", required_argument, 0, 'r'},
-  {"opt", optional_argument, 0, 'o'},
+  {"help",     no_argument, 0, 'h'},
+  {"verbose",  no_argument, 0, 'v'},
+  {"version",  no_argument, 0, 'V'},
+  {"terse",    no_argument, 0, 't'},
+  {"req",      required_argument, 0, 'r'},
+  {"opt",      optional_argument, 0, 'o'},
   {0, 0, 0, 0}
 };
 
@@ -132,25 +135,38 @@ Url make_url (const string & url_s) {
 
 int main(int argc, char **argv)
 {
+  const char *logfile = getenv("ZYPP_LOGFILE");
+  if (logfile == NULL)
+    logfile = ZYPP_CHECKPATCHES_LOG;
+  zypp::base::LogControl::instance().logfile( logfile );
+  
+  bool help = false;
   parsed_opts gopts = parse_options (argc, argv, global_options);
 
-  if (gopts.count("help")) {
-    cerr << "  Options:\n"
-       "\t--help, -h\t\tHelp\n"
-       "\t--version, -V\t\tOutput the version number\n"
-       "\t--verbose, -v\t\tIncrease verbosity\n"
-       "\t--terse, -t\t\tTerse output for machine consumption\n"
-       ;
-    
-  }
+  // Help is parsed by setting the help flag for a command, which may be empty
+  // $0 -h,--help
+  // $0 command -h,--help
+  // The help command is eaten and transformed to the help option
+  // $0 help
+  // $0 help command
+  if (gopts.count("help"))
+    help = true;
+
+  string help_global_options = "  Options:\n"
+    "\t--help, -h\t\tHelp\n"
+    "\t--version, -V\t\tOutput the version number\n"
+    "\t--verbose, -v\t\tIncrease verbosity\n"
+    "\t--terse, -t\t\tTerse output for machine consumption\n"
+    ;
 
   if (gopts.count("version")) {
     cerr << "zypper 0.1" << endl;
+    return 0;
   }
 
   if (gopts.count("verbose")) {
-    verbose += gopts.count("verbose");
-    cerr << "verbosity " << verbose << endl;
+    gSettings.verbose += gopts["verbose"].size();
+    cerr << "verbosity " << gSettings.verbose << endl;
   }
 
   // testing option
@@ -170,20 +186,34 @@ int main(int argc, char **argv)
   }
 
   string command;
+
   if (optind < argc) {
     command = argv[optind++];
   }
-  if (command.empty())
-    command = "help";
-  cout << "COMMAND: " << command << endl;
+  if (command == "help") {
+    help = true;
+    if (optind < argc) {
+      command = argv[optind++];
+    }
+  }
+
+  if (command.empty()) {
+    cerr_vv << "No command" <<endl;
+    //command = "help";
+  }
+  cerr_v << "COMMAND: " << command << endl;
+
+  // === command-specific options ===
 
   struct option no_options = {0, 0, 0, 0};
   struct option *specific_options = &no_options;
+  string specific_help;
 
   string help_commands = "  Commands:\n"
       "\tinstall, in\t\tInstall packages or resolvables\n"
-      "\tservice-list, sl\t\tList services aka installation sources\n"
+      "\tservice-list, sl\tList services aka installation sources\n"
       "\tservice-add, sa\t\tAdd a new service\n"
+      "\tservice-delete, sd\t\tDelete a service\n"
       ;
 
   string help_global_source_options = "  Source options:\n"
@@ -203,16 +233,19 @@ int main(int argc, char **argv)
       {"no-refresh", no_argument, 0, 'n'},
       {0, 0, 0, 0}
     };
-
     specific_options = service_add_options;
+    specific_help = "  Command options:\n"
+      "\t--disabled\t\tAdd the service as disabled\n"
+      ;
   }
   else if (command == "service-list" || command == "sl") {
     static struct option service_list_options[] = {
-      {"terse", no_argument, 0, 't'},
       {0, 0, 0, 0}
     };
-
     specific_options = service_list_options;
+    specific_help = "  Command options:\n"
+      "\n"
+      ;
   }
   else {
     // no options. or make this an exhaustive thing?
@@ -224,33 +257,83 @@ int main(int argc, char **argv)
 
   list<string> arguments;
   if (optind < argc) {
-    cerr << "non-option ARGV-elements: ";
+    cerr_v << "non-option ARGV-elements: ";
     while (optind < argc) {
       string argument = argv[optind++];
-      cerr << argument << ' ';
+      cerr_v << argument << ' ';
       arguments.push_back (argument);
     }
-    cerr << endl;
+    cerr_v << endl;
   }
 
-  if (copts.count("disabled")) {
-      cout << "FAKE Disabled" << endl;
+  // === process options ===
+
+  if (gopts.count("terse")) {
+      cerr_v << "FAKE Terse" << endl;
   }
 
-  if (copts.count("no-refresh")) {
-      cout << "FAKE No Refresh" << endl;
+  if (gopts.count("disable-system-sources"))
+  {
+    MIL << "system sources disabled" << endl;
+    gSettings.disable_system_sources = true;
+  }
+  else
+  {
+    MIL << "system sources enabled" << endl;
   }
 
-  if (copts.count("terse")) {
-      cout << "FAKE Terse" << endl;
+  if (gopts.count("disable-system-resolvables"))
+  {
+    MIL << "system resolvables disabled" << endl;
+    cerr << "Ignoring installed resolvables..." << endl;
+    gSettings.disable_system_resolvables = true;
+  }
+  
+  if (gopts.count("source")) {
+    list<string> sources = gopts["source"];
+    for (list<string>::const_iterator it = sources.begin(); it != sources.end(); ++it )
+    {
+      Url url = make_url (*it);
+      if (!url.isValid())
+       return 1;
+      gSettings.additional_sources.push_back(url); 
+    }
+  }
+  
+  // === execute command ===
+
+  if (command.empty()) {
+    if (help) {
+      cerr << help_global_options << help_commands;
+    }
+    else {
+      cerr << "Try -h for help" << endl;
+    }
+    return 0;
   }
 
+  if (command == "moo") {
+    cout << "   \\\\\\\\\\\n  \\\\\\\\\\\\\\__o\n__\\\\\\\\\\\\\\'/_" << endl;
+    return 0;
+  }
 
+  // here come commands that need the lock
+  try {
+    God = zypp::getZYpp();
+  }
+  catch (Exception & excpt_r) {
+    ZYPP_CAUGHT (excpt_r);
+    ERR  << "a ZYpp transaction is already in progress." << endl;
+    cerr << "a ZYpp transaction is already in progress." << endl;
+    cout << RANDOM_TOKEN;
+    return 1;
+  }
+  
   if (command == "service-list" || command == "sl")
   {
     if ( geteuid() != 0 )
     {
-      cout << "Sorry, you need root privileges to view system sources." << endl;
+      cerr << "Sorry, you need root privileges to view system sources." << endl;
       return 1;
     }
     
@@ -258,145 +341,139 @@ int main(int argc, char **argv)
     return 0;
   }
   
-  if (command == "help") {
-    cout << "Help command" << endl;
-    return 0;
-  }
-
-  if (gopts.count("disable-system-sources"))
-  {
-    MIL << "system sources disabled" << endl;
-    gSettings.disable_system_sources = true;
-  }
-  else
+  if (command == "service-add" || command == "sa")
   {
-    if ( geteuid() != 0 )
-    {
-      cout << "Sorry, you need root privileges to use system sources, disabling them..." << endl;
-      gSettings.disable_system_sources = true;
-      MIL << "system sources disabled" << endl;
+    if (copts.count("disabled")) {
+      cerr_v << "FAKE Disabled" << endl;
     }
-    else
-    {
-      MIL << "system sources enabled" << endl;
+    if (copts.count("no-refresh")) {
+      cerr_v << "FAKE No Refresh" << endl;
     }
-  }
 
-  if (command == "service-add" || command == "sa")
-  {
+    if (help || arguments.size() < 1) {
+      cerr << "service-add [options] URI [alias]\n"
+       ""
+          << specific_help
+       ;
+      return !help;
+    }
+      
     Url url = make_url (arguments.front());
+    arguments.pop_front();
     if (!url.isValid())
       return 1;
-    
+    string alias = url.asString();
+    if (!arguments.empty())
+      alias = arguments.front();
+
+    // load gpg keys
+    // FIXME only once
+    cerr_v << "initializing target" << endl;
+    God->initializeTarget("/");
+
     try {
-      add_source_by_url(url, "aliasfixme");
+      // also stores it
+      add_source_by_url(url, alias);
     }
     catch ( const Exception & excpt_r )
     {
       cerr << excpt_r.asUserString() << endl;
       return 1;
     }
+
     return 0;
   }
-  
-  if (gopts.count("disable-system-resolvables"))
-  {
-    MIL << "system resolvables disabled" << endl;
-    cout << "Ignoring installed resolvables..." << endl;
-    gSettings.disable_system_resolvables = true;
-  }
-  
-  if (command == "install" || command == "in")
+
+  if (command == "service-delete" || command == "sd")
   {
-    gData.packages_to_install = vector<string>(arguments.begin(), arguments.end());
-  }
-  
-  if (gopts.count("source")) {
-    list<string> sources = gopts["source"];
-    for (list<string>::const_iterator it = sources.begin(); it != sources.end(); ++it )
+    if (help || arguments.size() < 1) {
+      cerr << "service-delete [options] <URI|alias>\n"
+          << specific_help
+       ;
+      return !help;
+    }
+
+    try {
+      // also stores it
+      remove_source(arguments.front());
+    }
+    catch ( const Exception & excpt_r )
     {
-      Url url = make_url (*it);
-      if (!url.isValid())
-       return 1;
-      gSettings.additional_sources.push_back(url); 
+      cerr << excpt_r.asUserString() << endl;
+      return 1;
     }
+
+    return 0;
   }
   
-  const char *logfile = getenv("ZYPP_LOGFILE");
-  if (logfile == NULL)
-    logfile = ZYPP_CHECKPATCHES_LOG;
-  zypp::base::LogControl::instance().logfile( logfile );
-  
-  std::string previous_token;
-  
-  God = NULL;
-  try
-  {
-    God = zypp::getZYpp();
-  }
-  catch (Exception & excpt_r)
-  {
-    ZYPP_CAUGHT (excpt_r);
-    ERR  << "a ZYpp transaction is already in progress." << endl;
-    cerr << "a ZYpp transaction is already in progress." << endl;
-    cout << RANDOM_TOKEN;
-    return 1;
-  }
-  
-  SourceManager_Ptr manager;
-  manager = SourceManager::sourceManager();
+  if (command == "install" || command == "in") {
+    gData.packages_to_install = vector<string>(arguments.begin(), arguments.end());
+    std::string previous_token;
   
-  KeyRingCallbacks keyring_callbacks;
-  DigestCallbacks digest_callbacks;
+    SourceManager_Ptr manager;
+    manager = SourceManager::sourceManager();
   
-  if ( ! gSettings.disable_system_sources )
-    init_system_sources();
+    KeyRingCallbacks keyring_callbacks;
+    DigestCallbacks digest_callbacks;
   
-  for ( std::list<Url>::const_iterator it = gSettings.additional_sources.begin(); it != gSettings.additional_sources.end(); ++it )
-  {
-    include_source_by_url( *it );
-  }
+    if ( geteuid() != 0 )
+    {
+      cerr << "Sorry, you need root privileges to use system sources, disabling them..." << endl;
+      gSettings.disable_system_sources = true;
+      MIL << "system sources disabled" << endl;
+    }
+
+    if ( ! gSettings.disable_system_sources ) {
+      cerr_v << "initializing sources" << endl;
+      init_system_sources();
+    }
   
-  cout << endl;
+    for ( std::list<Url>::const_iterator it = gSettings.additional_sources.begin(); it != gSettings.additional_sources.end(); ++it )
+      {
+       include_source_by_url( *it );
+      }
   
-  if ( gData.sources.empty() )
-  {
-    cout << "Warning! No sources. Operating only over the installed resolvables. You will not be able to install stuff" << endl;
-  } 
+    if ( gData.sources.empty() )
+      {
+       cerr << "Warning! No sources. Operating only over the installed resolvables. You will not be able to install stuff" << endl;
+      
   
-  // dont add rpms
-  God->initializeTarget("/");
+    // dont add rpms
+    cerr_v << "initializing target" << endl;
+    God->initializeTarget("/");
   
-  std::string token = calculate_token();
+    cerr_v << "calculating token" << endl;
+    std::string token = calculate_token();
   
-  if ( token != gSettings.previous_token )
-  {
-    // something changed
-    load_sources();
+    if ( token != gSettings.previous_token )
+      {
+       // something changed
+       cerr_v << "loading sources" << endl;
+       load_sources();
     
-    if ( ! gSettings.disable_system_resolvables )
-      load_target();
+       if ( ! gSettings.disable_system_resolvables ) {
+         cerr_v << "loading target" << endl;
+         load_target();
+       }
     
-    for ( vector<string>::const_iterator it = gData.packages_to_install.begin(); it != gData.packages_to_install.end(); ++it )
-    {
-      mark_package_for_install(*it);
-    }
+       for ( vector<string>::const_iterator it = gData.packages_to_install.begin(); it != gData.packages_to_install.end(); ++it )
+         {
+           mark_package_for_install(*it);
+         }
     
-    resolve();
+       cerr_v << "resolving" << endl;
+       resolve();
     
-    show_summary();
+       show_summary();
       
-    std::cout << "Continue? [y/n] ";
-    if (readBoolAnswer())
-    {
-      ZYppCommitResult result = God->commit( ZYppCommitPolicy() );
-      std::cout << result << std::endl; 
-    }
+       cerr << "Continue? [y/n] ";
+       if (readBoolAnswer())
+         {
+           cerr_v << "committing" << endl;
+           ZYppCommitResult result = God->commit( ZYppCommitPolicy() );
+           cerr << result << std::endl; 
+         }
+      }
   }
-  
-  
-
   return 0;
 }
-
-