1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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)
|