git.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # ex:ts=4:sw=4:sts=4:et
  2. # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
  3. """
  4. BitBake 'Fetch' git implementation
  5. """
  6. #Copyright (C) 2005 Richard Purdie
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License version 2 as
  10. # published by the Free Software Foundation.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. import os, re
  21. import bb
  22. from bb import data
  23. from bb.fetch import Fetch
  24. from bb.fetch import FetchError
  25. from bb.fetch import runfetchcmd
  26. class Git(Fetch):
  27. """Class to fetch a module or modules from git repositories"""
  28. def supports(self, url, ud, d):
  29. """
  30. Check to see if a given url can be fetched with git.
  31. """
  32. return ud.type in ['git']
  33. def localpath(self, url, ud, d):
  34. ud.proto = "rsync"
  35. if 'protocol' in ud.parm:
  36. ud.proto = ud.parm['protocol']
  37. ud.branch = ud.parm.get("branch", "master")
  38. tag = Fetch.srcrev_internal_helper(ud, d)
  39. if tag is True:
  40. ud.tag = self.latest_revision(url, ud, d)
  41. elif tag:
  42. ud.tag = tag
  43. if not ud.tag:
  44. ud.tag = self.latest_revision(url, ud, d)
  45. if ud.tag == "master":
  46. ud.tag = self.latest_revision(url, ud, d)
  47. ud.localfile = data.expand('git_%s%s_%s.tar.gz' % (ud.host, ud.path.replace('/', '.'), ud.tag), d)
  48. return os.path.join(data.getVar("DL_DIR", d, True), ud.localfile)
  49. def go(self, loc, ud, d):
  50. """Fetch url"""
  51. if Fetch.try_mirror(d, ud.localfile):
  52. bb.msg.debug(1, bb.msg.domain.Fetcher, "%s already exists (or was stashed). Skipping git checkout." % ud.localpath)
  53. return
  54. gitsrcname = '%s%s' % (ud.host, ud.path.replace('/', '.'))
  55. repofilename = 'git_%s.tar.gz' % (gitsrcname)
  56. repofile = os.path.join(data.getVar("DL_DIR", d, 1), repofilename)
  57. repodir = os.path.join(data.expand('${GITDIR}', d), gitsrcname)
  58. coname = '%s' % (ud.tag)
  59. codir = os.path.join(repodir, coname)
  60. if not os.path.exists(repodir):
  61. if Fetch.try_mirror(d, repofilename):
  62. bb.mkdirhier(repodir)
  63. os.chdir(repodir)
  64. runfetchcmd("tar -xzf %s" % (repofile), d)
  65. else:
  66. runfetchcmd("git clone -n %s://%s%s %s" % (ud.proto, ud.host, ud.path, repodir), d)
  67. os.chdir(repodir)
  68. # Remove all but the .git directory
  69. runfetchcmd("rm * -Rf", d)
  70. runfetchcmd("git fetch %s://%s%s %s" % (ud.proto, ud.host, ud.path, ud.branch), d)
  71. runfetchcmd("git fetch --tags %s://%s%s" % (ud.proto, ud.host, ud.path), d)
  72. runfetchcmd("git prune-packed", d)
  73. runfetchcmd("git pack-redundant --all | xargs -r rm", d)
  74. os.chdir(repodir)
  75. mirror_tarballs = data.getVar("BB_GENERATE_MIRROR_TARBALLS", d, True)
  76. if mirror_tarballs != "0":
  77. bb.msg.note(1, bb.msg.domain.Fetcher, "Creating tarball of git repository")
  78. runfetchcmd("tar -czf %s %s" % (repofile, os.path.join(".", ".git", "*") ), d)
  79. if os.path.exists(codir):
  80. bb.utils.prunedir(codir)
  81. bb.mkdirhier(codir)
  82. os.chdir(repodir)
  83. runfetchcmd("git read-tree %s" % (ud.tag), d)
  84. runfetchcmd("git checkout-index -q -f --prefix=%s -a" % (os.path.join(codir, "git", "")), d)
  85. os.chdir(codir)
  86. bb.msg.note(1, bb.msg.domain.Fetcher, "Creating tarball of git checkout")
  87. runfetchcmd("tar -czf %s %s" % (ud.localpath, os.path.join(".", "*") ), d)
  88. os.chdir(repodir)
  89. bb.utils.prunedir(codir)
  90. def suppports_srcrev(self):
  91. return True
  92. def _revision_key(self, url, ud, d):
  93. """
  94. Return a unique key for the url
  95. """
  96. return "git:" + ud.host + ud.path.replace('/', '.')
  97. def _latest_revision(self, url, ud, d):
  98. """
  99. Compute the HEAD revision for the url
  100. """
  101. output = runfetchcmd("git ls-remote %s://%s%s %s" % (ud.proto, ud.host, ud.path, ud.branch), d, True)
  102. return output.split()[0]
  103. def _build_revision(self, url, ud, d):
  104. return ud.tag