[PATCH 6/6] bb/fetch2: Improve runfetchcmd environment handling
Richard Purdie <[email protected]> Sun, 31 May 2026 19:27:43 +0100
| Newsgroups | org.openembedded.lists.bitbake-devel |
|---|---|
| Message-ID | <[email protected]> |
One of the reasons for using shell=True in runfetchcmd is due to environment manipulations. There are better ways to do this directly with subprocess' env parameter. Switch to doing this, paving the way for fewer shell=True process calls. Signed-off-by: Richard Purdie <[email protected]> --- lib/bb/fetch2/__init__.py | 12 ++++++++---- lib/bb/fetch2/git.py | 16 ++++++++-------- lib/bb/fetch2/svn.py | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/bb/fetch2/__init__.py b/lib/bb/fetch2/__init__.py index ce7456b60f1..564147603b5 100644 --- a/lib/bb/fetch2/__init__.py +++ b/lib/bb/fetch2/__init__.py @@ -933,7 +933,7 @@ def get_fetcher_environment(d): newenv[name] = value return newenv -def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None, workdir=None): +def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None, workdir=None, extraenv=None): """ Run cmd returning the command output Raise an error if interrupted or cmd fails @@ -958,13 +958,17 @@ def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None, workdir=None): d.setVar("PR", "fetcheravoidrecurse") origenv = d.getVar("BB_ORIGENV", False) + env = os.environ.copy() for var in exportvars: val = d.getVar(var) or (origenv and origenv.getVar(var)) if val: - cmd = 'export ' + var + '=\"%s\"; %s' % (val, cmd) + env[var] = val + + for var in (extraenv or []): + env[var] = extraenv[var] # Disable pseudo as it may affect ssh, potentially causing it to hang. - cmd = 'export PSEUDO_DISABLED=1; ' + cmd + env["PSEUDO_DISABLED"] = "1" if workdir: logger.debug("Running '%s' in %s" % (cmd, workdir)) @@ -975,7 +979,7 @@ def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None, workdir=None): error_message = "" try: - (output, errors) = bb.process.run(cmd, log=log, shell=True, stderr=subprocess.PIPE, cwd=workdir) + (output, errors) = bb.process.run(cmd, log=log, shell=True, stderr=subprocess.PIPE, cwd=workdir, env=env) success = True except bb.process.NotFoundError as e: error_message = "Fetch command %s not found" % (e.command) diff --git a/lib/bb/fetch2/git.py b/lib/bb/fetch2/git.py index d305eb878e8..793b3570b11 100644 --- a/lib/bb/fetch2/git.py +++ b/lib/bb/fetch2/git.py @@ -397,8 +397,8 @@ class Git(FetchMethod): if 'mirror' in output: runfetchcmd("%s remote rm mirror" % ud.basecmd, d, workdir=ud.clonedir) runfetchcmd("%s remote add --mirror=fetch mirror %s" % (ud.basecmd, tmpdir), d, workdir=ud.clonedir) - fetch_cmd = "LANG=C %s fetch -f --update-head-ok --progress mirror " % (ud.basecmd) - runfetchcmd(fetch_cmd, d, workdir=ud.clonedir) + fetch_cmd = "%s fetch -f --update-head-ok --progress mirror " % (ud.basecmd) + runfetchcmd(fetch_cmd, d, workdir=ud.clonedir, extraenv={'LANG':'C'}) repourl = self._get_repo_url(ud) needs_clone = False @@ -407,7 +407,7 @@ class Git(FetchMethod): # repository in which case it needs to be deleted and re-cloned. try: # Since clones can be bare, use --absolute-git-dir instead of --show-toplevel - output = runfetchcmd("LANG=C %s rev-parse --absolute-git-dir" % ud.basecmd, d, workdir=ud.clonedir) + output = runfetchcmd("%s rev-parse --absolute-git-dir" % ud.basecmd, d, workdir=ud.clonedir, extraenv={'LANG':'C'}) toplevel = output.rstrip() if not bb.utils.path_is_descendant(toplevel, ud.clonedir): @@ -434,7 +434,7 @@ class Git(FetchMethod): objects = os.path.join(repourl_path, 'objects') if os.path.isdir(objects) and not os.path.islink(objects): repourl = repourl_path - clone_cmd = "LANG=C %s clone --bare --mirror %s %s --progress" % (ud.basecmd, shlex.quote(repourl), ud.clonedir) + clone_cmd = "%s clone --bare --mirror %s %s --progress" % (ud.basecmd, shlex.quote(repourl), ud.clonedir) if ud.proto.lower() != 'file': bb.fetch2.check_network_access(d, clone_cmd, ud.url) progresshandler = GitProgressHandler(d) @@ -456,7 +456,7 @@ class Git(FetchMethod): # When skipping fast initial shallow or the fast inital shallow clone failed: # Try again with an initial regular clone - runfetchcmd(clone_cmd, d, log=progresshandler) + runfetchcmd(clone_cmd, d, log=progresshandler, extraenv={'LANG':'C'}) # Update the checkout if needed if self.clonedir_need_update(ud, d): @@ -467,13 +467,13 @@ class Git(FetchMethod): runfetchcmd("%s remote add --mirror=fetch origin %s" % (ud.basecmd, shlex.quote(repourl)), d, workdir=ud.clonedir) if ud.nobranch: - fetch_cmd = "LANG=C %s fetch -f --progress %s refs/*:refs/*" % (ud.basecmd, shlex.quote(repourl)) + fetch_cmd = "%s fetch -f --progress %s refs/*:refs/*" % (ud.basecmd, shlex.quote(repourl)) else: - fetch_cmd = "LANG=C %s fetch -f --progress %s refs/heads/*:refs/heads/* refs/tags/*:refs/tags/*" % (ud.basecmd, shlex.quote(repourl)) + fetch_cmd = "%s fetch -f --progress %s refs/heads/*:refs/heads/* refs/tags/*:refs/tags/*" % (ud.basecmd, shlex.quote(repourl)) if ud.proto.lower() != 'file': bb.fetch2.check_network_access(d, fetch_cmd, ud.url) progresshandler = GitProgressHandler(d) - runfetchcmd(fetch_cmd, d, log=progresshandler, workdir=ud.clonedir) + runfetchcmd(fetch_cmd, d, log=progresshandler, workdir=ud.clonedir, extraenv={'LANG':'C'}) runfetchcmd("%s repack -adk" % ud.basecmd, d, workdir=ud.clonedir) runfetchcmd("%s pack-refs --all" % ud.basecmd, d, workdir=ud.clonedir) runfetchcmd("%s prune-packed" % ud.basecmd, d, workdir=ud.clonedir) diff --git a/lib/bb/fetch2/svn.py b/lib/bb/fetch2/svn.py index a097ffb76b5..b5862139fac 100644 --- a/lib/bb/fetch2/svn.py +++ b/lib/bb/fetch2/svn.py @@ -193,7 +193,7 @@ class Svn(FetchMethod): """ bb.fetch2.check_network_access(d, self._buildsvncommand(ud, d, "log1"), ud.url) - output = runfetchcmd("LANG=C LC_ALL=C " + self._buildsvncommand(ud, d, "log1"), d, True) + output = runfetchcmd(self._buildsvncommand(ud, d, "log1"), d, True, extraenv={'LANG':'C', 'LC_ALL': 'C'}) # skip the first line, as per output of svn log # then we expect the revision on the 2nd line