From patchwork Wed Jun 3 10:48:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Purdie X-Patchwork-Id: 89236 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9BE99CD6E56 for ; Wed, 3 Jun 2026 10:48:48 +0000 (UTC) Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.17308.1780483724051804088 for ; Wed, 03 Jun 2026 03:48:44 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linuxfoundation.org header.s=google header.b=b9yXoBT2; spf=pass (domain: linuxfoundation.org, ip: 209.85.221.53, mailfrom: richard.purdie@linuxfoundation.org) Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-45eee266c6cso4814149f8f.1 for ; Wed, 03 Jun 2026 03:48:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; t=1780483722; x=1781088522; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=yN8PP+PwPUFHtfdql7jqiWpY1fTj4PKNEPJoWzQGI+o=; b=b9yXoBT23HmKguwJ0egdc16GPVfGkC1x06S3e78C4GDs30bOj6VKBn+vttprovnvEq h7E4VpLwcJcLlyh7aKJpWjNgle6sYDbOxkm/DqXodETLorW++0WI21kTNHPQAzhyLppX xhKlVbR6ILSJ+FhbplyVHbly9SVCgX1ne/aHA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780483722; x=1781088522; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=yN8PP+PwPUFHtfdql7jqiWpY1fTj4PKNEPJoWzQGI+o=; b=iglpti49I0KQxCTV0NgqY43AQGmS8xmainzRubeTW02vgg9qXGrWMDSmyzdFROL4fg cz/GHM4Xf0TD5f/3UzN2UQtSH/VloejRDEb51P1YmzfvtsixQO/5vN/mJ4JzbtQC0YZ7 H7oTwXnV5kTzbjBOXpSUnZYMLyyHuHgRkH4tJRm2tIhPMe/wtEBPfHdYJAEt4PusQ3yk d/xcaqIp0andso/g+iai5qlWOTUbPuv2k7SledBZtmLgGh/8LhRedTPRte94i6TjmbB5 //oMd9utYUDd2XeQR5/zg1GwQ6/7y7qAmT5vlxvLvzOzZWGc2Sg7wHo/UnZZHnfDuXek BV1Q== X-Gm-Message-State: AOJu0YytoFHR2BEIkWdcLbKUNgTZ2uLzrhL0yhBgaxOLWwCGPdNsJ3Jt JJhj7AyEnD4vJCd506NgpiLJ1JuTN+whEqra7k9M/w1srs8vNslmAWh9Sx8DX2TJH7pTWZCN/tR ltom0 X-Gm-Gg: Acq92OGR3FypS1ftt2MPkKvm1j1SzNqdfcVN1mGESTVpKkmrvPBWnue8gFT33wYBU73 gDsb4zKbAn3kChqkrDvkzqkTlpdW0DaQMn7sTgSIAQqrsy1E+oGRn3OyZcwFw/J500a+oxNa+lH r31d5lta6L57NfxJIDVKk6xN47K5peQLPIm40fAovPOYSDptE/6dLgoiouv9UCSkKwM0PfqcgYR p25WKsb9NfWKbi5LpTUpJQevfDQcvmxtRX+BioB3a/ynsiS89zRsdNteKaVCfbLqPqWGAomeEBW BIQTyN/eli6wvDCNTR1mbyYvOYPYw0cB/NbjxgvMimhN6ishiwLg+Rp+i3EbBZmGeHEEYIsvcZh qn1QqrnqsL5Lba+bqan4udh8Ek/dhockc44rfzk4fV2HilcVWRG2JJhCWTI7jkZdTvWKIsN6HQ0 HyBZGGd6uSgt4Qmzz1huCaDrsf7rsRf2gPVa/YLYlTh+wov9m4kpjvEBicxYdj3A== X-Received: by 2002:a05:6000:60a:b0:45e:f4f7:7cad with SMTP id ffacd0b85a97d-46021980b94mr3785972f8f.39.1780483722155; Wed, 03 Jun 2026 03:48:42 -0700 (PDT) Received: from max.int.rpsys.net ([2001:8b0:aba:5f3c:202c:df88:9261:8b8]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f35ee64sm8090759f8f.30.2026.06.03.03.48.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 03:48:41 -0700 (PDT) From: Richard Purdie To: bitbake-devel@lists.openembedded.org Subject: [PATCH 1/8] fetch2: Allow runfetchcmd to handle lists of command arguments Date: Wed, 3 Jun 2026 11:48:33 +0100 Message-ID: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 03 Jun 2026 10:48:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19594 We want to be able to pass lists of arguments into process.run(), to do this we need a way of avoding shell=True. Add such a codepath if the cmd is a list (not a string). Signed-off-by: Richard Purdie --- lib/bb/fetch2/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/bb/fetch2/__init__.py b/lib/bb/fetch2/__init__.py index 4234c62d0c8..e3b8f5787b1 100644 --- a/lib/bb/fetch2/__init__.py +++ b/lib/bb/fetch2/__init__.py @@ -979,7 +979,10 @@ def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None, workdir=None, extra error_message = "" try: - (output, errors) = bb.process.run(cmd, log=log, shell=True, stderr=subprocess.PIPE, cwd=workdir, env=env) + if isinstance(cmd, str): + (output, errors) = bb.process.run(cmd, log=log, shell=True, stderr=subprocess.PIPE, cwd=workdir, env=env) + else: + (output, errors) = bb.process.run(cmd, log=log, stderr=subprocess.PIPE, cwd=workdir, env=env) success = True except bb.process.NotFoundError as e: error_message = "Fetch command %s not found" % (e.command) From patchwork Wed Jun 3 10:48:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Purdie X-Patchwork-Id: 89237 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id BB85DCD6E64 for ; Wed, 3 Jun 2026 10:48:48 +0000 (UTC) Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.17309.1780483725406666004 for ; Wed, 03 Jun 2026 03:48:45 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linuxfoundation.org header.s=google header.b=Esz1L6pb; spf=pass (domain: linuxfoundation.org, ip: 209.85.221.46, mailfrom: richard.purdie@linuxfoundation.org) Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-45ef1629ff4so4059448f8f.0 for ; Wed, 03 Jun 2026 03:48:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; t=1780483724; x=1781088524; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=V+RbBiyaaIyLtlsP47vr0JIgt9sCNJ2P2wM6JRcTSMg=; b=Esz1L6pbHNpG/c1j2pP3haBWk8bCuk4qf0lNxA/AhyxA9EWN0EWwfOECX6pMb5HB1N fQFsYwh8Neg8nP69QxCYxYJ61pv/2FrQgQmAkOoMWC4uaxMXHEtJ8hXYMAkVXTIlqbF6 SXF93n0a2t70DyXWEPGxAGQT8yhgYkXAnVfWM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780483724; x=1781088524; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=V+RbBiyaaIyLtlsP47vr0JIgt9sCNJ2P2wM6JRcTSMg=; b=kgcxkG48K63WusFly7/39hzBWgrNBbY7L6GcGbZozpEuGqHoLqevInEYVCMzOPHg/Q AefUkJ/7XNQvo9OQhoN36d0ws1Var6WNMh2+RLFsTMI2utqvVxB2UDB/zubLe8yPMrz+ mqcB/pzUMBtuYmHbxX3vYZ9ezQ92CbyJ6/ydReOtPX7coRSqjtQyTKJHsXGxGWk8/Iqq SJPwoCKlzHGbmc6lxz6b0tqJbMlYGmjDnQaTxjqGy4+LNmzn8J/ZBUO0yWUYacaGqeUS A4suWbUIZLaNU0YGTBJti0SUzMnOuhkQnTiFWUQ52XweKk0ytc2/i1FKtScdk0IletAF V6DQ== X-Gm-Message-State: AOJu0YzWJp77QlhvyYOLfgSHsDq7D75R/L5C+mu5yT8PH3Pc4VWpp9ia KwV51fxOwCAwxpN0eqSbbH4C2NggKJx4FwdsU+dbrQR3uhqxYKiQ6aEyvfPFeIRuu2ABuJuWfZ4 7G7JG X-Gm-Gg: Acq92OHmUemhWx71NLbAmaGcuCXT22UMy0KFihpq4gdyCbAVjDev1aWvj55UDS7CFnz oqhRfAPF+dT/59q4xsca28RA/QTEa7isACTRW9Ofsx2sshCXo/IJ/F1IqpGPRAkUW8E24W84x6t linFMiGQmcSvAfjWZpFpfrAgzmR+XHQAA+6hwSqHVVZOAzzWoytEk69F9UDSnndDhpUVd3GwTUz McH2EYCDY4fyUarNIIUH2hpJT7+C4NDGiRV7ePdOFgBi9uu/qSgdpiY6Rvu7DB8jq/8HTyQKuUE cUQ9lEXkx64aPJ8xO/AgpT8K1+uYdeWsujTwS6SP1roGrwRg4RN6Ibmm/4EzbKFg77RJ0ctAf1e r20dsojcsE7aX8fymtcYEB48TorHC1WeXJUrF172ctifVSH4Ki7RrU9FSEhhq9SSEuyLZahFL5m Kd9LxGsoZ/onYEA0KuLm0bQKVl+d1cW23SavaepwbrA2tfoTwA3UitBHAr9FBKng== X-Received: by 2002:a05:600c:4ecc:b0:490:b724:dbd6 with SMTP id 5b1f17b1804b1-490b724dd8emr41797925e9.6.1780483723119; Wed, 03 Jun 2026 03:48:43 -0700 (PDT) Received: from max.int.rpsys.net ([2001:8b0:aba:5f3c:202c:df88:9261:8b8]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f35ee64sm8090759f8f.30.2026.06.03.03.48.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 03:48:42 -0700 (PDT) From: Richard Purdie To: bitbake-devel@lists.openembedded.org Subject: [PATCH 2/8] fetch/{git,gitannex,gitsm}: Convert to use lists of command arguments Date: Wed, 3 Jun 2026 11:48:34 +0100 Message-ID: <20260603104840.815399-2-richard.purdie@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> References: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 03 Jun 2026 10:48:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19595 To follow best practises and avoid shell=True subprocess usage, convert the fetcher commands to use lists instead of strings. This improves variable quoting and models modern coding standards. Some shell pipeline commands are adapted to aviod the pipelines. Environment variables are passed in separately using extraenv where needed. Signed-off-by: Richard Purdie --- lib/bb/fetch2/git.py | 174 ++++++++++++++++++-------------------- lib/bb/fetch2/gitannex.py | 18 ++-- lib/bb/fetch2/gitsm.py | 19 +++-- 3 files changed, 99 insertions(+), 112 deletions(-) diff --git a/lib/bb/fetch2/git.py b/lib/bb/fetch2/git.py index 793b3570b11..cd045a3a947 100644 --- a/lib/bb/fetch2/git.py +++ b/lib/bb/fetch2/git.py @@ -189,11 +189,11 @@ class Git(FetchMethod): ud.noshared = d.getVar("BB_GIT_NOSHARED") == "1" - ud.cloneflags = "-n" + ud.cloneflags = ["-n"] if not ud.noshared: - ud.cloneflags += " -s" + ud.cloneflags.append("-s") if ud.bareclone: - ud.cloneflags += " --mirror" + ud.cloneflags.append("--mirror") ud.shallow_skip_fast = False ud.shallow = d.getVar("BB_GIT_SHALLOW") == "1" @@ -249,6 +249,8 @@ class Git(FetchMethod): ud.basecmd = d.getVar("FETCHCMD_git") or "git -c gc.autoDetach=false -c core.pager=cat -c safe.bareRepository=all -c clone.defaultRemoteName=origin" + ud.basecmd = shlex.split(ud.basecmd) + write_tarballs = d.getVar("BB_GENERATE_MIRROR_TARBALLS") or "0" ud.write_tarballs = write_tarballs != "0" or ud.rebaseable ud.write_shallow_tarballs = (d.getVar("BB_GENERATE_SHALLOW_TARBALLS") or write_tarballs) != "0" @@ -340,7 +342,7 @@ class Git(FetchMethod): def clonedir_need_shallow_revs(self, ud, d): for rev in ud.shallow_revs: try: - runfetchcmd('%s rev-parse -q --verify %s' % (ud.basecmd, rev), d, quiet=True, workdir=ud.clonedir) + runfetchcmd(ud.basecmd + ['rev-parse', '-q', '--verify', rev], d, quiet=True, workdir=ud.clonedir) except bb.fetch2.FetchError: return rev return None @@ -389,15 +391,15 @@ class Git(FetchMethod): elif os.path.exists(ud.fullmirror) and self.need_update(ud, d): if not os.path.exists(ud.clonedir): bb.utils.mkdirhier(ud.clonedir) - runfetchcmd("tar -xzf %s" % ud.fullmirror, d, workdir=ud.clonedir) + runfetchcmd(['tar', '-xzf', ud.fullmirror], d, workdir=ud.clonedir) else: with tempfile.TemporaryDirectory(dir=d.getVar('DL_DIR')) as tmpdir: - runfetchcmd("tar -xzf %s" % ud.fullmirror, d, workdir=tmpdir) - output = runfetchcmd("%s remote" % ud.basecmd, d, quiet=True, workdir=ud.clonedir) + runfetchcmd(['tar', '-xzf', ud.fullmirror], d, workdir=tmpdir) + output = runfetchcmd(ud.basecmd + ['remote'], d, quiet=True, workdir=ud.clonedir) 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 = "%s fetch -f --update-head-ok --progress mirror " % (ud.basecmd) + runfetchcmd(ud.basecmd + ['remote', 'rm', 'mirror'], d, workdir=ud.clonedir) + runfetchcmd(ud.basecmd + ['remote', 'add', '--mirror=fetch', 'mirror', tmpdir], d, workdir=ud.clonedir) + fetch_cmd = ud.basecmd + ['fetch', '-f', '--update-head-ok', '--progress', 'mirror'] runfetchcmd(fetch_cmd, d, workdir=ud.clonedir, extraenv={'LANG':'C'}) repourl = self._get_repo_url(ud) @@ -407,7 +409,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("%s rev-parse --absolute-git-dir" % ud.basecmd, d, workdir=ud.clonedir, extraenv={'LANG':'C'}) + output = runfetchcmd(ud.basecmd + ['rev-parse', '--absolute-git-dir'], d, workdir=ud.clonedir, extraenv={'LANG':'C'}) toplevel = output.rstrip() if not bb.utils.path_is_descendant(toplevel, ud.clonedir): @@ -434,7 +436,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 = "%s clone --bare --mirror %s %s --progress" % (ud.basecmd, shlex.quote(repourl), ud.clonedir) + clone_cmd = ud.basecmd + ['clone', '--bare', '--mirror', repourl, ud.clonedir, '--progress'] if ud.proto.lower() != 'file': bb.fetch2.check_network_access(d, clone_cmd, ud.url) progresshandler = GitProgressHandler(d) @@ -460,23 +462,23 @@ class Git(FetchMethod): # Update the checkout if needed if self.clonedir_need_update(ud, d): - output = runfetchcmd("%s remote" % ud.basecmd, d, quiet=True, workdir=ud.clonedir) + output = runfetchcmd(ud.basecmd + ['remote'], d, quiet=True, workdir=ud.clonedir) if "origin" in output: - runfetchcmd("%s remote rm origin" % ud.basecmd, d, workdir=ud.clonedir) + runfetchcmd(ud.basecmd + ['remote', 'rm', 'origin'], d, workdir=ud.clonedir) - runfetchcmd("%s remote add --mirror=fetch origin %s" % (ud.basecmd, shlex.quote(repourl)), d, workdir=ud.clonedir) + runfetchcmd(ud.basecmd + ['remote', 'add', '--mirror=fetch', 'origin', repourl], d, workdir=ud.clonedir) if ud.nobranch: - fetch_cmd = "%s fetch -f --progress %s refs/*:refs/*" % (ud.basecmd, shlex.quote(repourl)) + fetch_cmd = ud.basecmd + ['fetch', '-f', '--progress', repourl, 'refs/*:refs/*'] else: - fetch_cmd = "%s fetch -f --progress %s refs/heads/*:refs/heads/* refs/tags/*:refs/tags/*" % (ud.basecmd, shlex.quote(repourl)) + fetch_cmd = ud.basecmd + ['fetch', '-f', '--progress', repourl, 'refs/heads/*:refs/heads/*', 'refs/tags/*:refs/tags/*'] 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, 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) + runfetchcmd(ud.basecmd + ['repack','-adk'], d, workdir=ud.clonedir) + runfetchcmd(ud.basecmd + ['pack-refs','--all'], d, workdir=ud.clonedir) + runfetchcmd(ud.basecmd + ['prune-packed'], d, workdir=ud.clonedir) try: os.unlink(ud.fullmirror) except OSError as exc: @@ -501,11 +503,11 @@ class Git(FetchMethod): self._ensure_git_lfs(d, ud) # Using worktree with the revision because .lfsconfig may exists - worktree_add_cmd = "%s worktree add wt %s" % (ud.basecmd, revision) + worktree_add_cmd = ud.basecmd + ['worktree', 'add', 'wt', revision] runfetchcmd(worktree_add_cmd, d, log=progresshandler, workdir=clonedir) - lfs_fetch_cmd = "%s lfs fetch %s" % (ud.basecmd, "--all" if fetchall else "") + lfs_fetch_cmd = ud.basecmd + ['lfs', 'fetch', "--all" if fetchall else ""] runfetchcmd(lfs_fetch_cmd, d, log=progresshandler, workdir=(clonedir + "/wt")) - worktree_rem_cmd = "%s worktree remove -f wt" % ud.basecmd + worktree_rem_cmd = ud.basecmd + ['worktree', 'remove', '-f', 'wt'] runfetchcmd(worktree_rem_cmd, d, log=progresshandler, workdir=clonedir) except: logger.warning("Fetching LFS did not succeed.") @@ -535,11 +537,10 @@ class Git(FetchMethod): logger.info("Creating tarball of git repository") with self.create_atomic(ud.fullmirror) as tfile: - mtime = runfetchcmd("{} log --all -1 --format=%cD".format(ud.basecmd), d, + mtime = runfetchcmd(ud.basecmd + ['log', '--all', '-1', '--format=%cD'], d, quiet=True, workdir=ud.clonedir) - runfetchcmd("tar -czf %s --owner oe:0 --group oe:0 --mtime \"%s\" ." - % (tfile, mtime), d, workdir=ud.clonedir) - runfetchcmd("touch %s.done" % ud.fullmirror, d) + runfetchcmd(['tar', '-czf', tfile, '--owner', 'oe:0', '--group', 'oe:0', '--mtime', mtime, '.'], d, workdir=ud.clonedir) + runfetchcmd(['touch', "%s.done" % ud.fullmirror], d) def clone_shallow_with_tarball(self, ud, d): for fast in [True, False]: @@ -555,8 +556,8 @@ class Git(FetchMethod): continue logger.info("Creating tarball of git repository") with self.create_atomic(ud.fullshallow) as tfile: - runfetchcmd("tar -czf %s ." % tfile, d, workdir=shallowclone) - runfetchcmd("touch %s.done" % ud.fullshallow, d) + runfetchcmd(['tar', '-czf', tfile, '.'], d, workdir=shallowclone) + runfetchcmd(['touch', '%s.done' % ud.fullshallow], d) return True return False @@ -570,9 +571,9 @@ class Git(FetchMethod): progresshandler = GitProgressHandler(d) repourl = self._get_repo_url(ud) bb.utils.mkdirhier(dest) - init_cmd = "%s init -q" % ud.basecmd + init_cmd = ud.basecmd + ['init', '-q'] if ud.bareclone: - init_cmd += " --bare" + init_cmd.append('--bare') runfetchcmd(init_cmd, d, workdir=dest) # Use repourl when creating a fast initial shallow clone # Prefer already existing full bare clones if available @@ -580,12 +581,12 @@ class Git(FetchMethod): remote = shlex.quote(repourl) else: remote = ud.clonedir - runfetchcmd("%s remote add origin %s" % (ud.basecmd, remote), d, workdir=dest) + runfetchcmd(ud.basecmd + ['remote', 'add', 'origin', remote], d, workdir=dest) # Check the histories which should be excluded - shallow_exclude = '' + shallow_exclude = [] for revision in ud.shallow_revs: - shallow_exclude += " --shallow-exclude=%s" % revision + shallow_exclude.append("--shallow-exclude=%s" % revision) revision = ud.revision depth = ud.shallow_depths[ud.name] @@ -605,9 +606,9 @@ class Git(FetchMethod): else: ref = "refs/remotes/origin/%s" % branch - fetch_cmd = "%s fetch origin %s" % (ud.basecmd, revision) + fetch_cmd = ud.basecmd + ['fetch', 'origin', revision] if depth: - fetch_cmd += " --depth %s" % depth + fetch_cmd += ['--depth', str(depth)] if shallow_exclude: fetch_cmd += shallow_exclude @@ -616,17 +617,17 @@ class Git(FetchMethod): # error: Server does not allow request for unadvertised object. # The ud.clonedir is a local temporary dir, will be removed when # fetch is done, so we can do anything on it. - adv_cmd = 'git branch -f advertise-%s %s' % (revision, revision) + adv_cmd = ['git', 'branch', '-f', 'advertise-' + revision, revision] if ud.shallow_skip_fast: runfetchcmd(adv_cmd, d, workdir=ud.clonedir) runfetchcmd(fetch_cmd, d, workdir=dest) - runfetchcmd("%s update-ref %s %s" % (ud.basecmd, ref, revision), d, workdir=dest) + runfetchcmd(ud.basecmd + ['update-ref', ref, revision], d, workdir=dest) # Fetch Git LFS data self.lfs_fetch(ud, d, dest, ud.revision) # Apply extra ref wildcards - all_refs_remote = runfetchcmd("%s ls-remote origin 'refs/*'" % ud.basecmd, \ + all_refs_remote = runfetchcmd(ud.basecmd + ['ls-remote', 'origin', 'refs/*'], \ d, workdir=dest).splitlines() all_refs = [] for line in all_refs_remote: @@ -644,14 +645,12 @@ class Git(FetchMethod): for ref in extra_refs: ref_fetch = ref.replace('refs/heads/', '').replace('refs/remotes/origin/', '').replace('refs/tags/', '') - runfetchcmd("%s fetch origin --depth 1 -- %s" % - (ud.basecmd, shlex.quote(ref_fetch)), d, workdir=dest) - revision = runfetchcmd("%s rev-parse FETCH_HEAD" % ud.basecmd, d, workdir=dest) - runfetchcmd("%s update-ref %s %s" % - (ud.basecmd, shlex.quote(ref), revision), d, workdir=dest) + runfetchcmd(ud.basecmd + ['fetch', 'origin', '--depth', '1', '--', ref_fetch], d, workdir=dest) + revision = runfetchcmd(ud.basecmd + ['rev-parse', 'FETCH_HEAD'], d, workdir=dest).strip() + runfetchcmd(ud.basecmd + ['update-ref', ref, revision], d, workdir=dest) # The url is local ud.clonedir, set it to upstream one - runfetchcmd("%s remote set-url origin %s" % (ud.basecmd, shlex.quote(repourl)), d, workdir=dest) + runfetchcmd(ud.basecmd + ['remote', 'set-url', 'origin', repourl], d, workdir=dest) def unpack_update(self, ud, destdir, d): return self.unpack(ud, destdir, d, update=True) @@ -687,8 +686,9 @@ class Git(FetchMethod): need_lfs = self._need_lfs(ud) + extraenv = {} if not need_lfs: - ud.basecmd = "GIT_LFS_SKIP_SMUDGE=1 " + ud.basecmd + extraenv["GIT_LFS_SKIP_SMUDGE"] = "1" source_found = False update_mode = False @@ -699,7 +699,7 @@ class Git(FetchMethod): if update and os.path.exists(destdir): update_mode = True else: - runfetchcmd("%s clone %s %s %s" % (ud.basecmd, ud.cloneflags, ud.clonedir, destdir), d) + runfetchcmd(ud.basecmd + ['clone'] + ud.cloneflags + [ud.clonedir, destdir], d, extraenv=extraenv) source_found = True else: source_error.append("clone directory not available or not up to date: " + ud.clonedir) @@ -711,7 +711,7 @@ class Git(FetchMethod): update_mode = True else: bb.utils.mkdirhier(destdir) - runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=destdir) + runfetchcmd(['tar', '-xzf', ud.fullshallow], d, workdir=destdir) source_found = True else: source_error.append("shallow clone not available: " + ud.fullshallow) @@ -725,26 +725,26 @@ class Git(FetchMethod): if ud.shallow: raise bb.fetch2.UnpackError("Can't update shallow clones checkouts without network access, not supported.", ud.url) - output = runfetchcmd("%s status --untracked-files=no --porcelain" % (ud.basecmd), d, workdir=destdir) + output = runfetchcmd(ud.basecmd + ['status', '--untracked-files=no', '--porcelain'], d, workdir=destdir, extraenv=extraenv) if output: raise bb.fetch2.LocalModificationsError(destdir, ud.url, output) # Set up remote for the download location if it doesn't exist try: - runfetchcmd("%s remote get-url dldir" % (ud.basecmd), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['remote', 'get-url', 'dldir'], d, workdir=destdir) except bb.fetch2.FetchError: if ud.clonedir: - runfetchcmd("%s remote add dldir file://%s" % (ud.basecmd, ud.clonedir), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['remote', 'add', 'dldir', 'file://' + ud.clonedir], d, workdir=destdir) try: - runfetchcmd("%s fetch dldir" % (ud.basecmd), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['fetch', 'dldir'], d, workdir=destdir, extraenv=extraenv) except bb.fetch2.FetchError as e: raise bb.fetch2.UnpackError("Failed to fetch from dldir remote: %s" % str(e), ud.url) try: - runfetchcmd("%s rebase --no-autosquash --no-autostash %s" % (ud.basecmd, ud.revision), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['rebase', '--no-autosquash', '--no-autostash', ud.revision], d, workdir=destdir, extraenv=extraenv) except bb.fetch2.FetchError as e: # If rebase failed, abort it try: - runfetchcmd("%s rebase --abort" % (ud.basecmd), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['rebase', '--abort'], d, workdir=destdir) except Exception: pass raise bb.fetch2.RebaseError(destdir, ud.url, str(e)) @@ -753,23 +753,23 @@ class Git(FetchMethod): # If there is a tag parameter in the url and we also have a fixed srcrev, check the tag # matches the revision if 'tag' in ud.parm and sha1_re.match(ud.revision): - output = runfetchcmd("%s rev-list -n 1 %s" % (ud.basecmd, ud.parm['tag']), d, workdir=destdir) + output = runfetchcmd(ud.basecmd + ['rev-list', '-n', '1', ud.parm['tag']], d, workdir=destdir, extraenv=extraenv) output = output.strip() if output != ud.revision: # It is possible ud.revision is the revision on an annotated tag which won't match the output of rev-list # If it resolves to the same thing there isn't a problem. - output2 = runfetchcmd("%s rev-list -n 1 %s" % (ud.basecmd, ud.revision), d, workdir=destdir) + output2 = runfetchcmd(ud.basecmd + ['rev-list', '-n', '1', ud.revision], d, workdir=destdir) output2 = output2.strip() if output != output2: raise bb.fetch2.FetchError("The revision the git tag '%s' resolved to didn't match the SRCREV in use (%s vs %s)" % (ud.parm['tag'], output, ud.revision), ud.url) repourl = self._get_repo_url(ud) - runfetchcmd("%s remote set-url origin %s" % (ud.basecmd, shlex.quote(repourl)), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['remote', 'set-url', 'origin', repourl], d, workdir=destdir) if ud.clonedir: try: - runfetchcmd("%s remote get-url dldir" % (ud.basecmd), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['remote', 'get-url', 'dldir'], d, workdir=destdir) except bb.fetch2.FetchError: - runfetchcmd("%s remote add dldir file://%s" % (ud.basecmd, ud.clonedir), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['remote', 'add', 'dldir', "file://" + ud.clonedir], d, workdir=destdir) if self._contains_lfs(ud, d, destdir): if not need_lfs: @@ -777,27 +777,22 @@ class Git(FetchMethod): else: self._ensure_git_lfs(d, ud) - runfetchcmd("%s lfs install --local" % ud.basecmd, d, workdir=destdir) + runfetchcmd(ud.basecmd + ['lfs', 'install', '--local'], d, workdir=destdir) if not ud.nocheckout: if subpath: - runfetchcmd("%s read-tree %s%s" % (ud.basecmd, ud.revision, readpathspec), d, - workdir=destdir) - runfetchcmd("%s checkout-index -q -f -a" % ud.basecmd, d, workdir=destdir) - runfetchcmd("%s update-ref --no-deref HEAD %s" % (ud.basecmd, ud.revision), - d, workdir=destdir) + runfetchcmd(ud.basecmd + ['read-tree', ud.revision + readpathspec], d, workdir=destdir, extraenv=extraenv) + runfetchcmd(ud.basecmd + ['checkout-index', '-q', '-f', '-a'], d, workdir=destdir, extraenv=extraenv) + runfetchcmd(ud.basecmd + ['update-ref', '--no-deref', 'HEAD', ud.revision], d, workdir=destdir, extraenv=extraenv) if not ud.nobranch: branchname = ud.branch - runfetchcmd("%s update-ref refs/heads/%s %s" % (ud.basecmd, branchname, - ud.revision), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['update-ref', 'refs/heads/' + branchname, ud.revision], d, workdir=destdir, extraenv=extraenv) elif not ud.nobranch: branchname = ud.branch - runfetchcmd("%s checkout -B %s %s" % (ud.basecmd, branchname, \ - ud.revision), d, workdir=destdir) - runfetchcmd("%s branch %s --set-upstream-to origin/%s" % (ud.basecmd, branchname, \ - branchname), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['checkout', '-B', branchname, ud.revision], d, workdir=destdir, extraenv=extraenv) + runfetchcmd(ud.basecmd + ['branch', branchname, '--set-upstream-to', 'origin/' + branchname], d, workdir=destdir, extraenv=extraenv) else: - runfetchcmd("%s checkout %s" % (ud.basecmd, ud.revision), d, workdir=destdir) + runfetchcmd(ud.basecmd + ['checkout', ud.revision], d, workdir=destdir, extraenv=extraenv) return True @@ -825,22 +820,17 @@ class Git(FetchMethod): return True def _contains_ref(self, ud, d, name, wd, tag=False): - cmd = "" git_ref_name = 'refs/tags/%s' % ud.parm['tag'] if tag else ud.revision if ud.nobranch: - cmd = "%s log --pretty=oneline -n 1 %s -- 2> /dev/null | wc -l" % ( - ud.basecmd, git_ref_name) + cmd = ud.basecmd + ['log', '--pretty=oneline', '-n', '1', git_ref_name, "--"] else: - cmd = "%s branch --contains %s --list %s 2> /dev/null | wc -l" % ( - ud.basecmd, git_ref_name, ud.branch) + cmd = ud.basecmd + ['branch', '--contains', git_ref_name, '--list', ud.branch] try: - output = runfetchcmd(cmd, d, quiet=True, workdir=wd) - except bb.fetch2.FetchError: + output = runfetchcmd(cmd, d, workdir=wd) + except (bb.fetch2.FetchError): return False - if len(output.split()) > 1: - raise bb.fetch2.FetchError("The command '%s' gave output with more then 1 line unexpectedly, output: '%s'" % (cmd, output)) - return output.split()[0] != "0" + return len(output.splitlines()) > 0 def _lfs_objects_downloaded(self, ud, d, wd): """ @@ -855,8 +845,7 @@ class Git(FetchMethod): # The Git LFS specification specifies ([1]) the LFS folder layout so it should be safe to check for file # existence. # [1] https://github.com/git-lfs/git-lfs/blob/main/docs/spec.md#intercepting-git - cmd = "%s lfs ls-files -l %s" \ - % (ud.basecmd, ud.revision) + cmd = ud.basecmd + ['lfs', 'ls-files', '-l', ud.revision] output = runfetchcmd(cmd, d, quiet=True, workdir=wd).rstrip() # Do not do any further matching if no objects are managed by LFS if not output: @@ -880,12 +869,10 @@ class Git(FetchMethod): """ Check if the repository has 'lfs' (large file) content """ - cmd = "%s grep '^[^#].*lfs' %s:.gitattributes | wc -l" % ( - ud.basecmd, ud.revision) - + cmd = ud.basecmd + ['grep', '^[^#].*lfs', ud.revision + ':.gitattributes'] try: output = runfetchcmd(cmd, d, quiet=True, workdir=wd) - if int(output) > 0: + if len(output.splitlines()) > 0: return True except (bb.fetch2.FetchError,ValueError): pass @@ -937,8 +924,9 @@ class Git(FetchMethod): d.setVar('_BB_GIT_IN_LSREMOTE', '1') try: repourl = self._get_repo_url(ud) - cmd = "%s ls-remote %s %s" % \ - (ud.basecmd, shlex.quote(repourl), search) + cmd = ud.basecmd + ['ls-remote', repourl] + if search: + cmd.append(search) if ud.proto.lower() != 'file': bb.fetch2.check_network_access(d, cmd, repourl) output = runfetchcmd(cmd, d, True) @@ -1041,11 +1029,9 @@ class Git(FetchMethod): commits = None else: if not os.path.exists(rev_file) or not os.path.getsize(rev_file): - commits = bb.fetch2.runfetchcmd( - "git rev-list %s -- | wc -l" % shlex.quote(rev), - d, quiet=True).strip().lstrip('0') + commits = bb.fetch2.runfetchcmd(['git', 'rev-list', rev, '--'], d).splitlines() if commits: - open(rev_file, "w").write("%d\n" % int(commits)) + open(rev_file, "w").write("%d\n" % len(commits)) else: commits = open(rev_file, "r").readline(128).strip() if commits: diff --git a/lib/bb/fetch2/gitannex.py b/lib/bb/fetch2/gitannex.py index 80a808d88f0..b0b2c229eeb 100644 --- a/lib/bb/fetch2/gitannex.py +++ b/lib/bb/fetch2/gitannex.py @@ -27,7 +27,7 @@ class GitANNEX(Git): def uses_annex(self, ud, d, wd): for name in ud.names: try: - runfetchcmd("%s rev-list git-annex" % (ud.basecmd), d, quiet=True, workdir=wd) + runfetchcmd(ud.basecmd + ['rev-list', 'git-annex'], d, quiet=True, workdir=wd) return True except bb.fetch.FetchError: pass @@ -36,10 +36,10 @@ class GitANNEX(Git): def update_annex(self, ud, d, wd): try: - runfetchcmd("%s annex get --all" % (ud.basecmd), d, quiet=True, workdir=wd) + runfetchcmd(ud.basecmd + ['annex get', '--all'], d, quiet=True, workdir=wd) except bb.fetch.FetchError: return False - runfetchcmd("chmod u+w -R %s/annex" % (ud.clonedir), d, quiet=True, workdir=wd) + runfetchcmd(['chmod', 'u+w', '-R', '%s/annex' % ud.clonedir], d, quiet=True, workdir=wd) return True @@ -54,24 +54,24 @@ class GitANNEX(Git): super(GitANNEX, self).clone_shallow_local(ud, dest, d) try: - runfetchcmd("%s annex init" % ud.basecmd, d, workdir=dest) + runfetchcmd(ud.basecmd + ['annex', 'init'], d, workdir=dest) except bb.fetch.FetchError: pass if self.uses_annex(ud, d, dest): - runfetchcmd("%s annex get" % ud.basecmd, d, workdir=dest) - runfetchcmd("chmod u+w -R %s/.git/annex" % (dest), d, quiet=True, workdir=dest) + runfetchcmd(ud.basecmd + ['annex', 'get'], d, workdir=dest) + runfetchcmd(['chmod', 'u+w', '-R', '%s/.git/annex' % dest], d, quiet=True, workdir=dest) def unpack(self, ud, destdir, d): Git.unpack(self, ud, destdir, d) try: - runfetchcmd("%s annex init" % (ud.basecmd), d, workdir=ud.destdir) + runfetchcmd(ud.basecmd + ['annex' ,'init'], d, workdir=ud.destdir) except bb.fetch.FetchError: pass annex = self.uses_annex(ud, d, ud.destdir) if annex: - runfetchcmd("%s annex get" % (ud.basecmd), d, workdir=ud.destdir) - runfetchcmd("chmod u+w -R %s/.git/annex" % (ud.destdir), d, quiet=True, workdir=ud.destdir) + runfetchcmd(ud.basecmd + ['annex', 'get'], d, workdir=ud.destdir) + runfetchcmd(['chmod', 'u+w', '-R', '%s/.git/annex' % ud.destdir], d, quiet=True, workdir=ud.destdir) diff --git a/lib/bb/fetch2/gitsm.py b/lib/bb/fetch2/gitsm.py index 5869e1b99b7..d4340e11651 100644 --- a/lib/bb/fetch2/gitsm.py +++ b/lib/bb/fetch2/gitsm.py @@ -63,14 +63,14 @@ class GitSM(Git): # Collect the defined submodules, and their attributes try: - gitmodules = runfetchcmd("%s show %s:.gitmodules" % (ud.basecmd, ud.revision), d, quiet=True, workdir=workdir) + gitmodules = runfetchcmd(ud.basecmd + ['show', '%s:.gitmodules' % ud.revision], d, quiet=True, workdir=workdir) except: # No submodules to update gitmodules = "" for m, md in parse_gitmodules(gitmodules).items(): try: - module_hash = runfetchcmd("%s ls-tree -z -d %s %s" % (ud.basecmd, ud.revision, md['path']), d, quiet=True, workdir=workdir) + module_hash = runfetchcmd(ud.basecmd + ['ls-tree', '-z', '-d', ud.revision, md['path']], d, quiet=True, workdir=workdir) except: # If the command fails, we don't have a valid file to check. If it doesn't # fail -- it still might be a failure, see next check... @@ -155,7 +155,7 @@ class GitSM(Git): if ud.shallow and os.path.exists(ud.fullshallow) and unpack: tmpdir = tempfile.mkdtemp(dir=d.getVar("DL_DIR")) try: - runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=tmpdir) + runfetchcmd(['tar', '-xzf', ud.fullshallow], d, workdir=tmpdir) self.process_submodules(ud, tmpdir, subfunc, d) finally: shutil.rmtree(tmpdir) @@ -228,14 +228,14 @@ class GitSM(Git): local_path = newfetch.localpath(url) # Correct the submodule references to the local download version... - runfetchcmd("%(basecmd)s config submodule.%(module)s.url %(url)s" % {'basecmd': ud.basecmd, 'module': module, 'url' : local_path}, d, workdir=ud.destdir) + runfetchcmd(ud.basecmd + ['config', 'submodule.%s.url' % module, local_path], d, workdir=ud.destdir) if ud.shallow: - runfetchcmd("%(basecmd)s config submodule.%(module)s.shallow true" % {'basecmd': ud.basecmd, 'module': module}, d, workdir=ud.destdir) + runfetchcmd(ud.basecmd + ['config', 'submodule.%s.shallow' % module, 'true'], d, workdir=ud.destdir) # Ensure the submodule repository is NOT set to bare, since we're checking it out... try: - runfetchcmd("%s config core.bare false" % (ud.basecmd), d, quiet=True, workdir=os.path.join(repo_conf, 'modules', module)) + runfetchcmd(ud.basecmd + ['config', 'core.bare', 'false'], d, quiet=True, workdir=os.path.join(repo_conf, 'modules', module)) except: logger.error("Unable to set git config core.bare to false for %s" % os.path.join(repo_conf, 'modules', module)) raise @@ -245,11 +245,12 @@ class GitSM(Git): ret = self.process_submodules(ud, ud.destdir, unpack_submodules, d) if not ud.bareclone and ret: - cmdprefix = "" + extraenv = {} # Avoid LFS smudging (replacing the LFS pointers with the actual content) when LFS shouldn't be used but git-lfs is installed. if not self._need_lfs(ud): - cmdprefix = "GIT_LFS_SKIP_SMUDGE=1 " - runfetchcmd("%s%s submodule update --recursive --no-fetch" % (cmdprefix, ud.basecmd), d, quiet=True, workdir=ud.destdir) + extraenv['GIT_LFS_SKIP_SMUDGE'] = '1' + runfetchcmd(ud.basecmd + ['submodule', 'update', '--recursive', '--no-fetch'], d, quiet=True, workdir=ud.destdir, extraenv=extraenv) + def clean(self, ud, d): def clean_submodule(ud, url, module, modpath, workdir, d): url += ";bareclone=1;nobranch=1" From patchwork Wed Jun 3 10:48:35 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Purdie X-Patchwork-Id: 89239 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8483CD6E55 for ; Wed, 3 Jun 2026 10:48:48 +0000 (UTC) Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.17310.1780483725669238615 for ; Wed, 03 Jun 2026 03:48:45 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linuxfoundation.org header.s=google header.b=T3joGMrX; spf=pass (domain: linuxfoundation.org, ip: 209.85.128.43, mailfrom: richard.purdie@linuxfoundation.org) Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-4905529b933so99941725e9.0 for ; Wed, 03 Jun 2026 03:48:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; t=1780483724; x=1781088524; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=L6veTflboWUU3OOTCvoZcLwVbjp6nXJH524RdKgSjIs=; b=T3joGMrXeCSnXHPuPsxMzJYrt2zBLzO3n8k1tfl21UrlB2kwG/wbs/Wq4Fjnx6r81r CTK4bo9qkVI/tSoo7m14Zi+O0JoqiZDc4DZgrGcnlUq1HCQ4owwOvLcu0KdPVtFxO35S logoTmNoPPtc1IA0/KA0gnhAZLApfOqgH2S+Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780483724; x=1781088524; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=L6veTflboWUU3OOTCvoZcLwVbjp6nXJH524RdKgSjIs=; b=hbXK8NNlQ57Nsp4sUMv8onzCJr6xOuXVBlUPi5J7FX3iBhXy0vICuvIoVrLyLNQFLX U6zbq7fos/YHHS3JRbZbOQYfAXPpNiJz+8Bzq1los9vUpWSrDmwdwsS8hwGE9tKpXtLf dojOaVeWgu5Lw0+XpFIlNNHBH02n2os5BqqYxH5YeOpbrzOfeOga94Ubu0GXMluyQV3q VniaseQ9/0uWKCf4ajZoBIw9humR6QdSoedU6UnY/oi6QuptPlCyF5izBIDPOfxdjtzp SbYeGxmb4+9Gdce6N8mgF2RzalzufhnNWJOxJNQUtsf12+GWCR8Q8a0RUrTrdCUwCmz2 lMTw== X-Gm-Message-State: AOJu0Yz0Y1PBygzq+r7tG7UeWtXLbkTCOpq+dCozYcOTSSrx1IwEhX6a Wk9AEKOFgG3IH/tdbPpBRYPVcfJwJy9Iv2HIrAhxKAZqR0oPa3EpkfrkyHDwRVf0p0nuOR2JF4U VNDU/ X-Gm-Gg: Acq92OFongPYfeFhxvLsMA1RVMtk9Es5MJt1c5M3duRPucaVTqDHYJHRvi1KI0RKFT6 BTUT+hibcpl5kmrtg9t+2T+0i9Pc9ilqHSGC3bR2eSUqIdGhkVbmkEnUepvZQ9e4dG39NnAlu8A TWHle98OF/8xZYbqKBevrulclqBhkZmepmktqHMLJaEOn00sXjNMdPy0B3G+kBgaH57uqeFseuG yevdJe0DjadPxGMzYQo2N5GRBXJ9H1URKONnzyCOWoUhqtbf7dSXh9riPeTSVAaaHxOzt1bqo1x Z1BT1b4bt67AnfYjI92hYvtg+ynJARfI3lFzSUMNX7o2yvTYufpOilH2LaEQJVROuLWdjsI1aWK 23XLm3H6q1bQmZm3MhkM8/W1Ffely2GPLw0vNsrphh6yuGv5ssNtkNJvcT4uJEVMiVDBd66cAgV mk4epL3aHvk2roHFzOAMgK7zOOalh2tFK+Jsd2+Ou/WjrFnz8HQf89dAZO12/XiA== X-Received: by 2002:a05:600c:810c:b0:490:b11f:2560 with SMTP id 5b1f17b1804b1-490b5e6ef66mr49370355e9.9.1780483724052; Wed, 03 Jun 2026 03:48:44 -0700 (PDT) Received: from max.int.rpsys.net ([2001:8b0:aba:5f3c:202c:df88:9261:8b8]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f35ee64sm8090759f8f.30.2026.06.03.03.48.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 03:48:43 -0700 (PDT) From: Richard Purdie To: bitbake-devel@lists.openembedded.org Subject: [PATCH 3/8] fetch/wget: Convert to use lists of command arguments Date: Wed, 3 Jun 2026 11:48:35 +0100 Message-ID: <20260603104840.815399-3-richard.purdie@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> References: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 03 Jun 2026 10:48:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19596 To follow best practises and avoid shell=True subprocess usage, convert the fetcher commands to use lists instead of strings. This improves variable quoting and models modern coding standards. Signed-off-by: Richard Purdie --- lib/bb/fetch2/wget.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/bb/fetch2/wget.py b/lib/bb/fetch2/wget.py index 6e186e1ca1f..475f042dd84 100644 --- a/lib/bb/fetch2/wget.py +++ b/lib/bb/fetch2/wget.py @@ -83,13 +83,13 @@ class Wget(FetchMethod): if not ud.localfile: ud.localfile = ud.host + ud.path.replace("/", ".") - self.basecmd = d.getVar("FETCHCMD_wget") or "/usr/bin/env wget --tries=2 --timeout=100" + self.basecmd = shlex.split(d.getVar("FETCHCMD_wget") or "") or ['wget', '--tries=2', '--timeout=100'] if ud.type == 'ftp' or ud.type == 'ftps': - self.basecmd += " --passive-ftp" + self.basecmd.append("--passive-ftp") if not self.check_certs(d): - self.basecmd += " --no-check-certificate" + self.basecmd.append("--no-check-certificate") def _runwget(self, ud, d, command, quiet, workdir=None): @@ -97,20 +97,21 @@ class Wget(FetchMethod): logger.debug2("Fetching %s using command '%s'" % (ud.url, command)) bb.fetch2.check_network_access(d, command, ud.url) - runfetchcmd(command + ' --progress=dot --verbose', d, quiet, log=progresshandler, workdir=workdir) + + runfetchcmd(command + ['--progress=dot', '--verbose'], d, quiet, log=progresshandler, workdir=workdir) def download(self, ud, d): """Fetch urls""" - fetchcmd = self.basecmd + fetchcmd = self.basecmd.copy() dldir = os.path.realpath(d.getVar("DL_DIR")) localpath = os.path.join(dldir, ud.localfile) + ".tmp" bb.utils.mkdirhier(os.path.dirname(localpath)) - fetchcmd += " --output-document=%s" % shlex.quote(localpath) + fetchcmd.append("--output-document=%s" % localpath) if ud.user and ud.pswd: - fetchcmd += " --auth-no-challenge" + fetchcmd.append("--auth-no-challenge") if ud.parm.get("redirectauth", "1") == "1": # An undocumented feature of wget is that if the # username/password are specified on the URI, wget will only @@ -120,10 +121,13 @@ class Wget(FetchMethod): # AWS will reject any request that has authentication both in # the query parameters (from the redirect) and in the # Authorization header. - fetchcmd += " --user=%s --password=%s" % (ud.user, ud.pswd) + fetchcmd.append("--user=" + ud.user) + fetchcmd.append("--password=" + ud.pswd) uri = ud.url.split(";")[0] - fetchcmd += " --continue --directory-prefix=%s '%s'" % (dldir, uri) + fetchcmd.append("--continue") + fetchcmd.append("--directory-prefix=" + dldir) + fetchcmd.append(uri) self._runwget(ud, d, fetchcmd, False) # Sanity check since wget can pretend it succeed when it didn't @@ -482,8 +486,7 @@ class Wget(FetchMethod): """ f = tempfile.NamedTemporaryFile() with tempfile.TemporaryDirectory(prefix="wget-index-") as workdir, tempfile.NamedTemporaryFile(dir=workdir, prefix="wget-listing-") as f: - fetchcmd = self.basecmd - fetchcmd += " --output-document=%s '%s'" % (f.name, uri) + fetchcmd = self.basecmd + ["--output-document=%s" % f.name, uri] try: self._runwget(ud, d, fetchcmd, True, workdir=workdir) fetchresult = f.read() From patchwork Wed Jun 3 10:48:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Purdie X-Patchwork-Id: 89238 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 34702CD6E6A for ; Wed, 3 Jun 2026 10:48:50 +0000 (UTC) Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.17037.1780483727076549145 for ; Wed, 03 Jun 2026 03:48:47 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linuxfoundation.org header.s=google header.b=G9Yisgda; spf=pass (domain: linuxfoundation.org, ip: 209.85.221.54, mailfrom: richard.purdie@linuxfoundation.org) Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-45ef56d9b67so4020884f8f.2 for ; Wed, 03 Jun 2026 03:48:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; t=1780483725; x=1781088525; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=9X7/VkxGpLygk3H4QJQED5d/yOCUnPfDRoRBAsQwOQY=; b=G9YisgdaesHaGMvrBrIMtJ+QSnrPoQeaFiSjOKRL4hr335bNUf16K9kFzRbNdzh7GP Nz0EamLgpnzTiv1fHC1PGz8c0f2WKTan2nadCOuXPsOoHhXhCN9WWy82h0zoWXBqREu+ MEgFC5JqQetznjhwOZ0sNsKp1K8rYfvR+Sk7o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780483725; x=1781088525; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=9X7/VkxGpLygk3H4QJQED5d/yOCUnPfDRoRBAsQwOQY=; b=VR1iqwcglVnnADIDu7WLTG6yanY4pgZ5JTc7AoQnrEFhvSXZyArwLGSmFb6so8/u7n m9bKq3XItE83n8OFHQThDmWW9q6syerHKZ1GmV+QxzrCy/5EhQjPxFNS6J9Hv3BsuvmB 78wCsSorN3lpbw0UMfI722hzLFHMONMnZY9PUr/My4jPKL0z1zjFkcg1q1OWaZlkso0a kr7M7xH7I974D146qJgRb/6T95XHh/ysyoCk88gFJ74FwbPuLs/K1YWdpi4b6lotMnd5 pcPG99nneRB3UiNRdziYqDSnCSni0fCxjWEdvqQesS6HplBBNrqPyGKmktmnVd8fwFOH NiWg== X-Gm-Message-State: AOJu0Yx06n8ls04LXrlEYgdqdzmTWf+V5UdFHl5he2AxsP5NLW0s2XXA z5XYPxmreuP4kluVRbqEnGJpFGynimpDF+gS4e/rN511ZQOWx1VnkhsAplS08O2M/XrZ2oLP/uB tzVPp X-Gm-Gg: Acq92OFSP/DaBFmyQ93cZYWBdRNViRK0Xr9w2HfMAGTOgUmmykNZ/jdGGeyWS/cu2pR kwmqka9YP+kZ28j/YnvklXmANSpYkIXx5dUbFOeUA8QEY0IXJWNUIpG4hg+zFBHIdwW0BXQSsw/ fmeRn4WWRkPWRSGkbio7zzj6YlTrTrFiOQ9GkFaZBLuxq0qaDiLdHzEx2Ms0Kq+m0GSDen3bgDq FmFGYDbxZnTa6uFKpfwM69MBq5dqTGbSPSN+MwkZvJCVf30qQaF19eQQEVKSiFNSwUEHVo4gtc/ nTQ9eaNpHSjrrowGpVj0ovAi43ffMMloD7tHHjDZhlRqTDnN8NMa/ZjUX3GadAEA25KveHvztlV b+m5yk/Qbe4JVmocKcwF+UM+b7GTpYSVni5jePG0PXLY9NoPtSAi5/yNhQJPD8iA4JMxsBHYhPJ //M4Ay1WyPKTuPy0TYEcGB1bDbMXpWBxSfn8qFM3Byorl3CAhcKCtY6Rl0UulX8ftUsYG4MbYR X-Received: by 2002:a5d:64c9:0:b0:45e:ea2a:dd79 with SMTP id ffacd0b85a97d-460218aaec9mr4106046f8f.4.1780483725378; Wed, 03 Jun 2026 03:48:45 -0700 (PDT) Received: from max.int.rpsys.net ([2001:8b0:aba:5f3c:202c:df88:9261:8b8]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f35ee64sm8090759f8f.30.2026.06.03.03.48.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 03:48:44 -0700 (PDT) From: Richard Purdie To: bitbake-devel@lists.openembedded.org Subject: [PATCH 4/8] fetch/{sftp,ssh}: Convert to use lists of command arguments Date: Wed, 3 Jun 2026 11:48:36 +0100 Message-ID: <20260603104840.815399-4-richard.purdie@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> References: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 03 Jun 2026 10:48:50 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19597 To follow best practises and avoid shell=True subprocess usage, convert the fetcher commands to use lists instead of strings. This improves variable quoting and models modern coding standards. Signed-off-by: Richard Purdie --- lib/bb/fetch2/sftp.py | 8 ++++---- lib/bb/fetch2/ssh.py | 28 ++++++++-------------------- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/lib/bb/fetch2/sftp.py b/lib/bb/fetch2/sftp.py index bee71a0d0d0..021a092f1f3 100644 --- a/lib/bb/fetch2/sftp.py +++ b/lib/bb/fetch2/sftp.py @@ -48,6 +48,7 @@ SRC_URI = "sftp://user@host.example.com/dir/path.file.txt" import os import bb +import shlex import urllib.request, urllib.parse, urllib.error from bb.fetch2 import URI from bb.fetch2 import FetchMethod @@ -83,10 +84,9 @@ class SFTP(FetchMethod): """Fetch urls""" urlo = URI(ud.url) - basecmd = 'sftp -oBatchMode=yes' - port = '' + basecmd = ['sftp', '-oBatchMode=yes'] if urlo.port: - port = '-P %d' % urlo.port + basecmd += ['-P', urlo.port] urlo.port = None dldir = d.getVar('DL_DIR') @@ -105,7 +105,7 @@ class SFTP(FetchMethod): remote = '"%s%s:%s"' % (user, urlo.hostname, path) - cmd = '%s %s %s %s' % (basecmd, port, remote, lpath) + cmd = basecmd + [remote, lpath] bb.fetch2.check_network_access(d, cmd, ud.url) runfetchcmd(cmd, d) diff --git a/lib/bb/fetch2/ssh.py b/lib/bb/fetch2/ssh.py index 2a0f2cb44b4..56e455fb47f 100644 --- a/lib/bb/fetch2/ssh.py +++ b/lib/bb/fetch2/ssh.py @@ -85,18 +85,16 @@ class SSH(FetchMethod): user = m.group('user') password = m.group('pass') + portarg = [] if port: - portarg = '-P %s' % port - else: - portarg = '' + portarg = ['-P', port] + fr = host if user: fr = user if password: fr += ':%s' % password fr += '@%s' % host - else: - fr = host if path[0] != '~': path = '/%s' % path @@ -104,11 +102,7 @@ class SSH(FetchMethod): fr += ':%s' % path - cmd = 'scp -B -r %s %s %s/' % ( - portarg, - fr, - dldir - ) + cmd = ['scp', '-B', '-r'] + portarg + [fr, dldir + "/"] check_network_access(d, cmd, urldata.url) @@ -125,28 +119,22 @@ class SSH(FetchMethod): user = m.group('user') password = m.group('pass') + portarg = [] if port: - portarg = '-P %s' % port - else: - portarg = '' + portarg = ['-P', port] + fr = host if user: fr = user if password: fr += ':%s' % password fr += '@%s' % host - else: - fr = host if path[0] != '~': path = '/%s' % path path = urllib.parse.unquote(path) - cmd = 'ssh -o BatchMode=true %s %s [ -f %s ]' % ( - portarg, - fr, - path - ) + cmd = ['ssh', '-o', 'BatchMode=true'] + portarg + [fr, '[', '-f', path, ']'] check_network_access(d, cmd, urldata.url) runfetchcmd(cmd, d) From patchwork Wed Jun 3 10:48:37 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Purdie X-Patchwork-Id: 89241 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6697CD6E55 for ; Wed, 3 Jun 2026 10:48:58 +0000 (UTC) Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.17311.1780483729051124556 for ; Wed, 03 Jun 2026 03:48:49 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linuxfoundation.org header.s=google header.b=Gn59smDU; spf=pass (domain: linuxfoundation.org, ip: 209.85.221.46, mailfrom: richard.purdie@linuxfoundation.org) Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-46015dc517aso2371497f8f.2 for ; Wed, 03 Jun 2026 03:48:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; t=1780483727; x=1781088527; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ECwLOKzEL1DPg7svBOpvAa7iKJDZb5pYLvIEmH3sy6Q=; b=Gn59smDU2yCJpI62Ak+EH7tNSHqtQNa8PVYq+m4xADxHO/nHHM505U89vNfPjWmaki K4Zuy9ov5GQFQg2RVzlWHU/Vf+sPuUdZLFtEqPiZZXAbMtuD+wMVKYS1V0kuB/oR/6cx h/lOVcHtUS8khwGUYsjou7YWAdLAeHf5e7Q6M= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780483727; x=1781088527; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ECwLOKzEL1DPg7svBOpvAa7iKJDZb5pYLvIEmH3sy6Q=; b=eQCZk0IOt03u81FW7tDv7Y86FRgdXg1kTbtgrcmVW5p5f0bjopGQkBSera3BGyHhgZ iRwmM6mdZw09R9cntXo8jLEgM651p/J6/0tf/+DZarLk1SDCQjfSLCzM4sm1fIR8Z/Dg OErw0teRtZZGXn5EoUNSJEOKJVt35Od5YOtJF6DPufX96aRdoayY/AtQipSpbCsplk4x IfEABSGZIWWH9rX/IjnGQ7Xf5HQiz1A+wCI54a54WhoLDXfjyYLRmXAZ3KXPXaNzL+vv CLET19G0BAKIY/TXYbRWiGo3TXohpVXOnrVXLZThbOCrjWttcRIKHYu7Cw9hWKHpWBXH /VgA== X-Gm-Message-State: AOJu0YyWjvdzPEFM0MrtVMIByomkycZjffdk9fOyGVNZTIqKePc7SEmt ffu1ak92cwJwmlhTSjw/ry9awPn7sFkj6Ej08yM3Uju81CVDIeoBRDGLgiPOaoHcdNfRVKo/5jG z9OH6 X-Gm-Gg: Acq92OEHDR2JkIycldYXRJKBr57HulSla2Xnb1FImB6KHdBTeF697hW74efNLqfYb26 mqVQO1N5q21y951L8emRkQYZf9fJDZ8j5larKq7EtVCQAwtD6Re83y7wpXOJvYtD5zQzj8FoBMe T4sgPWZ4VKWFFb8A4HQRhqejegYHTzN/OnyYfba0KglhEEZZ8korg3OLe72PayQK1b5wNVgoioR XyMPD5sQ2JUhQ0ezfWQFJnjfgBma75T2SCc3d/6d+I++pQ/0A64XsU7VES7EGABl31r64GZHAqq WsJg8kxnpBdBqlsf9EFc6r9KwG2v10sWKeTZSALOxSUSzkGB0t6kTgoQzaER7WMZPQNE6nE3B2Z fvQi0CZE5ivkLVtVMhJoIASYUHD6Veua1vuBAojl2+xFUWCCXjKYixf/Cwplv2xOw5o+ZUCzlfI wK9khD9YLU2qZ0mJI4o4W2yZi+hkpEZLEuXgnT7q5z/DKf3iXiaZpwAQ2zCN2Bh3XWu3e6a1eh X-Received: by 2002:a05:6000:1818:b0:45e:9421:4ca8 with SMTP id ffacd0b85a97d-4602184bfe7mr3359279f8f.28.1780483727291; Wed, 03 Jun 2026 03:48:47 -0700 (PDT) Received: from max.int.rpsys.net ([2001:8b0:aba:5f3c:202c:df88:9261:8b8]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f35ee64sm8090759f8f.30.2026.06.03.03.48.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 03:48:45 -0700 (PDT) From: Richard Purdie To: bitbake-devel@lists.openembedded.org Subject: [PATCH 5/8] fetch/svn: Convert to use lists of command arguments Date: Wed, 3 Jun 2026 11:48:37 +0100 Message-ID: <20260603104840.815399-5-richard.purdie@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> References: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 03 Jun 2026 10:48:58 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19598 To follow best practises and avoid shell=True subprocess usage, convert the fetcher commands to use lists instead of strings. This improves variable quoting and models modern coding standards. Signed-off-by: Richard Purdie --- lib/bb/fetch2/svn.py | 71 +++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/lib/bb/fetch2/svn.py b/lib/bb/fetch2/svn.py index b5862139fac..84e15c02d3c 100644 --- a/lib/bb/fetch2/svn.py +++ b/lib/bb/fetch2/svn.py @@ -13,6 +13,7 @@ BitBake 'Fetch' implementation for svn. import os import bb import re +import shlex from bb.fetch2 import FetchMethod from bb.fetch2 import FetchError from bb.fetch2 import MissingParameterError @@ -34,7 +35,7 @@ class Svn(FetchMethod): if not "module" in ud.parm: raise MissingParameterError('module', ud.url) - ud.basecmd = d.getVar("FETCHCMD_svn") or "/usr/bin/env svn --non-interactive" + ud.basecmd = shlex.split(d.getVar("FETCHCMD_svn") or "") or ['svn', '--non-interactive'] ud.module = ud.parm["module"] @@ -83,15 +84,17 @@ class Svn(FetchMethod): options.append("--no-auth-cache") if ud.user: - options.append("--username %s" % ud.user) + options.append("--username") + options.append(ud.user) if ud.pswd: - options.append("--password %s" % ud.pswd) + options.append("--password") + options.append(ud.pswd) if command == "info": - svncmd = "%s info %s %s://%s/%s/" % (ud.basecmd, " ".join(options), proto, svnroot, ud.module) + svncmd = ud.basecmd + ['info'] + options + ['%s://%s/%s/' % (proto, svnroot, ud.module)] elif command == "log1": - svncmd = "%s log --limit 1 --quiet %s %s://%s/%s/" % (ud.basecmd, " ".join(options), proto, svnroot, ud.module) + svncmd = ud.basecmd + ['log', '--limit', '1', '--quiet'] + options + ['%s://%s/%s/' % (proto, svnroot, ud.module)] else: suffix = "" @@ -102,22 +105,24 @@ class Svn(FetchMethod): options.append("--ignore-externals") if ud.revision: - options.append("-r %s" % ud.revision) + options.append("-r") + options.append(ud.revision) if ud.pegrevision: suffix = "@%s" % (ud.revision) if command == "fetch": transportuser = ud.parm.get("transportuser", "") - svncmd = "%s co %s %s://%s%s/%s%s %s" % (ud.basecmd, " ".join(options), proto, transportuser, svnroot, ud.module, suffix, ud.path_spec) + svncmd = ud.basecmd + ['co'] + options + ['%s://%s%s/%s%s' % (proto, transportuser, svnroot, ud.module, suffix), ud.path_spec] elif command == "update": - svncmd = "%s update %s" % (ud.basecmd, " ".join(options)) + svncmd = ud.basecmd + ['update'] + options else: raise FetchError("Invalid svn command %s" % command, ud.url) + extraenv = {} if svn_ssh: - svncmd = "SVN_SSH=\"%s\" %s" % (svn_ssh, svncmd) + extraenv['SVN_SSH'] = svn_ssh - return svncmd + return svncmd, extraenv def download(self, ud, d): """Fetch url""" @@ -128,45 +133,47 @@ class Svn(FetchMethod): try: if os.access(os.path.join(ud.moddir, '.svn'), os.R_OK): - svncmd = self._buildsvncommand(ud, d, "update") + svncmd, extraenv = self._buildsvncommand(ud, d, "update") logger.info("Update " + ud.url) # We need to attempt to run svn upgrade first in case its an older working format try: - runfetchcmd(ud.basecmd + " upgrade", d, workdir=ud.moddir) + runfetchcmd(ud.basecmd + ["upgrade"], d, workdir=ud.moddir) except FetchError: pass logger.debug("Running %s", svncmd) bb.fetch2.check_network_access(d, svncmd, ud.url) - runfetchcmd(svncmd, d, workdir=ud.moddir) + runfetchcmd(svncmd, d, workdir=ud.moddir, extraenv=extraenv) else: - svncmd = self._buildsvncommand(ud, d, "fetch") + svncmd, extraenv = self._buildsvncommand(ud, d, "fetch") logger.info("Fetch " + ud.url) # check out sources there bb.utils.mkdirhier(ud.pkgdir) logger.debug("Running %s", svncmd) bb.fetch2.check_network_access(d, svncmd, ud.url) - runfetchcmd(svncmd, d, workdir=ud.pkgdir) + runfetchcmd(svncmd, d, workdir=ud.pkgdir, extraenv=extraenv) if not ("externals" in ud.parm and ud.parm["externals"] == "nowarn"): # Warn the user if this had externals (won't catch them all) - output = runfetchcmd("svn propget svn:externals || true", d, workdir=ud.moddir) - if output: - if "--ignore-externals" in svncmd.split(): - bb.warn("%s contains svn:externals." % ud.url) - bb.warn("These should be added to the recipe SRC_URI as necessary.") - bb.warn("svn fetch has ignored externals:\n%s" % output) - bb.warn("To disable this warning add ';externals=nowarn' to the url.") - else: - bb.debug(1, "svn repository has externals:\n%s" % output) - + try: + output = runfetchcmd(['svn', 'propget', 'svn:externals'], d, workdir=ud.moddir) + if output: + if "--ignore-externals" in svncmd: + bb.warn("%s contains svn:externals." % ud.url) + bb.warn("These should be added to the recipe SRC_URI as necessary.") + bb.warn("svn fetch has ignored externals:\n%s" % output) + bb.warn("To disable this warning add ';externals=nowarn' to the url.") + else: + bb.debug(1, "svn repository has externals:\n%s" % output) + except bb.fetch2.FetchError: + passs scmdata = ud.parm.get("scmdata", "") if scmdata == "keep": - tar_flags = "" + tar_flags = [] else: - tar_flags = "--exclude='.svn'" + tar_flags = ["--exclude='.svn'"] # tar them up to a defined filename - runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, ud.path_spec), d, + runfetchcmd(['tar'] + tar_flags + ['-czf', ud.localpath, ud.path_spec], d, cleanup=[ud.localpath], workdir=ud.pkgdir) finally: bb.utils.unlockfile(lf) @@ -191,9 +198,11 @@ class Svn(FetchMethod): """ Return the latest upstream revision number """ - bb.fetch2.check_network_access(d, self._buildsvncommand(ud, d, "log1"), ud.url) - - output = runfetchcmd(self._buildsvncommand(ud, d, "log1"), d, True, extraenv={'LANG':'C', 'LC_ALL': 'C'}) + cmd, extraenv = self._buildsvncommand(ud, d, "log1") + bb.fetch2.check_network_access(d, cmd, ud.url) + extraenv['LANG'] = 'C' + extraenv['LC_ALL'] = 'C' + output = runfetchcmd(cmd, d, True, extraenv=extraenv) # skip the first line, as per output of svn log # then we expect the revision on the 2nd line From patchwork Wed Jun 3 10:48:38 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Purdie X-Patchwork-Id: 89240 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4052CD6E56 for ; Wed, 3 Jun 2026 10:48:58 +0000 (UTC) Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.17313.1780483730483795100 for ; Wed, 03 Jun 2026 03:48:50 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linuxfoundation.org header.s=google header.b=WDDWSW5o; spf=pass (domain: linuxfoundation.org, ip: 209.85.221.44, mailfrom: richard.purdie@linuxfoundation.org) Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-460166910e6so1661292f8f.2 for ; Wed, 03 Jun 2026 03:48:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; t=1780483729; x=1781088529; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=m/NoUBj09rXP6qscXGRUm68Bx4twS8Pqds3hkylzAqU=; b=WDDWSW5orKqkWyEGC2/6GHBTqa0Ik1oxICP3ifQKYlMFwd8KvMJcCgUf50AfJgLmrj Td5mo/9TujCxPBMWF0xcqYbDwOJ87uQylCbRzDpCKkTnr24XnldWog/F3Is2B7YGHQ13 nivyYnf/0KI9uLTajYrqFuMqEJ+iZhuxz8RD4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780483729; x=1781088529; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=m/NoUBj09rXP6qscXGRUm68Bx4twS8Pqds3hkylzAqU=; b=JiX10OxigSqdtLdVUmP0LrRWknfmhQFfG8cupphIpNV1f+MMlgbMx7Q7IUZbAufqzW 3sv5aa8A10CnRyNM79Z0u9X8QDzbYRyB8JLcsN/2pnK7Xc8Ic/XCFR3TwEu4xiI//KZ5 upCvIg304HFUWKsL3NvtoDjTJrKERMceUxIMRY+2d6Rim1IPffKRBXjyBZJ2FLeYWrrR qiSSbRLZVYK2tg907ysR4fJeIPrXXUPNIzYUPE+JrHWPxTjtvjxtWkSo3ctqe7aosJR1 idxSyRlL9pD58ZjmZ2RzM4rCua2cVPpjSbQPWpC+HRX5Z2yzHNE7vi2nbgGx9rAkUBHz 9KHA== X-Gm-Message-State: AOJu0Yx/YWtfeidm+8CIb0Z6/LzvY6AiTD48fawCl0vBtgBECeUw20YK P6LKnSToCd76xwI67Z87nd+zrhUnhTyegz3EckY/bfo5SIi6UHuocTWQQf4UBGv44fgClI7IUR7 p9BdU X-Gm-Gg: Acq92OFnYas2QWpZ2ZTE6Bta1vQqsDQGffyK8ivo/EjXO4bHsx/tnw+V0CAMCqprD0r r9SlLSxyF/BL8mzb5ILakTFzverZMq7OX05oHiQuhjVJkXU8IV9cMWRUmHMlibjwtv6sNkmSTpa c1kSlCzbuzFzLkAFGiqMs2KZkWLKOJh7XWUhJXrqp5nFGMCc9quOZ9xL4oFNpINAGnYz4qVZxYj 2y0epFNQZtGgYK676AxJH205UdqPcOFISJv6FqSgYhpU5Xzfi1lU/5wlPeHktukCbzu8R1P8Yvi C7QK27qJYCG03AHC0M6vBm2+HUUJkN01twlLgc+WzYThnM8EcrXkRe+y2Xax6onQbTGd9YZ6KBX cZoVjmOLQAQu8cc5/V2v343CFbQq/em7AWLj9zvbdli2nC6znjdjk1I0z4w4exki1Wiqj5u60sX ie25dpHjfOeVw0yRSprJC8I4VrWEfBV/xUOdiH/Rs5mHfuc1o72113whfhwZ6oIw== X-Received: by 2002:adf:f64f:0:b0:446:96b1:f5f with SMTP id ffacd0b85a97d-46021783c0fmr2735813f8f.8.1780483728861; Wed, 03 Jun 2026 03:48:48 -0700 (PDT) Received: from max.int.rpsys.net ([2001:8b0:aba:5f3c:202c:df88:9261:8b8]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f35ee64sm8090759f8f.30.2026.06.03.03.48.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 03:48:47 -0700 (PDT) From: Richard Purdie To: bitbake-devel@lists.openembedded.org Subject: [PATCH 6/8] fetch/{npm,npmsw}: Convert to use lists of command arguments Date: Wed, 3 Jun 2026 11:48:38 +0100 Message-ID: <20260603104840.815399-6-richard.purdie@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> References: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 03 Jun 2026 10:48:58 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19599 To follow best practises and avoid shell=True subprocess usage, convert the fetcher commands to use lists instead of strings. This improves variable quoting and models modern coding standards. Signed-off-by: Richard Purdie --- lib/bb/fetch2/npm.py | 24 +++++++++++------------- lib/bb/fetch2/npmsw.py | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/bb/fetch2/npm.py b/lib/bb/fetch2/npm.py index ed9ed167946..3c0cd9ff098 100644 --- a/lib/bb/fetch2/npm.py +++ b/lib/bb/fetch2/npm.py @@ -75,12 +75,9 @@ def npm_integrity(integrity): def npm_unpack(tarball, destdir, d): """Unpack a npm tarball""" bb.utils.mkdirhier(destdir) - cmd = "tar --extract --gzip --file=%s" % shlex.quote(tarball) - cmd += " --no-same-owner" - cmd += " --delay-directory-restore" - cmd += " --strip-components=1" + cmd = ['tar', '--extract', '--gzip', '--file=%s' % tarball, '--no-same-owner', '--delay-directory-restore', '--strip-components=1'] runfetchcmd(cmd, d, workdir=destdir) - runfetchcmd("chmod -R +X '%s'" % (destdir), d, quiet=True, workdir=destdir) + runfetchcmd(['chmod', '-R', '+X', destdir], d, quiet=True, workdir=destdir) class NpmEnvironment(object): """ @@ -129,19 +126,20 @@ class NpmEnvironment(object): workdir = tmpdir def _run(cmd): - cmd = "NPM_CONFIG_USERCONFIG=%s " % (self.user_config.name) + cmd - cmd = "NPM_CONFIG_GLOBALCONFIG=%s " % (self.global_config_name) + cmd - return runfetchcmd(cmd, d, workdir=workdir) + extraenv = {} + extraenv['NPM_CONFIG_USERCONFIG'] = self.user_config.name + extraenv['NPM_CONFIG_GLOBALCONFIG'] = self.global_config_name + return runfetchcmd(cmd, d, workdir=workdir, extraenv=extraenv) if configs: bb.warn("Use of configs argument of NpmEnvironment.run() function" " is deprecated. Please use args argument instead.") for key, value in configs: - cmd += " --%s=%s" % (key, shlex.quote(value)) + cmd.append('--%s=%s' % (key, value)) if args: for key, value in args: - cmd += " --%s=%s" % (key, shlex.quote(value)) + cmd.append('--%s=%s' % (key, value)) return _run(cmd) @@ -190,7 +188,7 @@ class Npm(FetchMethod): ud.localfile = npm_localfile(ud.package, ud.version) # Get the base 'npm' command - ud.basecmd = d.getVar("FETCHCMD_npm") or "npm" + ud.basecmd = shlex.split(d.getVar("FETCHCMD_npm") or "") or ["npm"] # This fetcher resolves a URI from a npm package name and version and # then forwards it to a proxy fetcher. A resolve file containing the @@ -206,8 +204,8 @@ class Npm(FetchMethod): args = [] args.append(("json", "true")) args.append(("registry", ud.registry)) - pkgver = shlex.quote(ud.package + "@" + ud.version) - cmd = ud.basecmd + " view %s" % pkgver + pkgver = ud.package + "@" + ud.version + cmd = ud.basecmd + ['view', pkgver] env = NpmEnvironment(d) check_network_access(d, cmd, ud.registry) view_string = env.run(cmd, args=args) diff --git a/lib/bb/fetch2/npmsw.py b/lib/bb/fetch2/npmsw.py index 85f4482ad7d..5255e8b465e 100644 --- a/lib/bb/fetch2/npmsw.py +++ b/lib/bb/fetch2/npmsw.py @@ -276,7 +276,7 @@ class NpmShrinkWrap(FetchMethod): npm_unpack(depsrcdir, depdestdir, d) else: bb.utils.mkdirhier(depdestdir) - cmd = 'cp -fpPRH "%s/." .' % (depsrcdir) + cmd = ['cp', '-fpPRH', '%s/.' % depsrcdir, "."] runfetchcmd(cmd, d, workdir=depdestdir) def clean(self, ud, d): From patchwork Wed Jun 3 10:48:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Purdie X-Patchwork-Id: 89243 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3637CD6E64 for ; Wed, 3 Jun 2026 10:48:58 +0000 (UTC) Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.17314.1780483733996951656 for ; Wed, 03 Jun 2026 03:48:54 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linuxfoundation.org header.s=google header.b=ZySg0gNK; spf=pass (domain: linuxfoundation.org, ip: 209.85.221.53, mailfrom: richard.purdie@linuxfoundation.org) Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-45ef4223be7so3134099f8f.2 for ; Wed, 03 Jun 2026 03:48:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; t=1780483732; x=1781088532; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=xtViTKhp8sOT8aYJdmN20Ng3709hzsfdUlUIqXxK0qw=; b=ZySg0gNKp+pNJEWBmZ7x/Txx8b6Hs6oEK7FUQz09a6S80V5EiHax0CVEGyYDkvsVri TE2I9N3xJUjk08WZRa0+AeMEvS3DhlHPMI8FavIr8Kekv0yQiRZM4sI+tpDhbX+IBwVN Yu3eB+e1VwWcrQftWCxmaOJ83RumXKoG397RM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780483732; x=1781088532; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=xtViTKhp8sOT8aYJdmN20Ng3709hzsfdUlUIqXxK0qw=; b=Fvv2Zk9cL0nZek9/KKRKnMjRp8cpxLliYhbqjgRE67WhW35qpcGSM9R0zw8cpYRX1b lry9emJEY8xiCQPgGf8xm9401jMpajD2Ix4BkdxZk6MjMGThtxKtCZ+qfhWYE+aA4UKF cg9bP/Yv+GIWLLI0yysoOhx9rc5RnRb+XasspWy9796rE5U1GepUGoCB4Q67WV5CY5NE r0bPm34AxH+TKx5FJ8VqOFkAXQrq8OcW+lRca0i+nKAbLfP+szdFxIbCUAyeZ+1K1bRJ NJX7CequSUM4iss0p2PO4PHkwLInP0B5fF5RqBwlJsY13y+f0yO3FITVbuOUxkUuvS/j VsFw== X-Gm-Message-State: AOJu0YzZu8YRy4r6EbJ1rD/MV9MguhelEb984r8Km1QY59lqk7DBhXjr h/Nc7xReD1XsxmvdZaH29ZJH9qaJgW+0hIEmoXKP3k3nF0deTMgqrS6dF+KpKKEq5x3sNbwRS23 /OmEz X-Gm-Gg: Acq92OFn3m66cy0ggojHxQz+527daugh0lnF+ow3PWbnfPjL8+F4uA830sb/Wme155R zMgYhJRgT6sROOjs7LIvpMeOeOuqQkEFBjMltV9ZsGdPjQEVeU7OzN6TF69mMVXRZxpY8JqoFqo FyFFftDau0pf3YufsiIGW4AQR3U458CMXjxPYfktWn8STSNXGUgJf1UTgk5Y+pSOWwL9pF5d1X+ I/oAcE3jMSMAtZfAxNwT9V870LyXmSO6Roats5hjrKZP2zBmKxkZDls9DOsvNKHGIhH0RUszs1F pU1LXsRZBS20om+6tEKFcpI1NkY8D+EMUPunNhSNxSfnW2ucGjXq0bx0kd47+9N5Nqx/Ejv74dZ O44jGDoc0odTsOO1/4avXbZOJwE+iPfD5IvFqSsYiyRCpAswM68TOSkhPvVlD9A9RTp6B+nBsVr q8sfYcI4sOpErWrNpSqfo5M7wI2l6/Y86dMj172T6g7KZa7z4X6yPzB01S/keahQCiQwMaBTNi X-Received: by 2002:a05:6000:144e:b0:45e:a19f:22c1 with SMTP id ffacd0b85a97d-460217e3018mr4130573f8f.15.1780483732154; Wed, 03 Jun 2026 03:48:52 -0700 (PDT) Received: from max.int.rpsys.net ([2001:8b0:aba:5f3c:202c:df88:9261:8b8]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f35ee64sm8090759f8f.30.2026.06.03.03.48.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 03:48:49 -0700 (PDT) From: Richard Purdie To: bitbake-devel@lists.openembedded.org Subject: [PATCH 7/8] fetch/{clearcase,gomod,hg,perforce,repo,s3}: Convert to use lists of command arguments Date: Wed, 3 Jun 2026 11:48:39 +0100 Message-ID: <20260603104840.815399-7-richard.purdie@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> References: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 03 Jun 2026 10:48:58 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19600 To follow best practises and avoid shell=True subprocess usage, convert the fetcher commands to use lists instead of strings. This improves variable quoting and models modern coding standards. Some of these fetchers could not be tested so the changes are made blind. Signed-off-by: Richard Purdie --- lib/bb/fetch2/clearcase.py | 39 ++++++++++++++++--------------- lib/bb/fetch2/gomod.py | 4 ++-- lib/bb/fetch2/hg.py | 47 ++++++++++++++++---------------------- lib/bb/fetch2/perforce.py | 30 ++++++++++++++---------- lib/bb/fetch2/repo.py | 14 ++++++------ lib/bb/fetch2/s3.py | 7 +++--- 6 files changed, 71 insertions(+), 70 deletions(-) diff --git a/lib/bb/fetch2/clearcase.py b/lib/bb/fetch2/clearcase.py index 17500daf952..cb3f8b650c7 100644 --- a/lib/bb/fetch2/clearcase.py +++ b/lib/bb/fetch2/clearcase.py @@ -49,6 +49,7 @@ User credentials: # import os +import shlex import shutil import bb from bb.fetch2 import FetchMethod @@ -94,7 +95,7 @@ class ClearCase(FetchMethod): else: ud.module = "" - ud.basecmd = d.getVar("FETCHCMD_ccrc") or "/usr/bin/env cleartool || rcleartool" + ud.fallbackcmd = shlex.split(d.getVar("FETCHCMD_ccrc") or "") if d.getVar("SRCREV") == "INVALID": raise FetchError("Set a valid SRCREV for the clearcase fetcher in your recipe, e.g. SRCREV = \"/main/LATEST\" or any other label of your choice.") @@ -122,7 +123,6 @@ class ClearCase(FetchMethod): self.debug("type = %s" % ud.type) self.debug("vob = %s" % ud.vob) self.debug("module = %s" % ud.module) - self.debug("basecmd = %s" % ud.basecmd) self.debug("label = %s" % ud.label) self.debug("ccasedir = %s" % ud.ccasedir) self.debug("viewdir = %s" % ud.viewdir) @@ -135,34 +135,35 @@ class ClearCase(FetchMethod): Build up a commandline based on ud command is: mkview, setcs, rmview """ - options = [] + cmd = [shutil.which("cleartool"), command] + if cmd[0] is None: + cmd = [shutil.which("rcleartool"), command] + if cmd[0] is None: + cmd = ud.fallbackcmd + [command] - if "rcleartool" in ud.basecmd: - options.append("-server %s" % ud.server) - - basecmd = "%s %s" % (ud.basecmd, command) + if cmd[0].endswith("rcleartool"): + cmd += ['-server', ud.server] if command == 'mkview': - if not "rcleartool" in ud.basecmd: + if not cmd[0].endswith("rcleartool"): # Cleartool needs a -snapshot view - options.append("-snapshot") - options.append("-tag %s" % ud.viewname) - options.append(ud.viewdir) + cmd.append("-snapshot") + cmd += ["-tag", ud.viewname] + cmd.append(ud.viewdir) elif command == 'rmview': - options.append("-force") - options.append("%s" % ud.viewdir) + cmd.append("-force") + cmd.append(ud.viewdir) elif command == 'setcs': - options.append("-overwrite") - options.append(ud.configspecfile) + cmd.append("-overwrite") + cmd.append(ud.configspecfile) else: raise FetchError("Invalid ccase command %s" % command) - ccasecmd = "%s %s" % (basecmd, " ".join(options)) - self.debug("ccasecmd = %s" % ccasecmd) - return ccasecmd + self.debug("ccasecmd = %s" % cmd) + return cmd def _write_configspec(self, ud, d): """ @@ -235,7 +236,7 @@ class ClearCase(FetchMethod): # Clean clearcase meta-data before tar - runfetchcmd('tar -czf "%s" .' % (ud.localpath), d, cleanup = [ud.localpath], workdir = ud.viewdir) + runfetchcmd(['tar', '-czf', ud.localpath, '.'], d, cleanup = [ud.localpath], workdir = ud.viewdir) # Clean up so we can create a new view next time self.clean(ud, d); diff --git a/lib/bb/fetch2/gomod.py b/lib/bb/fetch2/gomod.py index 53c1d8d115b..8a64f644dfd 100644 --- a/lib/bb/fetch2/gomod.py +++ b/lib/bb/fetch2/gomod.py @@ -242,9 +242,9 @@ class GoModGit(Git): srcrev = ud.parm['srcrev'] version = ud.parm['version'] escaped_version = escape(version) - cmd = f"git ls-tree -r --name-only '{srcrev}'" + cmd = ['git', 'ls-tree', '-r', '--name-only', srcrev] if 'subpath' in ud.parm: - cmd += f" '{ud.parm['subpath']}'" + cmd.append(ud.parm['subpath']) files = runfetchcmd(cmd, d, workdir=repodir).split() name = escaped_version + '.mod' bb.note(f"Unpacking {name} to {unpackdir}/") diff --git a/lib/bb/fetch2/hg.py b/lib/bb/fetch2/hg.py index cbff8c490c9..5c65a1985bb 100644 --- a/lib/bb/fetch2/hg.py +++ b/lib/bb/fetch2/hg.py @@ -15,6 +15,7 @@ BitBake 'Fetch' implementation for mercurial DRCS (hg). import os import bb import errno +import shlex from bb.fetch2 import FetchMethod from bb.fetch2 import FetchError from bb.fetch2 import MissingParameterError @@ -63,7 +64,7 @@ class Hg(FetchMethod): ud.pkgdir = os.path.join(hgdir, hgsrcname) ud.moddir = os.path.join(ud.pkgdir, ud.module) ud.localfile = ud.moddir - ud.basecmd = d.getVar("FETCHCMD_hg") or "/usr/bin/env hg" + ud.basecmd = shlex.split(d.getVar("FETCHCMD_hg") or "") or ["hg"] ud.setup_revisions(d) @@ -113,7 +114,7 @@ class Hg(FetchMethod): hgroot = ud.user + "@" + host + ud.path if command == "info": - return "%s identify -i %s://%s/%s" % (ud.basecmd, proto, hgroot, ud.module) + return ud.basecmd + ['identify', '-i', '%s://%s/%s' % (proto, hgroot, ud.module)] options = []; @@ -122,26 +123,21 @@ class Hg(FetchMethod): # the tag actually exists in the specified revision + 1, so it won't # be available when used in any successive commands. if ud.revision and command != "fetch": - options.append("-r %s" % ud.revision) + options += ["-r", ud.revision] + + authconfig = [] + if ud.user and ud.pswd: + authconfig = ['--config', 'auth.default.prefix=*', '--config', 'auth.default.username=' + ud.user, '--config', 'auth.default.password=' + ud.pswd, '--config', 'auth.default.schemes=' + proto] if command == "fetch": - if ud.user and ud.pswd: - cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" clone %s %s://%s/%s %s" % (ud.basecmd, ud.user, ud.pswd, proto, " ".join(options), proto, hgroot, ud.module, ud.module) - else: - cmd = "%s clone %s %s://%s/%s %s" % (ud.basecmd, " ".join(options), proto, hgroot, ud.module, ud.module) + cmd = ud.basecmd + authconfig + ['clone'] + options + ['%s://%s/%s' % (proto, hgroot, ud.module), ud.module] elif command == "pull": # do not pass options list; limiting pull to rev causes the local # repo not to contain it and immediately following "update" command # will crash - if ud.user and ud.pswd: - cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" pull" % (ud.basecmd, ud.user, ud.pswd, proto) - else: - cmd = "%s pull" % (ud.basecmd) + cmd = ud.basecmd + authconfig + ['pull'] elif command == "update" or command == "up": - if ud.user and ud.pswd: - cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" update -C %s" % (ud.basecmd, ud.user, ud.pswd, proto, " ".join(options)) - else: - cmd = "%s update -C %s" % (ud.basecmd, " ".join(options)) + cmd = ud.basecmd + authconfig + ['update', '-C'] + options else: raise FetchError("Invalid hg command %s" % command, ud.url) @@ -155,7 +151,7 @@ class Hg(FetchMethod): # If the checkout doesn't exist and the mirror tarball does, extract it if not os.path.exists(ud.pkgdir) and os.path.exists(ud.fullmirror): bb.utils.mkdirhier(ud.pkgdir) - runfetchcmd("tar -xzf %s" % (ud.fullmirror), d, workdir=ud.pkgdir) + runfetchcmd(['tar', '-xzf', ud.fullmirror], d, workdir=ud.pkgdir) if os.access(os.path.join(ud.moddir, '.hg'), os.R_OK): # Found the source, check whether need pull @@ -228,8 +224,8 @@ class Hg(FetchMethod): os.unlink(ud.fullmirror) logger.info("Creating tarball of hg repository") - runfetchcmd("tar -czf %s %s" % (ud.fullmirror, ud.module), d, workdir=ud.pkgdir) - runfetchcmd("touch %s.done" % (ud.fullmirror), d, workdir=ud.pkgdir) + runfetchcmd(['tar', '-czf', ud.fullmirror, ud.module], d, workdir=ud.pkgdir) + runfetchcmd(['touch', '%s.done' % ud.fullmirror], d, workdir=ud.pkgdir) def localpath(self, ud, d): return ud.pkgdir @@ -249,16 +245,13 @@ class Hg(FetchMethod): proto = ud.parm.get('protocol', 'http') if not os.access(os.path.join(codir, '.hg'), os.R_OK): logger.debug2("Unpack: creating new hg repository in '" + codir + "'") - runfetchcmd("%s init %s" % (ud.basecmd, codir), d) + runfetchcmd(ud.basecmd + ['init', codir], d) logger.debug2("Unpack: updating source in '" + codir + "'") + authconfig = [] if ud.user and ud.pswd: - runfetchcmd("%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" pull %s" % (ud.basecmd, ud.user, ud.pswd, proto, ud.moddir), d, workdir=codir) - else: - runfetchcmd("%s pull %s" % (ud.basecmd, ud.moddir), d, workdir=codir) - if ud.user and ud.pswd: - runfetchcmd("%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" up -C %s" % (ud.basecmd, ud.user, ud.pswd, proto, revflag), d, workdir=codir) - else: - runfetchcmd("%s up -C %s" % (ud.basecmd, revflag), d, workdir=codir) + authconfig = ['--config', 'auth.default.prefix=*', '--config', 'auth.default.username=' + ud.user, '--config', 'auth.default.password=' + ud.pswd, '--config', 'auth.default.schemes=' + proto] + runfetchcmd(ud.basecmd + authconfig + ['pull', ud.moddir], d, workdir=codir) + runfetchcmd(ud.basecmd + authconfig + ['up', '-C', revflag], d, workdir=codir) else: logger.debug2("Unpack: extracting source to '" + codir + "'") - runfetchcmd("%s archive -t files %s %s" % (ud.basecmd, revflag, codir), d, workdir=ud.moddir) + runfetchcmd(ud.basecmd + ['archive', '-t', 'files', revflag, codir], d, workdir=ud.moddir) diff --git a/lib/bb/fetch2/perforce.py b/lib/bb/fetch2/perforce.py index 3b6fa4b1ec9..52ea061c04b 100644 --- a/lib/bb/fetch2/perforce.py +++ b/lib/bb/fetch2/perforce.py @@ -26,6 +26,7 @@ Supported SRC_URI options are: import os import bb +import shlex from bb.fetch2 import FetchMethod from bb.fetch2 import FetchError from bb.fetch2 import logger @@ -73,7 +74,7 @@ class Perforce(FetchMethod): provided by the env, use it. If P4PORT is specified by the recipe, use its values, which may override the settings in P4CONFIG. """ - ud.basecmd = d.getVar("FETCHCMD_p4") or "/usr/bin/env p4" + ud.basecmd = shlex.split(d.getVar("FETCHCMD_p4") or "") or ["p4"] ud.dldir = d.getVar("P4DIR") or (d.getVar("DL_DIR") + "/p4") @@ -95,10 +96,15 @@ class Perforce(FetchMethod): else: logger.debug('Trying to use P4CONFIG to automatically set P4PORT...') ud.usingp4config = True - p4cmd = '%s info | grep "Server address"' % ud.basecmd + p4cmd = ud.basecmd + ['info'] bb.fetch2.check_network_access(d, p4cmd, ud.url) - ud.host = runfetchcmd(p4cmd, d, True) - ud.host = ud.host.split(': ')[1].strip() + output = runfetchcmd(p4cmd, d, True) + ud.host = None + for line in output.splitlines(): + if "Server address" in line: + ud.host = line.split(': ')[1].strip() + break + logger.debug('Determined P4PORT to be: %s' % ud.host) if not ud.host: raise FetchError('Could not determine P4PORT from P4CONFIG') @@ -142,16 +148,16 @@ class Perforce(FetchMethod): "files". depot_filename is the full path to the file in the depot including the trailing '#rev' value. """ - p4opt = "" + p4opt = [] if ud.user: - p4opt += ' -u "%s"' % (ud.user) + p4opt += ['-u', ud.user] if ud.pswd: - p4opt += ' -P "%s"' % (ud.pswd) + p4opt += ['-P', ud.pswd] if ud.host and not ud.usingp4config: - p4opt += ' -p %s' % (ud.host) + p4opt += ['-p', ud.host] if hasattr(ud, 'revision') and ud.revision: pathnrev = '%s@%s' % (ud.path, ud.revision) @@ -176,14 +182,14 @@ class Perforce(FetchMethod): filename = filename[:filename.find('#')] # Remove trailing '#rev' if command == 'changes': - p4cmd = '%s%s changes -m 1 //%s' % (ud.basecmd, p4opt, pathnrev) + p4cmd = ud.basecmd + p4opt + ['changes', '-m', '1', '//%s' % pathnrev] elif command == 'print': if depot_filename is not None: - p4cmd = '%s%s print -o "p4/%s" "%s"' % (ud.basecmd, p4opt, filename, depot_filename) + p4cmd = ud.basecmd + p4opt + ['print', '-o', 'p4/%s' % filename, depot_filename] else: raise FetchError('No depot file name provided to p4 %s' % command, ud.url) elif command == 'files': - p4cmd = '%s%s files //%s' % (ud.basecmd, p4opt, pathnrev) + p4cmd = ud.basecmd + p4opt + ['files', '//%s' % pathnrev] else: raise FetchError('Invalid p4 command %s' % command, ud.url) @@ -231,7 +237,7 @@ class Perforce(FetchMethod): bb.fetch2.check_network_access(d, p4fetchcmd, ud.url) runfetchcmd(p4fetchcmd, d, workdir=ud.pkgdir, log=progresshandler) - runfetchcmd('tar -czf %s p4' % (ud.localpath), d, cleanup=[ud.localpath], workdir=ud.pkgdir) + runfetchcmd(['tar', '-czf', ud.localpath, 'p4'], d, cleanup=[ud.localpath], workdir=ud.pkgdir) def clean(self, ud, d): """ Cleanup p4 specific files and dirs""" diff --git a/lib/bb/fetch2/repo.py b/lib/bb/fetch2/repo.py index fa4cb8149b7..1f9ede04430 100644 --- a/lib/bb/fetch2/repo.py +++ b/lib/bb/fetch2/repo.py @@ -33,7 +33,7 @@ class Repo(FetchMethod): "master". """ - ud.basecmd = d.getVar("FETCHCMD_repo") or "/usr/bin/env repo" + ud.basecmd = shlex.split(d.getVar("FETCHCMD_repo") or "") or ["repo"] ud.proto = ud.parm.get('protocol', 'git') ud.branch = ud.parm.get('branch', 'master') @@ -63,19 +63,19 @@ class Repo(FetchMethod): bb.utils.mkdirhier(repodir) if not os.path.exists(os.path.join(repodir, ".repo")): bb.fetch2.check_network_access(d, "%s init -m %s -b %s -u %s://%s%s%s" % (ud.basecmd, ud.manifest, ud.branch, ud.proto, username, ud.host, ud.path), ud.url) - runfetchcmd("%s init -m %s -b %s -u %s://%s%s%s" % (ud.basecmd, ud.manifest, ud.branch, ud.proto, username, ud.host, ud.path), d, workdir=repodir) + runfetchcmd(ud.basecmd + ['init', '-m', ud.manifest, '-b', ud.branch, '-u', '%s://%s%s%s' % (ud.proto, username, ud.host, ud.path)], d, workdir=repodir) - bb.fetch2.check_network_access(d, "%s sync %s" % (ud.basecmd, ud.url), ud.url) - runfetchcmd("%s sync" % ud.basecmd, d, workdir=repodir) + bb.fetch2.check_network_access(d, ud.basecmd + ['sync'], ud.url) + runfetchcmd(ud.basecmd + ['sync'], d, workdir=repodir) scmdata = ud.parm.get("scmdata", "") if scmdata == "keep": - tar_flags = "" + tar_flags = [] else: - tar_flags = "--exclude='.repo' --exclude='.git'" + tar_flags = ["--exclude='.repo'", "--exclude='.git'"] # Create a cache - runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, os.path.join(".", "*") ), d, workdir=codir) + runfetchcmd(['tar'] + tar_flags + ['-czf', ud.localpath, os.path.join(".", "*")], d, workdir=codir) def supports_srcrev(self): return False diff --git a/lib/bb/fetch2/s3.py b/lib/bb/fetch2/s3.py index 22c05381392..05935101471 100644 --- a/lib/bb/fetch2/s3.py +++ b/lib/bb/fetch2/s3.py @@ -19,6 +19,7 @@ import os import bb import urllib.request, urllib.parse, urllib.error import re +import shlex from bb.fetch2 import FetchMethod from bb.fetch2 import FetchError from bb.fetch2 import runfetchcmd @@ -79,7 +80,7 @@ class S3(FetchMethod): ud.localfile = ud.basename - ud.basecmd = d.getVar("FETCHCMD_s3") or "/usr/bin/env aws s3" + ud.basecmd = shlex.split(d.getVar("FETCHCMD_s3") or "") or ["aws", "s3"] def download(self, ud, d): """ @@ -87,7 +88,7 @@ class S3(FetchMethod): Assumes localpath was called first """ - cmd = '%s cp s3://%s%s %s' % (ud.basecmd, ud.host, ud.path, ud.localpath) + cmd = ud.basecmd + ['cp', 's3://%s%s' % (ud.basecmd, ud.host, ud.path), ud.localpath] bb.fetch2.check_network_access(d, cmd, ud.url) progresshandler = S3ProgressHandler(d) @@ -111,7 +112,7 @@ class S3(FetchMethod): Check the status of a URL """ - cmd = '%s ls s3://%s%s' % (ud.basecmd, ud.host, ud.path) + cmd = ud.basecmd + ['ls', 's3://%s%s' % (ud.basecmd, ud.host, ud.path)] bb.fetch2.check_network_access(d, cmd, ud.url) output = runfetchcmd(cmd, d) From patchwork Wed Jun 3 10:48:40 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Purdie X-Patchwork-Id: 89242 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C846CD6E6B for ; Wed, 3 Jun 2026 10:48:59 +0000 (UTC) Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.17040.1780483734669224855 for ; Wed, 03 Jun 2026 03:48:54 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linuxfoundation.org header.s=google header.b=avkac4hs; spf=pass (domain: linuxfoundation.org, ip: 209.85.221.42, mailfrom: richard.purdie@linuxfoundation.org) Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-45ef1629ff4so4059571f8f.0 for ; Wed, 03 Jun 2026 03:48:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; t=1780483733; x=1781088533; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=LwAFRt8rERQbGM4z9pgSdcSj91XPJyaxKeZxawLFYW0=; b=avkac4hsFeK6uaEu+ZidFljxdhti6xD54qNzndYRZs6OLEGH9rzY3lB/slklhWQ9MV My5EXQVTodAiW72Ew+zGNRS6zevuAxPWWtoyW1OflDem9jkOTppvF7jNt1dUhNUqG4YH L9CT39xK7d0Qu/RMhPDe/XDqiCb2XNFxQ0894= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780483733; x=1781088533; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=LwAFRt8rERQbGM4z9pgSdcSj91XPJyaxKeZxawLFYW0=; b=MHliHAHYcnAI6ISyl/GMjb2HaTopv1QeRPfeCn33zz1E9nokhaGoSkxYfhR8qnwcmj XkrkFKyx3xh65UJpHC4M2sD/kxzMhTRipmeCv2nK8C0hhsh7mF5KUTRLnRgypEiP/Teo NKr1184ysVcq4sD0KI1kKEXqLtrdnvtampL9Ht83J2cRvyQlDgRypV8AV/i8S0BhNf6L R252L7+trOgfuydr1P1NITj6pKn4ELMf5C1cW0zeEQ77ySdq6MQ0CEiM0Y0kjYCwiYDU KCxkcC8YJ9JvvnmoaeVl2/O2hPYvRKGDgHVcL+Wd4Zqgln0d96GYHEclqVk25FqgOHkC cxfg== X-Gm-Message-State: AOJu0YxAbJGmvoEH+nDirIaRCC1sC6T3egwotAHssXWCFo1Jjb7MAz4F SQ//kp+JTz23qz5aYdpH5a61M8ERZKANsEq2198gh3f//boZdlEy/Hi2alV9SIvGSCPWXtQH/Po uFIGk X-Gm-Gg: Acq92OGAOjNCzsHC4BA3A33TPXqTrSjLUw/PLqxV9kLSSiCtrJFklN/GQgbIPefwE7D 0KrWXwkiS9v4e51X5sWmLf54olErezqPLHPhFUfFwTB37cyLmXehAJhUYBfoHlqKQ0AxXu0L3p7 g3kuDCDgat4HYkAP0b4a6GFrlSZ/W4rl1Du+krfsz0R4AyzZ3q2GYCqUF0vmxLaB2nxxSAxR1zm fxVMEthq3y56ydTV7zYZHXZKvsyaKaIa5eM2iBtwV0ZINO9MNIFnzywS4MyNKW5rwlv/CgEZL2I Z+iPXGb1s3jjjNhaiV4Xnb5bRXFQ3ryVqMmsN+pILK3sRwrPeZuo0rLvvzBettcN3RJeA5mLYqS aitS1Ls90v1btXnrpMzYtHW0HzDOwrkt5jpwDUnezXqHLCVNVWEmcys4GscisdP0iCxi7TqtQti i5LmZP2JKa1ni74jo2qaPnGzPf9bjvMJbpxxJslX86Cmx3M+wZtzW937OqTK/NioV/z+OYps+k X-Received: by 2002:a05:600c:c174:b0:490:b2a6:8c2b with SMTP id 5b1f17b1804b1-490b5eb82b2mr47214255e9.10.1780483733135; Wed, 03 Jun 2026 03:48:53 -0700 (PDT) Received: from max.int.rpsys.net ([2001:8b0:aba:5f3c:202c:df88:9261:8b8]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f35ee64sm8090759f8f.30.2026.06.03.03.48.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 03:48:52 -0700 (PDT) From: Richard Purdie To: bitbake-devel@lists.openembedded.org Subject: [PATCH 8/8] fetch2: Drop shell=True from runfetchcmd Date: Wed, 3 Jun 2026 11:48:40 +0100 Message-ID: <20260603104840.815399-8-richard.purdie@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> References: <20260603104840.815399-1-richard.purdie@linuxfoundation.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 03 Jun 2026 10:48:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19601 All users should be updated to use lists and we can drop the shell=True fallback code. Signed-off-by: Richard Purdie --- lib/bb/fetch2/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/bb/fetch2/__init__.py b/lib/bb/fetch2/__init__.py index e3b8f5787b1..93d8b1820d8 100644 --- a/lib/bb/fetch2/__init__.py +++ b/lib/bb/fetch2/__init__.py @@ -979,10 +979,7 @@ def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None, workdir=None, extra error_message = "" try: - if isinstance(cmd, str): - (output, errors) = bb.process.run(cmd, log=log, shell=True, stderr=subprocess.PIPE, cwd=workdir, env=env) - else: - (output, errors) = bb.process.run(cmd, log=log, stderr=subprocess.PIPE, cwd=workdir, env=env) + (output, errors) = bb.process.run(cmd, log=log, stderr=subprocess.PIPE, cwd=workdir, env=env) success = True except bb.process.NotFoundError as e: error_message = "Fetch command %s not found" % (e.command)