diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2014-06-05 17:08:05 +0000 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2014-08-05 12:54:17 +0000 |
commit | c0dbf949e7e443440bc43fb4863d8a91b9725da7 (patch) | |
tree | 28ac4d77330240cc8057c75d330d6ef5a6472451 | |
parent | 1a6fb660b94228745efc4543138b9dc1fa50e912 (diff) | |
download | morph-c0dbf949e7e443440bc43fb4863d8a91b9725da7.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.py | 119 | ||||
-rw-r--r-- | without-test-modules | 1 |
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 |