aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Saleem Abdulrasool <compnerd@compnerd.org> 2012-10-14 13:57:02 -0700
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2012-10-14 22:04:54 +0100
commit934e4074907c23af458153235e15d90016681d94 (patch)
treec07e21b807f11809c0913cda27d68e013ab17238
parent636f8879403986797f3a72155f4af38d4ce49fce (diff)
downloadpaludis-934e4074907c23af458153235e15d90016681d94.tar.gz
paludis-934e4074907c23af458153235e15d90016681d94.tar.xz
cave: add print-unmanaged-files
This adds a new command to cave: print-unmanaged-files. This command is similar in spirit to the print-unamanged-files demo ruby script. The default invocation will scan the system root and recursively list all files. You may however limit it to a subset of the filesystem by specifying the --root parameter. More than one root may be specified simultaneously. Signed-off-by: Saleem Abdulrasool <compnerd@compnerd.org>
-rw-r--r--src/clients/cave/Makefile.am1
-rw-r--r--src/clients/cave/cmd_print_unmanaged_files.cc229
-rw-r--r--src/clients/cave/cmd_print_unmanaged_files.hh43
-rw-r--r--src/clients/cave/command_factory.cc2
4 files changed, 275 insertions, 0 deletions
diff --git a/src/clients/cave/Makefile.am b/src/clients/cave/Makefile.am
index c8a30b2..8af714b 100644
--- a/src/clients/cave/Makefile.am
+++ b/src/clients/cave/Makefile.am
@@ -197,6 +197,7 @@ libcave_a_SOURCES = \
cmd_print_sets.cc cmd_print_sets.hh \
cmd_print_spec.cc cmd_print_spec.hh \
cmd_print_sync_protocols.cc cmd_print_sync_protocols.hh \
+ cmd_print_unmanaged_files.cc cmd_print_unmanaged_files.hh \
cmd_print_unused_distfiles.cc cmd_print_unused_distfiles.hh \
cmd_purge.cc cmd_purge.hh \
cmd_report.cc cmd_report.hh cmd_report-fmt.hh \
diff --git a/src/clients/cave/cmd_print_unmanaged_files.cc b/src/clients/cave/cmd_print_unmanaged_files.cc
new file mode 100644
index 0000000..7b84669
--- /dev/null
+++ b/src/clients/cave/cmd_print_unmanaged_files.cc
@@ -0,0 +1,229 @@
+/* vim: set et fdm=syntax sts=4 sw=4: */
+
+/*
+ * Copyright (c) 2012 Saleem Abdulrasool
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 55 Temple
+ * Place, Suite 330, Boston, MA 02111-1308 USA
+ */
+
+#include "cmd_print_unmanaged_files.hh"
+#include "command_command_line.hh"
+
+#include <paludis/args/do_help.hh>
+#include <paludis/args/log_level_arg.hh>
+
+#include <paludis/filter.hh>
+#include <paludis/contents.hh>
+#include <paludis/generator.hh>
+#include <paludis/selection.hh>
+#include <paludis/package_id.hh>
+#include <paludis/environment.hh>
+#include <paludis/metadata_key.hh>
+#include <paludis/filtered_generator.hh>
+
+#include <paludis/util/fs_path.hh>
+#include <paludis/util/fs_stat.hh>
+#include <paludis/util/fs_error.hh>
+#include <paludis/util/fs_iterator.hh>
+
+#include <set>
+#include <list>
+#include <iostream>
+#include <algorithm>
+
+using namespace paludis;
+using namespace cave;
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+namespace
+{
+ struct PrintUnmanagedFilesCommandLine :
+ CaveCommandCommandLine
+ {
+ virtual std::string app_name() const
+ {
+ return "cave print-unmanaged-files";
+ }
+
+ virtual std::string app_synopsis() const
+ {
+ return "Prints a list of unamanged files.";
+ }
+
+ virtual std::string app_description() const
+ {
+ return "Prints all files under a specified root which is not owned "
+ "by an installed package. No formatting is used, making the "
+ "output suitable for parsing by scripts.";
+ }
+
+ args::ArgsGroup g_general;
+ args::StringSetArg a_root;
+
+ PrintUnmanagedFilesCommandLine() :
+ g_general(main_options_section(), "General options",
+ "Options which are relevant for most or all actions"),
+ a_root(&g_general, "root", 'r', "Search under the specified root")
+ {
+ add_usage_line("[ --root root ]");
+ }
+ };
+
+ class CollectRecursiveDirectoryContents
+ {
+ public:
+ CollectRecursiveDirectoryContents(std::set<FSPath, FSPathComparator> * contents)
+ : _contents(contents)
+ {
+ }
+
+ ~CollectRecursiveDirectoryContents()
+ {
+ }
+
+ void operator()(const FSPath& path)
+ {
+ for (FSIterator entry(path, { fsio_include_dotfiles, fsio_want_regular_files, fsio_want_directories }), end;
+ entry != end; ++entry)
+ {
+ try
+ {
+ if (entry->stat().is_directory())
+ CollectRecursiveDirectoryContents(this->_contents)(*entry);
+ else
+ _contents->insert(*entry);
+ }
+ catch (const FSError& error)
+ {
+ cerr << error.message() << endl;
+ }
+ }
+ }
+
+ private:
+ std::set<FSPath, FSPathComparator> * const _contents;
+ };
+
+ class CollectPackageContents
+ {
+ public:
+ CollectPackageContents(std::set<FSPath, FSPathComparator> * contents)
+ : _contents(contents)
+ {
+ }
+
+ ~CollectPackageContents()
+ {
+ }
+
+ void operator()(const std::shared_ptr<const PackageID>& package)
+ {
+ const auto contents(package->contents());
+
+ if (! contents)
+ return;
+
+ for (auto entry(contents->begin()), end(contents->end());
+ entry != end; ++entry)
+ _contents->insert((*entry)->location_key()->parse_value());
+ }
+
+ private:
+ std::set<FSPath, FSPathComparator> * const _contents;
+ };
+}
+
+int
+PrintUnmanagedFilesCommand::run(const std::shared_ptr<Environment> & env,
+ const std::shared_ptr< const Sequence<std::string> > & args)
+{
+ PrintUnmanagedFilesCommandLine cmdline;
+ std::set<FSPath, FSPathComparator> roots;
+ std::set<FSPath, FSPathComparator> all_files;
+ std::set<FSPath, FSPathComparator> managed_files;
+ std::set<FSPath, FSPathComparator> unmanaged_files;
+
+ cmdline.run(args, "CAVE", "CAVE_PRINT_UNMANAGED_FILES_OPTIONS",
+ "CAVE_PRINT_UNMANAGED_FILES_CMDLINE");
+
+ if (cmdline.a_help.specified())
+ {
+ cout << cmdline;
+ return EXIT_SUCCESS;
+ }
+
+ if (cmdline.begin_parameters() != cmdline.end_parameters())
+ throw args::DoHelp("print-unmanaged-files takes no parameters");
+
+ const auto sysroot = env->preferred_root_key()->parse_value();
+
+ for (auto root(cmdline.a_root.begin_args()), end(cmdline.a_root.end_args());
+ root != end; ++root)
+ {
+ const FSPath path(*root);
+ const FSPath realpath(path.realpath());
+
+ if (! realpath.stat().is_directory())
+ {
+ std::cerr << path << " is not a directory" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (! realpath.starts_with(sysroot))
+ {
+ std::cerr << path << " is not under " << sysroot << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ roots.insert(realpath);
+ }
+
+ if (roots.empty())
+ roots.insert(sysroot);
+
+ std::for_each(roots.begin(), roots.end(),
+ CollectRecursiveDirectoryContents(&all_files));
+
+ const auto selection(selection::AllVersionsUnsorted(generator::All() | filter::InstalledAtRoot(sysroot)));
+ const auto packages((*env)[selection]);
+
+ std::for_each(packages->begin(), packages->end(),
+ CollectPackageContents(&managed_files));
+
+ std::set_difference(all_files.begin(), all_files.end(),
+ managed_files.begin(), managed_files.end(),
+ std::inserter(unmanaged_files, unmanaged_files.begin()),
+ FSPathComparator());
+
+ for (auto entry(unmanaged_files.begin()), end(unmanaged_files.end());
+ entry != end; ++entry)
+ cout << *entry << endl;
+
+ return EXIT_SUCCESS;
+}
+
+std::shared_ptr<args::ArgsHandler>
+PrintUnmanagedFilesCommand::make_doc_cmdline()
+{
+ return std::make_shared<PrintUnmanagedFilesCommandLine>();
+}
+
+CommandImportance
+PrintUnmanagedFilesCommand::importance() const
+{
+ return ci_scripting;
+}
+
diff --git a/src/clients/cave/cmd_print_unmanaged_files.hh b/src/clients/cave/cmd_print_unmanaged_files.hh
new file mode 100644
index 0000000..2f4081a
--- /dev/null
+++ b/src/clients/cave/cmd_print_unmanaged_files.hh
@@ -0,0 +1,43 @@
+/* vim: set et fdm=syntax sts=4 sw=4: */
+
+/*
+ * Copyright (c) 2012 Saleem Abdulrasool
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 55 Temple
+ * Place, Suite 330, Boston, MA 02111-1308 USA
+ */
+
+#ifndef PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_PRINT_UNMANAGED_FILES_HH
+#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_PRINT_UNMANAGED_FILES_HH 1
+
+#include "command.hh"
+
+namespace paludis
+{
+ namespace cave
+ {
+ class PALUDIS_VISIBLE PrintUnmanagedFilesCommand :
+ public Command
+ {
+ public:
+ virtual CommandImportance importance() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ int run(const std::shared_ptr<Environment> &,
+ const std::shared_ptr< const Sequence<std::string> > & args);
+
+ std::shared_ptr<args::ArgsHandler> make_doc_cmdline();
+ };
+ }
+}
+
+#endif
+
diff --git a/src/clients/cave/command_factory.cc b/src/clients/cave/command_factory.cc
index b373b1a..01fb414 100644
--- a/src/clients/cave/command_factory.cc
+++ b/src/clients/cave/command_factory.cc
@@ -80,6 +80,7 @@
#include "cmd_print_sets.hh"
#include "cmd_print_spec.hh"
#include "cmd_print_sync_protocols.hh"
+#include "cmd_print_unmanaged_files.hh"
#include "cmd_print_unused_distfiles.hh"
#include "cmd_purge.hh"
#include "cmd_report.hh"
@@ -203,6 +204,7 @@ CommandFactory::CommandFactory() :
_imp->handlers.insert(std::make_pair("print-sets", std::bind(&make_command<PrintSetsCommand>)));
_imp->handlers.insert(std::make_pair("print-spec", std::bind(&make_command<PrintSpecCommand>)));
_imp->handlers.insert(std::make_pair("print-sync-protocols", std::bind(&make_command<PrintSyncProtocolsCommand>)));
+ _imp->handlers.insert(std::make_pair("print-unmanaged-files", std::bind(&make_command<PrintUnmanagedFilesCommand>)));
_imp->handlers.insert(std::make_pair("print-unused-distfiles", std::bind(&make_command<PrintUnusedDistfilesCommand>)));
_imp->handlers.insert(std::make_pair("report", std::bind(&make_command<ReportCommand>)));
_imp->handlers.insert(std::make_pair("resolve", std::bind(&make_command<ResolveCommand>)));