summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--morphlib/plugins/list_system_contents_plugin.py119
-rw-r--r--without-test-modules1
2 files changed, 120 insertions, 0 deletions
diff --git a/morphlib/plugins/list_system_contents_plugin.py b/morphlib/plugins/list_system_contents_plugin.py
new file mode 100644
index 00000000..02565620
--- /dev/null
+++ b/morphlib/plugins/list_system_contents_plugin.py
@@ -0,0 +1,119 @@
+# Copyright (C) 2014 Codethink Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+
+import cliapp
+import contextlib
+import fnmatch
+import tarfile
+import uuid
+
+import morphlib
+
+import pdb
+
+
+class ListSystemContentsPlugin(cliapp.Plugin):
+ '''Annotate the root file system for a given system.
+
+ Command line arguments:
+
+ * `SYSTEM` is the name of a system
+
+ '''
+
+ def enable(self):
+ self.app.add_subcommand(
+ 'list-system-contents', self.list_system_contents,
+ arg_synopsis='SYSTEM')
+
+ def disable(self):
+ pass
+
+ def commit_uncommitted_changes(self, system_branch):
+ # from morphlib/plugins/build_plugin.py
+ build_uuid = uuid.uuid4().hex
+
+ build_ref_prefix = self.app.settings['build-ref-prefix'] or 'build/'
+
+ self.app.status(msg="Creating temporary build branch")
+
+ build_branch = morphlib.buildbranch.BuildBranch(
+ system_branch, build_ref_prefix, push_temporary=False)
+ with contextlib.closing(build_branch) as build_branch:
+ # These functions return impure generators to do their work
+ # rather than actually doing what their names suggest.
+ list(build_branch.add_uncommitted_changes())
+
+ loader = morphlib.morphloader.MorphologyLoader()
+ list(build_branch.inject_build_refs(loader))
+
+ name = morphlib.git.get_user_name(self.app.runcmd)
+ email = morphlib.git.get_user_email(self.app.runcmd)
+ list(build_branch.update_build_refs(name, email, build_uuid))
+
+ return build_branch
+
+ def list_system_contents(self, args):
+ if len(args) != 1:
+ raise morphlib.Error("Usage: morph-search-file SYSTEM")
+
+ system_filename = morphlib.util.sanitise_morphology_path(args[0])
+
+ workspace = morphlib.workspace.open('.')
+ system_branch = morphlib.sysbranchdir.open_from_within('.')
+
+ build_branch = self.commit_uncommitted_changes(system_branch)
+
+ build_command = morphlib.buildcommand.BuildCommand(self.app)
+
+ source_pool = build_command.create_source_pool(
+ build_branch.root_repo_url,
+ build_branch.root_ref,
+ system_filename)
+ root_artifact = build_command.resolve_artifacts(source_pool)
+
+ build_command.build_in_order(root_artifact)
+
+ files = dict()
+ for artifact in root_artifact.walk():
+ if artifact.source.morphology['kind'] != 'chunk':
+ continue
+ try:
+ artifact_file = build_command.lac.get(artifact)
+ contents = morphlib.builder2.get_chunk_files(artifact_file)
+ for path in contents:
+ abs_path = '/%s' % path
+ if abs_path in files:
+ print 'WARNING: file %s is in more than one chunk!' % abs_path
+ files[abs_path] = artifact
+ files.update('/%s' % p for p in contents)
+ except tarfile.ReadError:
+ print "Read error for %s" % artifact.name
+
+ def get_stratum_for_chunk(chunk):
+ for artifact in chunk.dependents:
+ # Currently it's safe to assume that only the containing
+ # stratum will be in the chunk artifact's list of dependents.
+ if artifact.source.morphology['kind'] == 'stratum':
+ return artifact
+ raise ValueError(
+ 'Chunk %s has no stratum in its dependent list!' % chunk)
+
+ for path in sorted(files.iterkeys()):
+ chunk = files[path]
+ stratum = get_stratum_for_chunk(chunk)
+ chunk_in_system = (stratum in root_artifact.dependencies)
+ present_flag = ' ' if chunk_in_system else 'X'
+ print '%s %20s: %s' % (present_flag, chunk.name, path)
diff --git a/without-test-modules b/without-test-modules
index a3aedc45..718afd7f 100644
--- a/without-test-modules
+++ b/without-test-modules
@@ -31,5 +31,6 @@ morphlib/plugins/print_architecture_plugin.py
morphlib/plugins/add_binary_plugin.py
morphlib/plugins/push_pull_plugin.py
morphlib/plugins/distbuild_plugin.py
+morphlib/plugins/list_system_contents_plugin.py
# Not unit tested, since it needs a full system branch
morphlib/buildbranch.py