summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2014-06-05 17:08:05 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2014-08-05 12:54:17 +0000
commitc0dbf949e7e443440bc43fb4863d8a91b9725da7 (patch)
tree28ac4d77330240cc8057c75d330d6ef5a6472451
parent1a6fb660b94228745efc4543138b9dc1fa50e912 (diff)
downloadmorph-sam/list-system-contents.tar.gz
Add list-system-contents commandsam/list-system-contents
This allows you to list the contents of a system artifact, and see which chunk artifact provided which file. Further, you can see which files were not included in the final system, due to artifact splitting and selection (those prefaced with an 'X' are not included).
-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