66
61
from bzrlib.plugins.builddeb.bzrtools_import import import_dir
67
62
from bzrlib.plugins.builddeb.errors import (
63
PackageVersionNotPresent,
69
64
UpstreamAlreadyImported,
70
65
UpstreamBranchAlreadyMerged,
72
67
from bzrlib.plugins.builddeb.util import (
71
component_from_orig_tarball,
72
extract_orig_tarballs,
76
73
get_commit_info_from_changelog,
77
make_pristine_tar_delta,
79
75
open_file_via_transport,
84
from bzrlib.plugins.builddeb.upstream import (
80
from bzrlib.plugins.builddeb.upstream.pristinetar import (
87
from bzrlib.plugins.builddeb.upstream.branch import (
92
85
class DscCache(object):
94
def __init__(self, transport=None):
96
self.transport_cache = {}
97
self.transport = transport
99
def get_dsc(self, name):
101
if name in self.cache:
102
dsc1 = self.cache[name]
104
# Obtain the dsc file, following any redirects as needed.
105
filename, transport = open_transport(name)
106
f1 = open_file_via_transport(filename, transport)
108
dsc1 = deb822.Dsc(f1)
111
self.cache[name] = dsc1
112
self.transport_cache[name] = transport
116
def get_transport(self, name):
117
return self.transport_cache[name]
87
def __init__(self, transport=None):
89
self.transport_cache = {}
90
self.transport = transport
92
def get_dsc(self, name):
94
if name in self.cache:
95
dsc1 = self.cache[name]
97
# Obtain the dsc file, following any redirects as needed.
98
filename, transport = open_transport(name)
99
f1 = open_file_via_transport(filename, transport)
101
dsc1 = deb822.Dsc(f1)
104
self.cache[name] = dsc1
105
self.transport_cache[name] = transport
109
def get_transport(self, name):
110
return self.transport_cache[name]
119
112
class DscComp(object):
121
def __init__(self, cache):
114
def __init__(self, cache):
124
def cmp(self, dscname1, dscname2):
125
dsc1 = self.cache.get_dsc(dscname1)
126
dsc2 = self.cache.get_dsc(dscname2)
127
v1 = Version(dsc1['Version'])
128
v2 = Version(dsc2['Version'])
117
def cmp(self, dscname1, dscname2):
118
dsc1 = self.cache.get_dsc(dscname1)
119
dsc2 = self.cache.get_dsc(dscname2)
120
v1 = Version(dsc1['Version'])
121
v2 = Version(dsc2['Version'])
212
205
have a total ordering with respect to these relationships.
215
def __init__(self, branch, upstream_branch, tree=None,
208
def __init__(self, branch, pristine_upstream_branch, tree=None,
209
pristine_upstream_tree=None):
217
210
"""Create a distribution branch.
219
212
You can only import packages on to the DistributionBranch
220
if both tree and upstream_tree are provided.
213
if both tree and pristine_upstream_tree are provided.
222
215
:param branch: the Branch for the packaging part.
223
:param upstream_branch: the Branch for the upstream part, if any.
216
:param upstream_pristine_branch: the Branch for the pristine tar part, if any.
224
217
:param tree: an optional tree for the branch.
225
:param upstream_tree: an optional upstream_tree for the
218
:param pristine_upstream_tree: an optional tree for the
228
221
self.branch = branch
230
self.pristine_tar_source = PristineTarSource(branch=branch, tree=tree)
231
self.upstream_branch = upstream_branch
232
self.upstream_tree = upstream_tree
233
if upstream_branch is not None:
234
self.upstream_source = UpstreamBranchSource(self.upstream_branch)
223
self.pristine_upstream_branch = pristine_upstream_branch
224
self.pristine_upstream_tree = pristine_upstream_tree
225
if pristine_upstream_branch is not None:
226
self.pristine_upstream_source = PristineTarSource(
227
branch=pristine_upstream_branch, tree=pristine_upstream_tree)
236
self.upstream_source = None
229
self.pristine_upstream_source = None
237
230
self.get_lesser_branches = None
238
231
self.get_greater_branches = None
284
277
return str(version)
286
279
def _has_version(self, branch, tag_name, md5=None):
287
if branch.tags.has_tag(tag_name):
288
revid = branch.tags.lookup_tag(tag_name)
291
graph = branch.repository.get_graph()
292
if not graph.is_ancestor(revid, branch.last_revision()):
298
rev = branch.repository.get_revision(revid)
300
return rev.properties['deb-md5'] == md5
302
warning("tag %s present in branch, but there is no "
303
"associated 'deb-md5' property" % tag_name)
280
if not branch.tags.has_tag(tag_name):
282
revid = branch.tags.lookup_tag(tag_name)
285
graph = branch.repository.get_graph()
286
if not graph.is_ancestor(revid, branch.last_revision()):
292
rev = branch.repository.get_revision(revid)
294
return rev.properties['deb-md5'] == md5
296
warning("tag %s present in branch, but there is no "
297
"associated 'deb-md5' property" % tag_name)
307
300
def has_version(self, version, md5=None):
308
301
"""Whether this branch contains the package version specified.
332
def has_upstream_version(self, version, md5=None):
333
"""Whether this branch contains the upstream version specified.
335
The version must be judged present by having the appropriate tag
336
in the upstream branch. If the md5 argument is not None then the
337
string passed must the the md5sum that is associated with the
338
revision pointed to by the tag.
340
:param version: a upstream version number to look for in the upstream
342
:param md5: a string with the md5sum that if not None must be
343
associated with the revision.
344
:return: True if the upstream branch contains the specified upstream
345
version of the package. False otherwise.
347
for tag_name in self.pristine_tar_source.possible_tag_names(version):
348
if self._has_version(self.upstream_branch, tag_name, md5=md5):
352
325
def contained_versions(self, versions):
353
326
"""Splits a list of versions depending on presence in the branch.
436
409
return self.branch.tags.lookup_tag(ubuntu_tag_name)
437
410
return self.branch.tags.lookup_tag(tag_name)
439
def revid_of_upstream_version(self, version):
440
"""Returns the revision id corresponding to the upstream version.
442
:param version: the Version object to extract the upstream version
443
from to retreive the revid of. The upstream version must be
444
present in the upstream branch.
445
:return: the revision id corresponding to the upstream portion
448
for tag_name in self.pristine_tar_source.possible_tag_names(version):
449
if self._has_version(self.upstream_branch, tag_name):
450
return self.upstream_branch.tags.lookup_tag(tag_name)
451
tag_name = self.pristine_tar_source.tag_name(version)
452
return self.upstream_branch.tags.lookup_tag(tag_name)
454
412
def tag_version(self, version, revid=None):
455
413
"""Tags the branch's last revision with the given version.
478
436
:param version: the upstream part of the version number to derive the
480
438
:param revid: the revid to associate the tag with, or None for the
481
tip of self.upstream_branch.
439
tip of self.pristine_upstream_branch.
482
440
:return The tag name, revid of the added tag.
484
442
assert isinstance(version, str)
485
tag_name = self.pristine_tar_source.tag_name(version)
443
tag_name = self.pristine_upstream_source.tag_name(version)
486
444
if revid is None:
487
revid = self.upstream_branch.last_revision()
488
self.upstream_branch.tags.set_tag(tag_name, revid)
490
self.branch.repository.fetch(self.upstream_branch.repository,
492
except NoSuchRevision:
445
revid = self.pristine_upstream_branch.last_revision()
446
self.pristine_upstream_source.tag_version(version, revid)
447
self.branch.fetch(self.pristine_upstream_branch)
495
448
self.branch.tags.set_tag(tag_name, revid)
496
449
return tag_name, revid
566
534
self.branch.lock_read()
568
536
for branch in reversed(self.get_lesser_branches()):
569
if branch.has_version(version, md5=md5):
570
# Check that they haven't diverged
571
branch.branch.lock_read()
573
graph = branch.branch.repository.get_graph(
574
self.branch.repository)
575
other_revid = branch.revid_of_version(version)
576
if len(graph.heads([other_revid,
577
self.branch.last_revision()])) == 1:
580
branch.branch.unlock()
537
if self.can_pull_from_branch(branch, version, md5):
581
539
for branch in self.get_greater_branches():
582
if branch.has_version(version, md5=md5):
583
# Check that they haven't diverged
584
branch.branch.lock_read()
586
graph = branch.branch.repository.get_graph(
587
self.branch.repository)
588
other_revid = branch.revid_of_version(version)
589
if len(graph.heads([other_revid,
590
self.branch.last_revision()])) == 1:
593
branch.branch.unlock()
540
if self.can_pull_from_branch(branch, version, md5):
596
544
self.branch.unlock()
598
def branch_to_pull_upstream_from(self, version, md5):
546
def can_pull_upstream_from_branch(self, branch, package, version,
547
upstream_tarballs=None):
548
"""Check if a version can be pulled from another branch into this one.
550
:param branch: Branch with upstream version
551
:param package: Package name
552
:param version: Package version
553
:param upstream_tarballs: Required upstream tarballs (optional)
555
if not branch.pristine_upstream_source.has_version(package, version,
556
tarballs=upstream_tarballs):
559
up_branch = self.pristine_upstream_branch
560
up_branch.lock_read()
562
# Check that they haven't diverged
563
other_up_branch = branch.pristine_upstream_branch
564
other_up_branch.lock_read()
566
graph = other_up_branch.repository.get_graph(
567
up_branch.repository)
568
return graph.is_ancestor(up_branch.last_revision(),
569
branch.pristine_upstream_source.version_as_revision(package, version))
571
other_up_branch.unlock()
575
def branch_to_pull_upstream_from(self, package, version, upstream_tarballs):
599
576
"""Checks whether this upstream is a pull from a lesser branch.
601
578
Looks in all the other upstream branches for the given
609
586
:param version: the upstream version to use when searching in the
611
:param md5: a String containing the md5 associateed with the
613
588
:return: a DistributionBranch object to pull the upstream from
614
589
if that is what should be done, otherwise None.
616
591
assert isinstance(version, str)
617
assert md5 is not None, \
618
("It's not a good idea to use branch_to_pull_upstream_from with "
619
"md5 == None, as you may pull the wrong revision.")
620
up_branch = self.upstream_branch
621
up_branch.lock_read()
623
for branch in reversed(self.get_lesser_branches()):
624
if branch.has_upstream_version(version, md5=md5):
625
# Check for divergenge.
626
other_up_branch = branch.upstream_branch
627
other_up_branch.lock_read()
629
graph = other_up_branch.repository.get_graph(
630
up_branch.repository)
631
other_revid = branch.revid_of_upstream_version(
633
if len(graph.heads([other_revid,
634
up_branch.last_revision()])) == 1:
637
other_up_branch.unlock()
638
for branch in self.get_greater_branches():
639
if branch.has_upstream_version(version, md5=md5):
640
# Check for divergenge.
641
other_up_branch = branch.upstream_branch
642
other_up_branch.lock_read()
644
graph = other_up_branch.repository.get_graph(
645
up_branch.repository)
646
other_revid = branch.revid_of_upstream_version(
648
if len(graph.heads([other_revid,
649
up_branch.last_revision()])) == 1:
652
other_up_branch.unlock()
592
for branch in reversed(self.get_lesser_branches()):
593
if self.can_pull_upstream_from_branch(branch, package, version,
596
for branch in self.get_greater_branches():
597
if self.can_pull_upstream_from_branch(branch, package, version,
657
602
def get_parents(self, versions):
658
603
"""Return the list of parents for a specific version.
735
680
:param version: the upstream version string
737
682
assert isinstance(version, str)
738
pull_revision = pull_branch.revid_of_upstream_version(version)
683
pull_revision = pull_branch.pristine_upstream_source.version_as_revision(package, version)
739
684
mutter("Pulling upstream part of %s from revision %s" % \
740
685
(version, pull_revision))
741
up_pull_branch = pull_branch.upstream_branch
742
assert self.upstream_tree is not None, \
686
assert self.pristine_upstream_tree is not None, \
743
687
"Can't pull upstream with no tree"
744
self.upstream_tree.pull(up_pull_branch,
688
self.pristine_upstream_tree.pull(pull_branch.pristine_upstream_branch,
745
689
stop_revision=pull_revision)
746
self.tag_upstream_version(version, revid=pull_revision)
747
self.branch.fetch(self.upstream_branch, last_revision=pull_revision)
748
self.upstream_branch.tags.merge_to(self.branch.tags)
690
self.pristine_upstream_source.tag_version(version, pull_revision)
691
self.branch.fetch(self.pristine_upstream_branch, last_revision=pull_revision)
692
self.pristine_upstream_branch.tags.merge_to(self.branch.tags)
750
def pull_version_from_branch(self, pull_branch, version, native=False):
694
def pull_version_from_branch(self, pull_branch, package, version, native=False):
751
695
"""Pull a version from a particular branch.
753
697
Given a DistributionBranch and a version number this method
774
718
assert self.tree is not None, "Can't pull branch with no tree"
775
719
self.tree.pull(pull_branch.branch, stop_revision=pull_revision)
776
720
self.tag_version(version, revid=pull_revision)
777
if not native and not self.has_upstream_version(version.upstream_version):
778
if pull_branch.has_upstream_version(version.upstream_version):
721
if not native and not self.pristine_upstream_source.has_version(package, version.upstream_version):
722
if pull_branch.pristine_upstream_source.has_version(package, version.upstream_version):
779
723
self.pull_upstream_from_branch(pull_branch,
780
version.upstream_version)
724
package, version.upstream_version)
782
726
assert False, ("Can't find the needed upstream part "
783
727
"for version %s" % version)
784
if (native and self.upstream_branch.last_revision() == NULL_REVISION
785
and pull_branch.upstream_branch.last_revision() != NULL_REVISION):
728
if (native and self.pristine_upstream_branch.last_revision() == NULL_REVISION
729
and pull_branch.pristine_upstream_branch.last_revision() != NULL_REVISION):
786
730
# in case the package wasn't native before then we pull
787
731
# the upstream. These checks may be a bit restrictive.
788
self.upstream_tree.pull(pull_branch.upstream_branch)
789
pull_branch.upstream_branch.tags.merge_to(self.upstream_branch.tags)
732
self.pristine_upstream_tree.pull(pull_branch.pristine_upstream_branch)
733
pull_branch.pristine_upstream_branch.tags.merge_to(self.pristine_upstream_branch.tags)
791
735
mutter("Not checking for upstream as it is a native package")
793
737
mutter("Not importing the upstream part as it is already "
794
738
"present in the upstream branch")
796
def get_parents_with_upstream(self, version, versions,
797
force_upstream_parent=False):
740
def get_parents_with_upstream(self, package, version, versions,
741
tarballs, force_upstream_parent=False):
798
742
"""Get the list of parents including any upstream parents.
800
744
Further to get_parents this method includes any upstream parents
843
788
# Make sure we see any revisions added by the upstream branch
844
789
# since self.tree was locked.
845
790
self.branch.repository.refresh_data()
846
self.branch.fetch(self.upstream_branch, last_revision=revid)
847
self.upstream_branch.tags.merge_to(self.branch.tags)
791
self.branch.fetch(self.pristine_upstream_branch, last_revision=revid)
792
self.pristine_upstream_branch.tags.merge_to(self.branch.tags)
849
def import_upstream(self, upstream_part, version, md5, upstream_parents,
850
upstream_tarball=None, upstream_branch=None,
794
def import_upstream(self, upstream_part, package, version, upstream_parents,
795
upstream_tarballs, upstream_branch=None,
851
796
upstream_revision=None, timestamp=None, author=None,
852
797
file_ids_from=None):
853
798
"""Import an upstream part on to the upstream branch.
872
816
assert isinstance(version, str)
873
817
mutter("Importing upstream version %s from %s with parents %s" \
874
818
% (version, upstream_part, str(upstream_parents)))
875
assert self.upstream_tree is not None, \
819
assert self.pristine_upstream_tree is not None, \
876
820
"Can't import upstream with no tree"
877
if len(upstream_parents) > 0:
878
parent_revid = upstream_parents[0]
880
parent_revid = NULL_REVISION
881
self.upstream_tree.pull(self.upstream_tree.branch, overwrite=True,
882
stop_revision=parent_revid)
883
821
other_branches = self.get_other_branches()
884
def get_last_revision_tree(br):
885
return br.repository.revision_tree(br.last_revision())
886
upstream_trees = [get_last_revision_tree(o.upstream_branch)
887
for o in other_branches]
889
if upstream_branch is not None:
890
if upstream_revision is None:
891
upstream_revision = upstream_branch.last_revision()
892
self.upstream_branch.fetch(upstream_branch,
893
last_revision=upstream_revision)
894
upstream_branch.tags.merge_to(self.upstream_branch.tags)
895
upstream_parents.append(upstream_revision)
896
target_tree = self.upstream_branch.repository.revision_tree(
898
if file_ids_from is not None:
899
upstream_trees = file_ids_from + upstream_trees
901
self_tree = self.tree
902
self_tree.lock_write() # might also be upstream tree for dh_make
904
self_tree = self.get_branch_tip_revtree()
905
self_tree.lock_read()
907
import_dir(self.upstream_tree, upstream_part,
908
file_ids_from=[self_tree] + upstream_trees,
909
target_tree=target_tree)
912
self.upstream_tree.set_parent_ids(upstream_parents)
913
revprops = {"deb-md5": md5}
914
if upstream_tarball is not None:
915
delta = self.make_pristine_tar_delta(
916
self.upstream_tree, upstream_tarball)
917
uuencoded = standard_b64encode(delta)
918
if upstream_tarball.endswith(".tar.bz2"):
919
revprops["deb-pristine-delta-bz2"] = uuencoded
921
revprops["deb-pristine-delta"] = uuencoded
922
if author is not None:
923
revprops['authors'] = author
925
if timestamp is not None:
926
timezone = timestamp[1]
927
timestamp = timestamp[0]
928
revid = self.upstream_tree.commit("Import upstream version %s" \
930
revprops=revprops, timestamp=timestamp, timezone=timezone)
931
tag_name, _ = self.tag_upstream_version(version, revid=revid)
932
return tag_name, revid
823
for (tarball, component, md5) in upstream_tarballs:
824
upstream_trees = [o.pristine_upstream_branch.basis_tree()
825
for o in other_branches]
827
if upstream_branch is not None:
828
if upstream_revision is None:
829
upstream_revision = upstream_branch.last_revision()
830
self.pristine_upstream_branch.fetch(upstream_branch,
831
last_revision=upstream_revision)
832
upstream_branch.tags.merge_to(self.pristine_upstream_branch.tags)
833
upstream_parents.append(upstream_revision)
834
target_tree = self.pristine_upstream_branch.repository.revision_tree(
836
if file_ids_from is not None:
837
upstream_trees = file_ids_from + upstream_trees
839
self_tree = self.tree
840
self_tree.lock_write() # might also be upstream tree for dh_make
842
self_tree = self.branch.basis_tree()
843
self_tree.lock_read()
844
if len(upstream_parents) > 0:
845
parent_revid = upstream_parents[0]
847
parent_revid = NULL_REVISION
848
self.pristine_upstream_tree.pull(self.pristine_upstream_tree.branch,
849
overwrite=True, stop_revision=parent_revid)
850
if component is None:
853
path = os.path.join(upstream_part, component)
855
import_dir(self.pristine_upstream_tree, path,
856
file_ids_from=[self_tree] + upstream_trees,
857
target_tree=target_tree)
860
(tag, revid) = self.pristine_upstream_source.import_component_tarball(
861
package, version, self.pristine_upstream_tree, upstream_parents, component,
862
md5, tarball, author=author, timestamp=timestamp)
863
ret.append((component, tag, revid))
864
self.branch.fetch(self.pristine_upstream_branch)
865
self.branch.tags.set_tag(tag, revid)
934
def import_upstream_tarball(self, tarball_filename, version, parents,
935
md5sum=None, upstream_branch=None, upstream_revision=None):
868
def import_upstream_tarballs(self, tarballs, package, version, parents,
869
upstream_branch=None, upstream_revision=None):
936
870
"""Import an upstream part to the upstream branch.
938
:param tarball_filename: The tarball to import.
872
:param tarballs: List of tarballs / components to extract
939
873
:param version: The upstream version to import.
940
874
:param parents: The tarball-branch parents to use for the import.
941
875
If an upstream branch is supplied, its automatically added to
945
879
:param upstream_revision: Upstream revision id
946
880
:param md5sum: hex digest of the md5sum of the tarball, if known.
947
:return: (tag_name, revision_id) of the imported tarball.
881
:return: list with (component, tag, revid) tuples
950
md5sum = md5sum_filename(tarball_filename)
951
tarball_dir = self._extract_tarball_to_tempdir(tarball_filename)
883
tarball_dir = self._extract_tarballs_to_tempdir(tarballs)
953
return self.import_upstream(tarball_dir, version, md5sum, parents,
954
upstream_tarball=tarball_filename,
885
return self.import_upstream(tarball_dir, package, version, parents,
955
887
upstream_branch=upstream_branch,
956
888
upstream_revision=upstream_revision)
958
890
shutil.rmtree(tarball_dir)
960
def get_branch_tip_revtree(self):
961
return self.branch.repository.revision_tree(
962
self.branch.last_revision())
964
892
def _mark_native_config(self, native):
965
poss_native_tree = self.get_branch_tip_revtree()
893
poss_native_tree = self.branch.basis_tree()
966
894
current_native = self._is_tree_native(poss_native_tree)
967
895
current_config = self._default_config_for_tree(poss_native_tree)
968
dirname = os.path.join(self.tree.basedir,
896
dirname = os.path.join(self.tree.basedir, '.bzr-builddeb')
970
897
if current_config is not None:
971
898
# Add that back to the current tree
972
899
if not os.path.exists(dirname):
1127
1052
pull_branch = pull_parents[1][0]
1128
1053
pull_version = pull_parents[1][1]
1129
1054
if not pull_branch.is_version_native(pull_version):
1131
pull_branch.revid_of_upstream_version(pull_version.upstream_version)
1132
mutter("Initialising upstream from %s, version %s" \
1133
% (str(pull_branch), str(pull_version)))
1134
parents.append(pull_revid)
1135
self.upstream_branch.fetch(
1136
pull_branch.upstream_branch,
1137
last_revision=pull_revid)
1138
pull_branch.upstream_branch.tags.merge_to(
1139
self.upstream_branch.tags)
1055
pull_revid = pull_branch.pristine_upstream_source.version_as_revision(
1056
package, pull_version.upstream_version)
1057
mutter("Initialising upstream from %s, version %s",
1058
str(pull_branch), str(pull_version))
1059
parents.append(pull_revid)
1060
self.pristine_upstream_branch.fetch(
1061
pull_branch.pristine_upstream_branch,
1062
last_revision=pull_revid)
1063
pull_branch.pristine_upstream_branch.tags.merge_to(
1064
self.pristine_upstream_branch.tags)
1142
1067
def get_changelog_from_source(self, dir):
1145
1070
cl.parse_changelog(open(cl_filename).read(), strict=False)
1148
def _do_import_package(self, version, versions, debian_part, md5,
1149
upstream_part, upstream_md5, upstream_tarball=None,
1150
timestamp=None, author=None, file_ids_from=None,
1073
def _import_normal_package(self, package, version, versions, debian_part, md5,
1074
upstream_part, upstream_tarballs, timestamp=None, author=None,
1075
file_ids_from=None, pull_debian=True):
1076
"""Import a source package.
1078
:param package: Package name
1079
:param version: Full Debian version
1080
:param versions: Safe versions from changelog
1081
:param debian_part: Path to extracted directory with Debian changes
1082
:param unextracted_debian_md5: MD5 sum of unextracted Debian diff/tarball
1083
:param upstream_part: Extracted upstream directory
1084
:param upstream_tarballs: List of tuples with (upstream tarfile, md5sum)
1085
:param timestamp: Version timestamp according to changelog
1086
:param author: Author according to changelog
1087
:param file_ids_from: Sequence of trees to take file ids from
1088
:param pull_debian: Whether to pull from the Debian branch
1152
1090
pull_branch = None
1153
1091
if pull_debian:
1154
1092
pull_branch = self.branch_to_pull_version_from(version, md5)
1155
1093
if pull_branch is not None:
1156
if (self.branch_to_pull_upstream_from(version.upstream_version,
1094
if (self.branch_to_pull_upstream_from(package,
1095
version.upstream_version, upstream_tarballs)
1159
1097
pull_branch = None
1160
1098
if pull_branch is not None:
1161
self.pull_version_from_branch(pull_branch, version)
1099
self.pull_version_from_branch(pull_branch, package, version)
1163
1101
# We need to import at least the diff, possibly upstream.
1164
1102
# Work out if we need the upstream part first.
1165
1103
imported_upstream = False
1166
if not self.has_upstream_version(version.upstream_version):
1104
if not self.pristine_upstream_source.has_version(package,
1105
version.upstream_version):
1167
1106
up_pull_branch = \
1168
self.branch_to_pull_upstream_from(version.upstream_version,
1107
self.branch_to_pull_upstream_from(package, version.upstream_version,
1170
1109
if up_pull_branch is not None:
1171
1110
self.pull_upstream_from_branch(up_pull_branch,
1172
version.upstream_version)
1111
package, version.upstream_version)
1174
1113
imported_upstream = True
1175
1114
# Check whether we should pull first if this initialises
1176
1115
# from another branch:
1177
upstream_parents = self.upstream_parents(versions,
1116
upstream_parents = self.upstream_parents(package, versions,
1178
1117
version.upstream_version)
1179
_, new_revid = self.import_upstream(upstream_part,
1180
version.upstream_version,
1181
upstream_md5, upstream_parents,
1182
upstream_tarball=upstream_tarball,
1118
for (component, tag, revid) in self.import_upstream(upstream_part,
1119
package, version.upstream_version,
1121
upstream_tarballs=upstream_tarballs,
1183
1122
timestamp=timestamp, author=author,
1184
file_ids_from=file_ids_from)
1185
self._fetch_upstream_to_branch(new_revid)
1123
file_ids_from=file_ids_from):
1124
self._fetch_upstream_to_branch(revid)
1187
1126
mutter("We already have the needed upstream part")
1188
parents = self.get_parents_with_upstream(version, versions,
1189
force_upstream_parent=imported_upstream)
1127
parents = self.get_parents_with_upstream(package, version, versions,
1128
upstream_tarballs, force_upstream_parent=imported_upstream)
1190
1129
# Now we have the list of parents we need to import the .diff.gz
1191
1130
self.import_debian(debian_part, version, parents, md5,
1192
1131
timestamp=timestamp, file_ids_from=file_ids_from)
1221
1160
branch.branch.tags.merge_to(self.branch.tags)
1222
1161
self.branch.fetch(branch.branch,
1223
1162
last_revision=revid)
1224
if self.upstream_branch.last_revision() == NULL_REVISION:
1225
self.upstream_tree.pull(branch.upstream_branch)
1226
branch.upstream_branch.tags.merge_to(self.upstream_branch.tags)
1163
if self.pristine_upstream_branch.last_revision() == NULL_REVISION:
1164
self.pristine_upstream_tree.pull(branch.pristine_upstream_branch)
1165
branch.pristine_upstream_branch.tags.merge_to(self.pristine_upstream_branch.tags)
1227
1166
if (self.branch.last_revision() != NULL_REVISION
1228
1167
and not self.branch.last_revision() in parents):
1229
1168
parents.insert(0, self.branch.last_revision())
1232
def _import_native_package(self, version, versions, debian_part, md5,
1171
def _import_native_package(self, package, version, versions, debian_part, md5,
1233
1172
timestamp=None, file_ids_from=None, pull_debian=True):
1234
1173
pull_branch = None
1235
1174
if pull_debian:
1236
1175
pull_branch = self.branch_to_pull_version_from(version, md5)
1237
1176
if pull_branch is not None:
1238
self.pull_version_from_branch(pull_branch, version, native=True)
1177
self.pull_version_from_branch(pull_branch, package, version, native=True)
1240
1179
parents = self.get_native_parents(version, versions)
1241
1180
self.import_debian(debian_part, version, parents, md5,
1287
1226
#TODO: check that the versions list is correctly ordered,
1288
1227
# as some methods assume that, and it's not clear what
1289
1228
# should happen if it isn't.
1290
1230
if extractor.extracted_upstream is not None:
1291
self._do_import_package(version, versions,
1231
self._import_normal_package(dsc['Source'], version, versions,
1292
1232
extractor.extracted_debianised,
1293
1233
extractor.unextracted_debian_md5,
1294
1234
extractor.extracted_upstream,
1295
extractor.unextracted_upstream_md5,
1296
upstream_tarball=extractor.unextracted_upstream,
1235
extractor.upstream_tarballs,
1297
1236
timestamp=timestamp, author=author,
1298
1237
file_ids_from=file_ids_from,
1299
1238
pull_debian=pull_debian)
1301
self._import_native_package(version, versions,
1240
self._import_native_package(dsc['Source'], version, versions,
1302
1241
extractor.extracted_debianised,
1303
1242
extractor.unextracted_debian_md5,
1304
1243
timestamp=timestamp, file_ids_from=file_ids_from,
1313
1252
# TODO: remove the _extract_upstream_tree alias below.
1314
1253
to_location = os.path.join(basedir, "upstream")
1315
1254
# Use upstream_branch if it has been set, otherwise self.branch.
1316
source_branch = self.upstream_branch or self.branch
1255
source_branch = self.pristine_upstream_branch or self.branch
1317
1256
dir_to = source_branch.bzrdir.sprout(to_location,
1318
1257
revision_id=upstream_tip,
1319
1258
accelerator_tree=self.tree)
1321
self.upstream_tree = dir_to.open_workingtree()
1260
self.pristine_upstream_tree = dir_to.open_workingtree()
1322
1261
except NoWorkingTree:
1323
1262
# Handle shared treeless repo's.
1324
self.upstream_tree = dir_to.create_workingtree()
1325
self.upstream_branch = self.upstream_tree.branch
1263
self.pristine_upstream_tree = dir_to.create_workingtree()
1264
self.pristine_upstream_branch = self.pristine_upstream_tree.branch
1327
1266
_extract_upstream_tree = extract_upstream_tree
1347
1286
branch = existing_bzrdir.create_branch()
1348
1287
existing_bzrdir.create_workingtree()
1349
self.upstream_branch = branch
1350
self.upstream_tree = branch.bzrdir.open_workingtree()
1288
self.pristine_upstream_branch = branch
1289
self.pristine_upstream_tree = branch.bzrdir.open_workingtree()
1352
1291
root_id = self.tree.path2id('')
1354
tip = self.get_branch_tip_revtree()
1293
tip = self.branch.basis_tree()
1355
1294
tip.lock_read()
1357
1296
root_id = tip.path2id('')
1361
self.upstream_tree.set_root_id(root_id)
1300
self.pristine_upstream_tree.set_root_id(root_id)
1363
def _extract_tarball_to_tempdir(self, tarball_filename):
1302
def _extract_tarballs_to_tempdir(self, tarballs):
1364
1303
tempdir = tempfile.mkdtemp()
1365
if tarball_filename.endswith(".tar.bz2"):
1370
proc = subprocess.Popen(["tar", tar_args, tarball_filename, "-C",
1371
tempdir, "--strip-components", "1"],
1372
preexec_fn=subprocess_setup)
1374
if proc.returncode != 0:
1375
raise TarFailed("extract", tarball_filename)
1305
extract_orig_tarballs(
1306
[(fn, component) for (fn, component, md5) in tarballs],
1307
tempdir, strip_components=1)
1378
1310
shutil.rmtree(tempdir)
1381
def _export_previous_upstream_tree(self, package, previous_version, tempdir, upstream_branch=None):
1313
def _export_previous_upstream_tree(self, package, previous_version, tempdir):
1382
1314
assert isinstance(previous_version, str), \
1383
1315
"Should pass upstream version as str, not Version."
1384
if self.pristine_tar_source.has_version(package, previous_version):
1385
upstream_tip = self.pristine_tar_source.version_as_revision(
1317
upstream_tip = self.pristine_upstream_source.version_as_revision(
1386
1318
package, previous_version)
1387
self.extract_upstream_tree(upstream_tip, tempdir)
1388
elif self.upstream_source is not None:
1389
upstream_tip = self.upstream_source.version_as_revision(package, previous_version)
1390
self.extract_upstream_tree(upstream_tip, tempdir)
1319
except PackageVersionNotPresent:
1392
1320
raise BzrCommandError("Unable to find the tag for the "
1393
1321
"previous upstream version, %s, in the branch: "
1395
1323
previous_version,
1396
self.pristine_tar_source.tag_name(previous_version)))
1324
self.pristine_upstream_source.tag_name(previous_version)))
1325
self.extract_upstream_tree(upstream_tip, tempdir)
1398
def merge_upstream(self, tarball_filename, package, version, previous_version,
1327
def merge_upstream(self, tarball_filenames, package, version, previous_version,
1399
1328
upstream_branch=None, upstream_revision=None, merge_type=None,
1401
assert self.upstream_branch is None, \
1402
"Should use self.upstream_branch if set"
1403
1330
assert isinstance(version, str), \
1404
1331
"Should pass version as str not %s" % str(type(version))
1405
1332
assert isinstance(previous_version, str) or previous_version is None, \
1425
1351
if not force and graph.is_ancestor(upstream_revision,
1426
1352
self.branch.last_revision()):
1427
1353
raise UpstreamBranchAlreadyMerged
1428
tarball_filename = os.path.abspath(tarball_filename)
1429
md5sum = md5sum_filename(tarball_filename)
1430
tarball_dir = self._extract_tarball_to_tempdir(tarball_filename)
1354
upstream_tarballs = [
1355
(os.path.abspath(fn), component, md5sum_filename(fn)) for
1358
tarball_dir = self._extract_tarballs_to_tempdir(upstream_tarballs)
1432
1360
# FIXME: should use upstream_parents()?
1434
if self.upstream_branch.last_revision() != NULL_REVISION:
1435
parents = [self.upstream_branch.last_revision()]
1436
_, new_revid = self.import_upstream(tarball_dir,
1438
md5sum, parents, upstream_tarball=tarball_filename,
1362
if self.pristine_upstream_branch.last_revision() != NULL_REVISION:
1363
parents = [self.pristine_upstream_branch.last_revision()]
1364
for (component, tag, revid) in self.import_upstream(tarball_dir,
1365
package, version, parents, upstream_tarballs=upstream_tarballs,
1439
1366
upstream_branch=upstream_branch,
1440
upstream_revision=upstream_revision)
1441
self._fetch_upstream_to_branch(new_revid)
1367
upstream_revision=upstream_revision):
1368
self._fetch_upstream_to_branch(revid)
1443
1370
shutil.rmtree(tarball_dir)
1444
1371
if self.branch.last_revision() != NULL_REVISION:
1446
1373
conflicts = self.tree.merge_from_branch(
1447
self.upstream_branch, merge_type=merge_type)
1374
self.pristine_upstream_branch, merge_type=merge_type)
1448
1375
except UnrelatedBranches:
1449
1376
# Bug lp:515367 where the first upstream tarball is
1450
1377
# missing a proper history link and a criss-cross merge
1523
1448
self.unextracted_debian_md5 = part['md5sum']
1525
1450
if part['name'].endswith(".orig.tar.gz"):
1526
assert self.unextracted_upstream is None, "Two .orig.tar.gz?"
1527
self.unextracted_upstream = os.path.abspath(
1451
self.upstream_tarballs.append((os.path.abspath(
1528
1452
os.path.join(osutils.dirname(self.dsc_path),
1530
self.unextracted_upstream_md5 = part['md5sum']
1454
component_from_orig_tarball(part['name'], name, str(version.upstream_version)),
1531
1456
elif part['name'].endswith(".diff.gz"):
1532
1457
self.unextracted_debian_md5 = part['md5sum']
1535
if os.path.exists(self.tempdir):
1536
shutil.rmtree(self.tempdir)
1539
1460
class ThreeDotZeroNativeSourceExtractor(SourceExtractor):
1461
"""Source extractor for the "3.0 (native)" source format."""
1541
1463
def extract(self):
1542
1464
self.tempdir = tempfile.mkdtemp()
1588
1512
subprocess.call(["find", self.extracted_debianised, "-perm",
1589
1513
"0000", "-exec", "chmod", "644", "{}", ";"])
1590
1514
for part in self.dsc['files']:
1591
if (re.search("\.orig-[^.]+\.tar\.(gz|bz2|lzma)$", part['name'])):
1592
raise AssertionError("Can't import packages with multiple "
1593
"upstream tarballs yet")
1594
if (part['name'].endswith(".orig.tar.gz")
1595
or part['name'].endswith(".orig.tar.bz2")):
1596
assert self.unextracted_upstream is None, "Two .orig.tar.(gz|bz2)?"
1597
self.unextracted_upstream = os.path.abspath(
1515
if part['name'].startswith("%s_%s.orig" % (name, str(version.upstream_version))):
1516
self.upstream_tarballs.append((os.path.abspath(
1598
1517
os.path.join(osutils.dirname(self.dsc_path),
1600
self.unextracted_upstream_md5 = part['md5sum']
1518
part['name'])), part['md5sum']))
1601
1519
elif (part['name'].endswith(".debian.tar.gz")
1602
or part['name'].endswith(".debian.tar.bz2")):
1520
or part['name'].endswith(".debian.tar.bz2")
1521
or part['name'].endswith(".debian.tar.lzma")):
1603
1522
self.unextracted_debian_md5 = part['md5sum']
1604
assert self.unextracted_upstream is not None, \
1605
"Can't handle non gz|bz2 tarballs yet"
1523
assert self.upstream_tarballs is not None, \
1524
"Can't handle non gz|bz2|lzma tarballs yet"
1606
1525
assert self.unextracted_debian_md5 is not None, \
1607
"Can't handle non gz|bz2 tarballs yet"
1526
"Can't handle non gz|bz2|lzma tarballs yet"
1610
1529
SOURCE_EXTRACTORS = {}
1611
SOURCE_EXTRACTORS["1.0"] = SourceExtractor
1530
SOURCE_EXTRACTORS[FORMAT_1_0] = OneZeroSourceExtractor
1612
1531
SOURCE_EXTRACTORS[FORMAT_3_0_NATIVE] = ThreeDotZeroNativeSourceExtractor
1613
1532
SOURCE_EXTRACTORS[FORMAT_3_0_QUILT] = ThreeDotZeroQuiltSourceExtractor