Merge lp:~abentley/charmworld/remove-bzr-ingest-job into lp:~juju-jitsu/charmworld/trunk

Proposed by Aaron Bentley
Status: Merged
Approved by: Curtis Hovey
Approved revision: 282
Merged at revision: 280
Proposed branch: lp:~abentley/charmworld/remove-bzr-ingest-job
Merge into: lp:~juju-jitsu/charmworld/trunk
Diff against target: 471 lines (+150/-142)
5 files modified
charmworld/jobs/ingest.py (+96/-91)
charmworld/jobs/tests/test_bzr.py (+33/-34)
charmworld/jobs/tests/test_ingest.py (+8/-6)
charmworld/jobs/tests/test_scan.py (+6/-7)
charmworld/views/tests/test_charms.py (+7/-4)
To merge this branch: bzr merge lp:~abentley/charmworld/remove-bzr-ingest-job
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+170899@code.launchpad.net

Commit message

Remove BzrIngestJob.

Description of the change

This branch removes BzrIngestJob, converting its functionality into a set of functions.

Follow-on branches will remove other Job functionality, such as ScanIngestJob and FSIngestJob, and refactor the functions themselves into sensible collections of functionlality.

The main entry point is now do_bzr_update, which basically gathers resources and then calls update_charm_branch.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

Thank you.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'charmworld/jobs/ingest.py'
--- charmworld/jobs/ingest.py 2013-06-14 21:08:36 +0000
+++ charmworld/jobs/ingest.py 2013-06-21 20:10:35 +0000
@@ -76,7 +76,7 @@
76 pass76 pass
7777
78 def run(self, charm_data):78 def run(self, charm_data):
79 raise NotImplemented79 raise NotImplementedError
8080
8181
82class DBIngestJob(IngestJob):82class DBIngestJob(IngestJob):
@@ -97,95 +97,101 @@
97 self.fs = fs97 self.fs = fs
9898
9999
100class BzrIngestJob(FSIngestJob):100def do_bzr_update(charm_data, root_dir=None, db=None, fs=None, retry=True):
101101 """Fetch a branch from bzr, and augment charm data."""
102 name = 'bzr'102 job = FSIngestJob()
103103 job.setup(db, fs)
104 def setup(self, root_dir=None, db=None, fs=None):104 if not root_dir:
105 super(BzrIngestJob, self).setup(db, fs)105 root_dir = CHARM_DIR
106 if not root_dir:106 root_dir = root_dir
107 root_dir = CHARM_DIR107 if not os.path.exists(root_dir):
108 self.root_dir = root_dir108 os.makedirs(root_dir)
109 if not os.path.exists(self.root_dir):109 update_charm_files(root_dir, job.fs, charm_data, job.log, retry)
110 os.makedirs(self.root_dir)110
111111
112 def store_branch_files(self, charm_data):112def update_charm_branch(root_dir, fs, charm_data, branch_dir, log,
113 """Process the bzr branch for files that need to be stored in gridfs.113 retry=False):
114 """114 log.debug("Updating branch lp:%s", charm_data["branch_spec"])
115 self.log.info('Storing files of branch into gridfs')115 try:
116 filestore = CharmFileSet.save_files(
117 self.fs, charm_data, charm_data['branch_dir'], self.log)
118 self.log.info('Completed gridfs storage.')
119 return filestore
120
121 def add_files(self, charm_data):
122 charm_data['files'] = dict([
123 (quote_key(cfile.filename), dict(cfile)) for cfile in
124 self.store_branch_files(charm_data)
125 ])
126 return charm_data
127
128 def checkout_charm(self, charm_data, branch_dir):
129 # The branch has never been seen before. Original branch.
130 self.log.info("Branching charm lp:%s", charm_data["branch_spec"])
131 subprocess.check_output(116 subprocess.check_output(
132 ["/usr/bin/bzr", "co", "-q",117 ["/usr/bin/bzr", "update", "-q"],
133 "lp:%s" % charm_data["branch_spec"], branch_dir])118 cwd=branch_dir,
134 charm_data = self.add_files(charm_data)119 stderr=subprocess.STDOUT)
135120 charm_data = add_files(fs, charm_data, log)
136 def charm_is_current(self, charm_data, branch_dir):121 except subprocess.CalledProcessError:
137 # It exists and check if it's the latest revision already.122 # Update failed for some reason; destroy it and start over.
138 self.log.debug(123 if retry:
139 "Existing charm from lp:%s", charm_data["branch_spec"])124 shutil.rmtree(branch_dir)
140 transport = get_transport(branch_dir)125 return update_charm_files(root_dir, fs, charm_data, log,
141 branch = Branch.open_from_transport(transport)126 retry=False)
142 cur_rev_id = branch.last_revision()127 raise
143 return cur_rev_id == charm_data['commit']128
144129
145 def update_charm(self, charm_data, branch_dir, retry=False):130def charm_branch_is_current(charm_data, branch_dir, log):
146 self.log.debug("Updating branch lp:%s", charm_data["branch_spec"])131 # It exists and check if it's the latest revision already.
147 try:132 log.debug(
148 subprocess.check_output(133 "Existing charm from lp:%s", charm_data["branch_spec"])
149 ["/usr/bin/bzr", "update", "-q"],134 transport = get_transport(branch_dir)
150 cwd=branch_dir,135 branch = Branch.open_from_transport(transport)
151 stderr=subprocess.STDOUT)136 cur_rev_id = branch.last_revision()
152 charm_data = self.add_files(charm_data)137 return cur_rev_id == charm_data['commit']
153 except subprocess.CalledProcessError:138
154 # Update failed for some reason; destroy it and start over.139
155 if retry:140def checkout_charm(fs, charm_data, branch_dir, log):
156 shutil.rmtree(branch_dir)141 # The branch has never been seen before. Original branch.
157 return self.run(charm_data, retry=False)142 log.info("Branching charm lp:%s", charm_data["branch_spec"])
158 raise143 subprocess.check_output(
159144 ["/usr/bin/bzr", "co", "-q",
160 def run(self, charm_data, retry=True):145 "lp:%s" % charm_data["branch_spec"], branch_dir])
161 """Fetch a branch from bzr, and augment charm data."""146 charm_data = add_files(fs, charm_data, log)
162 if charm_data['branch_deleted']:147
163 return148
164 branch_dir = os.path.abspath(149def store_branch_files(fs, charm_data, log):
165 str(os.path.join(self.root_dir,150 """Process the bzr branch for files that need to be stored in gridfs.
166 charm_data["series"],151 """
167 charm_data["owner"],152 log.info('Storing files of branch into gridfs')
168 charm_data["name"],153 filestore = CharmFileSet.save_files(
169 charm_data["bname"])))154 fs, charm_data, charm_data['branch_dir'], log)
170155 log.info('Completed gridfs storage.')
171 if not os.path.exists(os.path.dirname(branch_dir)):156 return filestore
172 os.makedirs(os.path.dirname(branch_dir))157
173 # Store the branch directory158
174 charm_data["branch_dir"] = branch_dir159def add_files(fs, charm_data, log):
175160 charm_data['files'] = dict([
176 if not os.path.exists(branch_dir):161 (quote_key(cfile.filename), dict(cfile)) for cfile in
177 # Charm doesn't exist; check it out.162 store_branch_files(fs, charm_data, log)
178 self.checkout_charm(charm_data, branch_dir)163 ])
179 return164 return charm_data
180 elif self.charm_is_current(charm_data, branch_dir):165
181 # Charm exists, and is current; log and finish.166
182 charm_data = self.add_files(charm_data)167def update_charm_files(root_dir, fs, charm_data, log, retry):
183 self.log.debug(168 if charm_data['branch_deleted']:
184 "Already up to date lp:%s", charm_data["branch_spec"])169 return
185 return170 branch_dir = os.path.abspath(
186 else:171 str(os.path.join(root_dir,
187 # Charm exists, but needs updating; update it.172 charm_data["series"],
188 self.update_charm(charm_data, branch_dir, retry)173 charm_data["owner"],
174 charm_data["name"],
175 charm_data["bname"])))
176
177 if not os.path.exists(os.path.dirname(branch_dir)):
178 os.makedirs(os.path.dirname(branch_dir))
179 # Store the branch directory
180 charm_data["branch_dir"] = branch_dir
181
182 if not os.path.exists(branch_dir):
183 # Charm doesn't exist; check it out.
184 checkout_charm(fs, charm_data, branch_dir, log)
185 return
186 elif charm_branch_is_current(charm_data, branch_dir, log):
187 # Charm exists, and is current; log and finish.
188 charm_data = add_files(fs, charm_data, log)
189 log.debug(
190 "Already up to date lp:%s", charm_data["branch_spec"])
191 return
192 else:
193 # Charm exists, but needs updating; update it.
194 update_charm_branch(charm_data, branch_dir, retry)
189195
190196
191def log(stage, level, exc, charm_data, tb=None):197def log(stage, level, exc, charm_data, tb=None):
@@ -228,8 +234,7 @@
228 charm_data.pop('error', None)234 charm_data.pop('error', None)
229 log = logging.getLogger("charm.update_charm")235 log = logging.getLogger("charm.update_charm")
230 try:236 try:
231 if not run_job(BzrIngestJob(), charm_data, db=db):237 do_bzr_update(charm_data, db=db)
232 return False
233 if not run_job(StoreIngestJob(), charm_data):238 if not run_job(StoreIngestJob(), charm_data):
234 return False239 return False
235 if not run_job(ProofIngestJob(), charm_data):240 if not run_job(ProofIngestJob(), charm_data):
236241
=== modified file 'charmworld/jobs/tests/test_bzr.py'
--- charmworld/jobs/tests/test_bzr.py 2013-06-07 12:36:30 +0000
+++ charmworld/jobs/tests/test_bzr.py 2013-06-21 20:10:35 +0000
@@ -11,8 +11,10 @@
1111
1212
13from charmworld.jobs.ingest import (13from charmworld.jobs.ingest import (
14 BzrIngestJob,14 add_files,
15 do_bzr_update,
15 ChangelogIngestJob,16 ChangelogIngestJob,
17 FSIngestJob,
16)18)
17from charmworld.testing import (19from charmworld.testing import (
18 factory,20 factory,
@@ -27,38 +29,32 @@
27ZRH = 'Z. Random Hacker <zrandom@example.com>'29ZRH = 'Z. Random Hacker <zrandom@example.com>'
2830
2931
30class TestBzrJob(JobTestBase):32class TestBzrOperations(JobTestBase):
3133
32 def setUp(self):34 def setUp(self):
33 super(TestBzrJob, self).setUp()35 super(TestBzrOperations, self).setUp()
34 self.test_dir = 'test_bzr_job'36 self.test_dir = 'test_bzr_operations'
35 os.mkdir(self.test_dir)37 os.mkdir(self.test_dir)
3638
37 def tearDown(self):39 def tearDown(self):
38 shutil.rmtree(self.test_dir)40 shutil.rmtree(self.test_dir)
39 super(TestBzrJob, self).tearDown()41 super(TestBzrOperations, self).tearDown()
4042
41 def test_run_creates_charm_directory(self):43 def test_run_creates_charm_directory(self):
42 job = BzrIngestJob()
43 job.setup(root_dir=self.test_dir, db=self.db)
44 ignore, charm = factory.makeCharm(self.db, branch_root=self.test_dir)44 ignore, charm = factory.makeCharm(self.db, branch_root=self.test_dir)
45 with patch.object(job, 'checkout_charm'):45 with patch('charmworld.jobs.ingest.checkout_charm'):
46 job.run(charm)46 do_bzr_update(charm, self.test_dir, self.db)
47 expected_path = os.path.abspath(os.path.join(47 expected_path = os.path.abspath(os.path.join(
48 self.test_dir, charm['series'], charm['owner'], charm['name']))48 self.test_dir, charm['series'], charm['owner'], charm['name']))
49 self.assertTrue(os.path.exists(expected_path))49 self.assertTrue(os.path.exists(expected_path))
5050
51 def test_run_checkouts_new_charms(self):51 def test_run_checkouts_new_charms(self):
52 job = BzrIngestJob()
53 job.setup(root_dir=self.test_dir, db=self.db)
54 ignore, charm = factory.makeCharm(self.db, branch_root=self.test_dir)52 ignore, charm = factory.makeCharm(self.db, branch_root=self.test_dir)
55 with patch.object(job, 'checkout_charm') as mock:53 with patch('charmworld.jobs.ingest.checkout_charm') as mock:
56 job.run(charm)54 do_bzr_update(charm, self.test_dir, self.db)
57 self.assertTrue(mock.called)55 self.assertTrue(mock.called)
5856
59 def test_run_updates_exising_charms_if_not_current(self):57 def test_run_updates_exising_charms_if_not_current(self):
60 job = BzrIngestJob()
61 job.setup(root_dir=self.test_dir, db=self.db)
62 ignore, charm = factory.makeCharm(self.db, branch_root=self.test_dir)58 ignore, charm = factory.makeCharm(self.db, branch_root=self.test_dir)
63 charm_path = os.path.abspath(os.path.join(59 charm_path = os.path.abspath(os.path.join(
64 self.test_dir,60 self.test_dir,
@@ -67,14 +63,13 @@
67 charm['name'],63 charm['name'],
68 charm['bname']))64 charm['bname']))
69 os.makedirs(charm_path)65 os.makedirs(charm_path)
70 with patch.object(job, 'charm_is_current', lambda x, y: False):66 with patch('charmworld.jobs.ingest.charm_branch_is_current',
71 with patch.object(job, 'update_charm') as mock:67 lambda x, y, z: False):
72 job.run(charm)68 with patch('charmworld.jobs.ingest.update_charm_branch') as mock:
69 do_bzr_update(charm, self.test_dir, self.db)
73 self.assertTrue(mock.called)70 self.assertTrue(mock.called)
7471
75 def test_run_does_not_update_exising_charms_if_current(self):72 def test_run_does_not_update_exising_charms_if_current(self):
76 job = BzrIngestJob()
77 job.setup(root_dir=self.test_dir, db=self.db)
78 ignore, charm = factory.makeCharm(self.db, branch_root=self.test_dir)73 ignore, charm = factory.makeCharm(self.db, branch_root=self.test_dir)
79 charm_path = os.path.abspath(os.path.join(74 charm_path = os.path.abspath(os.path.join(
80 self.test_dir,75 self.test_dir,
@@ -83,10 +78,12 @@
83 charm['name'],78 charm['name'],
84 charm['bname']))79 charm['bname']))
85 os.makedirs(charm_path)80 os.makedirs(charm_path)
86 with patch.object(job, 'charm_is_current', lambda x, y: True):81 with patch('charmworld.jobs.ingest.charm_branch_is_current',
87 with patch.object(job, 'add_files'):82 lambda x, y, z: True):
88 with patch.object(job, 'update_charm') as mock:83 with patch('charmworld.jobs.ingest.add_files'):
89 job.run(charm)84 with patch(
85 'charmworld.jobs.ingest.update_charm_branch') as mock:
86 do_bzr_update(charm, self.test_dir, self.db)
90 self.assertFalse(mock.called)87 self.assertFalse(mock.called)
9188
92 def test_add_files(self):89 def test_add_files(self):
@@ -98,17 +95,15 @@
98 'name': 'sample_charm',95 'name': 'sample_charm',
99 'bname': 'trunk',96 'bname': 'trunk',
100 }97 }
101 job = BzrIngestJob()98 job = FSIngestJob()
102 job.setup(db=self.db)99 job.setup(db=self.db)
103 job.add_files(charm_data)100 add_files(job.fs, charm_data, job.log)
104 self.assertIn('files', charm_data)101 self.assertIn('files', charm_data)
105 self.assertNotIn('icon', charm_data)102 self.assertNotIn('icon', charm_data)
106103
107 def test_deleted_branch(self):104 def test_deleted_branch(self):
108 # If the Launchpad branch of a charm is deleted, BzrJob does105 # If the Launchpad branch of a charm is deleted, do_bzr_update does
109 # not do anything.106 # not do anything.
110 job = BzrIngestJob()
111 job.setup(root_dir=self.test_dir, db=self.db)
112 ignore, charm = factory.makeCharm(107 ignore, charm = factory.makeCharm(
113 self.db, branch_root=self.test_dir, branch_deleted=True)108 self.db, branch_root=self.test_dir, branch_deleted=True)
114 charm_path = os.path.abspath(os.path.join(109 charm_path = os.path.abspath(os.path.join(
@@ -117,11 +112,15 @@
117 charm['owner'],112 charm['owner'],
118 charm['name'],113 charm['name'],
119 charm['bname']))114 charm['bname']))
120 with patch.object(job, 'checkout_charm') as checkout_mock:115 with patch('charmworld.jobs.ingest.checkout_charm') as checkout_mock:
121 with patch.object(job, 'charm_is_current') as is_current_mock:116 with patch('charmworld.jobs.ingest.charm_branch_is_current') as (
122 with patch.object(job, 'add_files') as add_files_mock:117 is_current_mock):
123 with patch.object(job, 'update_charm') as update_mock:118 with patch('charmworld.jobs.ingest.add_files') as (
124 job.run(charm)119 add_files_mock):
120 with patch(
121 'charmworld.jobs.ingest.update_charm_branch') as (
122 update_mock):
123 do_bzr_update(charm, self.test_dir, self.db)
125 self.assertFalse(os.path.exists(charm_path))124 self.assertFalse(os.path.exists(charm_path))
126 self.assertFalse(checkout_mock.called)125 self.assertFalse(checkout_mock.called)
127 self.assertFalse(is_current_mock.called)126 self.assertFalse(is_current_mock.called)
128127
=== modified file 'charmworld/jobs/tests/test_ingest.py'
--- charmworld/jobs/tests/test_ingest.py 2013-06-07 12:36:30 +0000
+++ charmworld/jobs/tests/test_ingest.py 2013-06-21 20:10:35 +0000
@@ -19,6 +19,7 @@
1919
20from charmworld.charmstore import get_address20from charmworld.charmstore import get_address
21from charmworld.jobs.ingest import (21from charmworld.jobs.ingest import (
22 add_files,
22 IngestError,23 IngestError,
23 IngestJob,24 IngestJob,
24 run_job,25 run_job,
@@ -64,16 +65,16 @@
6465
65@contextmanager66@contextmanager
66def update_environment(real_charm_data, index_client):67def update_environment(real_charm_data, index_client):
67 def checkout_charm(self, charm_data, branch_dir):68 def checkout_charm(fs, charm_data, branch_dir, log):
68 wt = BzrDir.create_standalone_workingtree(branch_dir)69 wt = BzrDir.create_standalone_workingtree(branch_dir)
69 wt.bzrdir.root_transport.mkdir('hooks')70 wt.bzrdir.root_transport.mkdir('hooks')
70 wt.bzrdir.root_transport.put_bytes('metadata.yaml', json.dumps({71 wt.bzrdir.root_transport.put_bytes('metadata.yaml', json.dumps({
71 'name': charm_data['name'],72 'name': charm_data['name'],
72 'summary': real_charm_data['summary'],73 'summary': real_charm_data['summary'],
73 }))74 }))
74 self.add_files(charm_data)75 add_files(fs, charm_data, log)
75 checkout_patch = patch(76 checkout_patch = patch(
76 'charmworld.jobs.ingest.BzrIngestJob.checkout_charm', checkout_charm)77 'charmworld.jobs.ingest.checkout_charm', checkout_charm)
7778
78 @urlmatch(path='/charm-info')79 @urlmatch(path='/charm-info')
79 def mock_store_data(url, request):80 def mock_store_data(url, request):
@@ -150,15 +151,16 @@
150 # Induce improbable error -- bname must be a string.151 # Induce improbable error -- bname must be a string.
151 charm_data['bname'] = None152 charm_data['bname'] = None
152 update_handler = self.get_handler('charm.update')153 update_handler = self.get_handler('charm.update')
153 bzr_handler = self.get_handler('charm.bzr')154 update_charm_handler = self.get_handler('charm.update_charm')
154 run_job(UpdateCharmJob(), self.payload(charm_data), db=self.db)155 run_job(UpdateCharmJob(), self.payload(charm_data), db=self.db)
155 self.assertIsNot(156 self.assertIsNot(
156 None, self.db.charms.find_one(charm_data['_id']))157 None, self.db.charms.find_one(charm_data['_id']))
157 logs = ''.join(r.getMessage() for r in update_handler.buffer)158 logs = ''.join(r.getMessage() for r in update_handler.buffer)
158 bzr_logs = ''.join(r.getMessage() for r in bzr_handler.buffer)159 update_charm_logs = ''.join(r.getMessage()
160 for r in update_charm_handler.buffer)
159 self.assertEqual('Saving %s' % charm_data['_id'], logs)161 self.assertEqual('Saving %s' % charm_data['_id'], logs)
160 self.assertIn("'NoneType' object has no attribute 'startswith'",162 self.assertIn("'NoneType' object has no attribute 'startswith'",
161 bzr_logs)163 update_charm_logs)
162164
163 def test_updates_promulgated(self):165 def test_updates_promulgated(self):
164 charm_data = factory.get_charm_json(promulgated=False)166 charm_data = factory.get_charm_json(promulgated=False)
165167
=== modified file 'charmworld/jobs/tests/test_scan.py'
--- charmworld/jobs/tests/test_scan.py 2013-05-27 10:26:40 +0000
+++ charmworld/jobs/tests/test_scan.py 2013-06-21 20:10:35 +0000
@@ -1,12 +1,13 @@
1# Copyright 2012, 2013 Canonical Ltd. This software is licensed under the1# Copyright 2012, 2013 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4from charmworld.jobs.ingest import BzrIngestJob4from charmworld.jobs.ingest import (
5from charmworld.jobs.ingest import IngestError5 IngestError,
6from charmworld.jobs.ingest import ScanIngestJob6 ScanIngestJob,
7 store_branch_files,
8)
7from charmworld.testing import factory9from charmworld.testing import factory
8from charmworld.testing import JobTestBase10from charmworld.testing import JobTestBase
9from charmworld.testing import REAL_FILE_CHARM_DIR
10from charmworld.utils import quote_key11from charmworld.utils import quote_key
1112
1213
@@ -14,14 +15,12 @@
1415
15 def setUp(self):16 def setUp(self):
16 super(TestScanJob, self).setUp()17 super(TestScanJob, self).setUp()
17 self.bzr_job = BzrIngestJob()
18 self.bzr_job.setup(db=self.db, root_dir=REAL_FILE_CHARM_DIR)
19 self.scan_job = ScanIngestJob()18 self.scan_job = ScanIngestJob()
20 self.scan_job.setup(db=self.db)19 self.scan_job.setup(db=self.db)
21 ignore, self.charm = factory.makeCharm(self.db, with_real_files=True)20 ignore, self.charm = factory.makeCharm(self.db, with_real_files=True)
22 self.charm['files'] = dict([21 self.charm['files'] = dict([
23 (quote_key(cfile.filename), dict(cfile)) for cfile in22 (quote_key(cfile.filename), dict(cfile)) for cfile in
24 self.bzr_job.store_branch_files(self.charm)23 store_branch_files(self.scan_job.fs, self.charm, self.scan_job.log)
25 ])24 ])
2625
27 def test_config_metadata_with_dotted_keys(self):26 def test_config_metadata_with_dotted_keys(self):
2827
=== modified file 'charmworld/views/tests/test_charms.py'
--- charmworld/views/tests/test_charms.py 2013-06-19 20:45:35 +0000
+++ charmworld/views/tests/test_charms.py 2013-06-21 20:10:35 +0000
@@ -1,7 +1,10 @@
1# Copyright 2012, 2013 Canonical Ltd. This software is licensed under the1# Copyright 2012, 2013 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4from charmworld.jobs.ingest import BzrIngestJob4from charmworld.jobs.ingest import (
5 add_files,
6 FSIngestJob,
7)
5from charmworld.models import Charm8from charmworld.models import Charm
6from charmworld.models import CharmSource9from charmworld.models import CharmSource
7from charmworld.testing import factory10from charmworld.testing import factory
@@ -282,9 +285,9 @@
282 ignore, charm = factory.makeCharm(285 ignore, charm = factory.makeCharm(
283 self.db, owner='bar', series='precise',286 self.db, owner='bar', series='precise',
284 promulgated=promulgated, with_real_files=True)287 promulgated=promulgated, with_real_files=True)
285 bzr_job = BzrIngestJob()288 fs_job = FSIngestJob()
286 bzr_job.setup(root_dir=None, db=self.db)289 fs_job.setup(db=self.db)
287 bzr_job.add_files(charm)290 add_files(fs_job.fs, charm, fs_job.log)
288 self.db.charms.update({'_id': charm['_id']}, charm)291 self.db.charms.update({'_id': charm['_id']}, charm)
289 return charm292 return charm
290293

Subscribers

People subscribed via source and target branches