aboutsummaryrefslogtreecommitdiff
path: root/src/clients/cave/cmd_print_unmanaged_files.cc
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 /src/clients/cave/cmd_print_unmanaged_files.cc
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>
Diffstat (limited to 'src/clients/cave/cmd_print_unmanaged_files.cc')
-rw-r--r--src/clients/cave/cmd_print_unmanaged_files.cc229
1 files changed, 229 insertions, 0 deletions
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 000000000..7b84669d7
--- /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;
+}
+