blob: 3e0a18182183aae9f6424c5254d131e27b24e70b [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# Copyright (C) 2006 OpenedHand LTD
2
3# Point to an empty file so any user's custom settings don't break things
4QUILTRCFILE ?= "${STAGING_ETCDIR_NATIVE}/quiltrc"
5
6PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_sysroot"
7
Patrick Williamsc0f7c042017-02-23 20:41:17 -06008PATCH_GIT_USER_NAME ?= "OpenEmbedded"
9PATCH_GIT_USER_EMAIL ?= "oe.patch@oe"
10
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011inherit terminal
12
Brad Bishop6e60e8b2018-02-01 10:27:11 -050013python () {
14 if d.getVar('PATCHTOOL') == 'git' and d.getVar('PATCH_COMMIT_FUNCTIONS') == '1':
15 extratasks = bb.build.tasksbetween('do_unpack', 'do_patch', d)
16 try:
17 extratasks.remove('do_unpack')
18 except ValueError:
19 # For some recipes do_unpack doesn't exist, ignore it
20 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -050021
Brad Bishop6e60e8b2018-02-01 10:27:11 -050022 d.appendVarFlag('do_patch', 'prefuncs', ' patch_task_patch_prefunc')
23 for task in extratasks:
24 d.appendVarFlag(task, 'postfuncs', ' patch_task_postfunc')
25}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050026
Brad Bishop6e60e8b2018-02-01 10:27:11 -050027python patch_task_patch_prefunc() {
28 # Prefunc for do_patch
Brad Bishop6e60e8b2018-02-01 10:27:11 -050029 srcsubdir = d.getVar('S')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050030
Brad Bishop316dfdd2018-06-25 12:45:53 -040031 workdir = os.path.abspath(d.getVar('WORKDIR'))
32 testsrcdir = os.path.abspath(srcsubdir)
33 if (testsrcdir + os.sep).startswith(workdir + os.sep):
34 # Double-check that either workdir or S or some directory in-between is a git repository
35 found = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080036 while testsrcdir != workdir:
Brad Bishop316dfdd2018-06-25 12:45:53 -040037 if os.path.exists(os.path.join(testsrcdir, '.git')):
38 found = True
39 break
40 if testsrcdir == workdir:
41 break
42 testsrcdir = os.path.dirname(testsrcdir)
43 if not found:
44 bb.fatal('PATCHTOOL = "git" set for source tree that is not a git repository. Refusing to continue as that may result in commits being made in your metadata repository.')
45
Brad Bishop6e60e8b2018-02-01 10:27:11 -050046 patchdir = os.path.join(srcsubdir, 'patches')
47 if os.path.exists(patchdir):
48 if os.listdir(patchdir):
49 d.setVar('PATCH_HAS_PATCHES_DIR', '1')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050050 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050051 os.rmdir(patchdir)
52}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050053
Brad Bishop6e60e8b2018-02-01 10:27:11 -050054python patch_task_postfunc() {
55 # Prefunc for task functions between do_unpack and do_patch
56 import oe.patch
57 import shutil
58 func = d.getVar('BB_RUNTASK')
59 srcsubdir = d.getVar('S')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050060
Brad Bishop6e60e8b2018-02-01 10:27:11 -050061 if os.path.exists(srcsubdir):
62 if func == 'do_patch':
63 haspatches = (d.getVar('PATCH_HAS_PATCHES_DIR') == '1')
64 patchdir = os.path.join(srcsubdir, 'patches')
65 if os.path.exists(patchdir):
66 shutil.rmtree(patchdir)
67 if haspatches:
68 stdout, _ = bb.process.run('git status --porcelain patches', cwd=srcsubdir)
69 if stdout:
70 bb.process.run('git checkout patches', cwd=srcsubdir)
71 stdout, _ = bb.process.run('git status --porcelain .', cwd=srcsubdir)
72 if stdout:
73 useroptions = []
74 oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=d)
75 bb.process.run('git add .; git %s commit -a -m "Committing changes from %s\n\n%s"' % (' '.join(useroptions), func, oe.patch.GitApplyTree.ignore_commit_prefix + ' - from %s' % func), cwd=srcsubdir)
76}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050077
Brad Bishop6e60e8b2018-02-01 10:27:11 -050078def src_patches(d, all=False, expand=True):
79 import oe.patch
80 return oe.patch.src_patches(d, all, expand)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050081
82def should_apply(parm, d):
83 """Determine if we should apply the given patch"""
Brad Bishop6e60e8b2018-02-01 10:27:11 -050084 import oe.patch
85 return oe.patch.should_apply(parm, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050086
87should_apply[vardepsexclude] = "DATE SRCDATE"
88
89python patch_do_patch() {
90 import oe.patch
91
92 patchsetmap = {
93 "patch": oe.patch.PatchTree,
94 "quilt": oe.patch.QuiltTree,
95 "git": oe.patch.GitApplyTree,
96 }
97
Brad Bishop6e60e8b2018-02-01 10:27:11 -050098 cls = patchsetmap[d.getVar('PATCHTOOL') or 'quilt']
Patrick Williamsc124f4f2015-09-15 14:41:29 -050099
100 resolvermap = {
101 "noop": oe.patch.NOOPResolver,
102 "user": oe.patch.UserResolver,
103 }
104
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500105 rcls = resolvermap[d.getVar('PATCHRESOLVE') or 'user']
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500106
107 classes = {}
108
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500109 s = d.getVar('S')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500110
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500111 os.putenv('PATH', d.getVar('PATH'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500112
113 # We must use one TMPDIR per process so that the "patch" processes
114 # don't generate the same temp file name.
115
116 import tempfile
117 process_tmpdir = tempfile.mkdtemp()
118 os.environ['TMPDIR'] = process_tmpdir
119
120 for patch in src_patches(d):
121 _, _, local, _, _, parm = bb.fetch.decodeurl(patch)
122
123 if "patchdir" in parm:
124 patchdir = parm["patchdir"]
125 if not os.path.isabs(patchdir):
126 patchdir = os.path.join(s, patchdir)
127 else:
128 patchdir = s
129
130 if not patchdir in classes:
131 patchset = cls(patchdir, d)
132 resolver = rcls(patchset, oe_terminal)
133 classes[patchdir] = (patchset, resolver)
134 patchset.Clean()
135 else:
136 patchset, resolver = classes[patchdir]
137
138 bb.note("Applying patch '%s' (%s)" % (parm['patchname'], oe.path.format_display(local, d)))
139 try:
140 patchset.Import({"file":local, "strippath": parm['striplevel']}, True)
141 except Exception as exc:
142 bb.utils.remove(process_tmpdir, True)
143 bb.fatal(str(exc))
144 try:
145 resolver.Resolve()
146 except bb.BBHandledException as e:
147 bb.utils.remove(process_tmpdir, True)
148 bb.fatal(str(e))
149
150 bb.utils.remove(process_tmpdir, True)
151 del os.environ['TMPDIR']
152}
153patch_do_patch[vardepsexclude] = "PATCHRESOLVE"
154
155addtask patch after do_unpack
156do_patch[dirs] = "${WORKDIR}"
157do_patch[depends] = "${PATCHDEPENDENCY}"
158
159EXPORT_FUNCTIONS do_patch