diff --git a/tern/analyze/common.py b/tern/analyze/common.py
index df4889a..a9de792 100644
--- a/tern/analyze/common.py
+++ b/tern/analyze/common.py
@@ -31,9 +31,11 @@ logger = logging.getLogger(constants.logger_name)
 
 
 def get_shell_commands(shell_command_line):
-    '''Given a shell command line, get a list of Command objects'''
+    '''Given a shell command line, get a list of Command objects and report on
+    branch statements'''
     statements = general.split_command(shell_command_line)
     command_list = []
+    branch_report = ''
     # traverse the statements, pick out the loop and commands.
     for stat in statements:
         if 'command' in stat:
@@ -43,7 +45,13 @@ def get_shell_commands(shell_command_line):
             for st in loop_stat:
                 if 'command' in st:
                     command_list.append(Command(st['command']))
-    return command_list
+        elif 'branch' in stat:
+            branch_report = branch_report + '\n'.join(stat['content']) + '\n\n'
+    if branch_report:
+        # add prefix
+        branch_report = '\nNon-deterministic branching statement: \n' + \
+                        branch_report
+    return command_list, branch_report
 
 
 def load_from_cache(layer, redo=False):
@@ -478,7 +486,7 @@ def filter_install_commands(shell_command_line):
         3. Return installed command objects, and messages for ignored commands
         and unrecognized commands'''
     report = ''
-    command_list = get_shell_commands(shell_command_line)
+    command_list, branch_report = get_shell_commands(shell_command_line)
     for command in command_list:
         command_lib.set_command_attrs(command)
     ignore_msgs, filter1 = remove_ignored_commands(command_list)
@@ -487,7 +495,8 @@ def filter_install_commands(shell_command_line):
         report = report + formats.ignored + ignore_msgs
     if unrec_msgs:
         report = report + formats.unrecognized + unrec_msgs
-
+    if branch_report:
+        report = report + branch_report
     return consolidate_commands(filter2), report
 
 

Report RUN command statements that are non-deterministic like if and case statements
**Describe the Feature**
Currently, the report notices just says that if, case and for statements are unrecognizable. It would be nice to add notices for non-deterministic branching statements like if and case statements as you could only know the status of the branch at build time.

**Implementation Changes**
The new shell script parser produces a dictionary that will identify if and case statements. We could just look at this object and extract the if and case statements to create notices for them.

diff --git a/tests/test_analyze_common.py b/tests/test_analyze_common.py
index e40445c..82aba50 100644
--- a/tests/test_analyze_common.py
+++ b/tests/test_analyze_common.py
@@ -32,10 +32,18 @@ class TestAnalyzeCommon(unittest.TestCase):
         del self.test_dockerfile
 
     def testGetShellCommands(self):
-        command = common.get_shell_commands("yum install nfs-utils")
+        command, _ = common.get_shell_commands("yum install nfs-utils")
         self.assertEqual(type(command), list)
         self.assertEqual(len(command), 1)
         self.assertEqual(command[0].options, self.command1.options)
+        # test on branching command
+        branching_script = "if [ -z $var ]; then yum install nfs-utils; fi"
+        branch_command, report = common.get_shell_commands(branching_script)
+        self.assertEqual(type(branch_command), list)
+        # we will ignore branching command, so len should be 0
+        self.assertEqual(len(branch_command), 0)
+        # and the report should not be None
+        self.assertTrue(report)
 
     def testLoadFromCache(self):
         '''Given a layer object, populate the given layer in case the cache isn't empty'''

pip install -e.[dev]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
astroid==2.15.8
attrs==24.2.0
bandit==1.7.5
cachetools==5.5.2
certifi @ file:///croot/certifi_1671487769961/work/certifi
chardet==5.2.0
charset-normalizer==3.4.1
colorama==0.4.6
debut==0.9.9
dill==0.3.7
distlib==0.3.9
docker==4.4.4
dockerfile-parse==0.0.18
dodgy==0.2.1
exceptiongroup==1.2.2
filelock==3.12.2
flake8==3.9.2
flake8-polyfill==1.0.2
gitdb2==2.0.6
GitPython==2.1.15
idna==3.10
importlib-metadata==6.7.0
iniconfig==2.0.0
isort==5.11.5
lazy-object-proxy==1.9.0
markdown-it-py==2.2.0
mccabe==0.6.1
mdurl==0.1.2
packaging==24.0
pbr==6.1.1
pep8-naming==0.10.0
platformdirs==4.0.0
pluggy==1.2.0
prospector==1.7.7
pycodestyle==2.7.0
pydocstyle==6.1.1
pyflakes==2.3.1
Pygments==2.17.2
pylint==2.17.7
pylint-celery==0.3
pylint-django==2.5.3
pylint-flask==0.6
pylint-plugin-utils==0.7
pyproject-api==1.5.3
pytest==7.4.4
PyYAML==6.0.1
regex==2024.4.16
requests==2.31.0
requirements-detector==0.7
rich==13.8.1
setoptconf-tmp==0.3.1
six==1.17.0
smmap==5.0.2
smmap2==3.0.1
snowballstemmer==2.2.0
stevedore==3.5.2
-e git+https://github.com/tern-tools/tern.git@044dc470ec5be8aacbc085a5ae307c608ff13255#egg=tern
toml==0.10.2
tomli==2.0.1
tomlkit==0.12.5
tox==4.8.0
typed-ast==1.5.5
typing_extensions==4.7.1
urllib3==2.0.7
virtualenv==20.26.6
websocket-client==1.6.1
wrapt==1.16.0
zipp==3.15.0

name: tern
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - astroid==2.15.8
      - attrs==24.2.0
      - bandit==1.7.5
      - cachetools==5.5.2
      - chardet==5.2.0
      - charset-normalizer==3.4.1
      - colorama==0.4.6
      - debut==0.9.9
      - dill==0.3.7
      - distlib==0.3.9
      - docker==4.4.4
      - dockerfile-parse==0.0.18
      - dodgy==0.2.1
      - exceptiongroup==1.2.2
      - filelock==3.12.2
      - flake8==3.9.2
      - flake8-polyfill==1.0.2
      - gitdb2==2.0.6
      - gitpython==2.1.15
      - idna==3.10
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - isort==5.11.5
      - lazy-object-proxy==1.9.0
      - markdown-it-py==2.2.0
      - mccabe==0.6.1
      - mdurl==0.1.2
      - packaging==24.0
      - pbr==6.1.1
      - pep8-naming==0.10.0
      - platformdirs==4.0.0
      - pluggy==1.2.0
      - prospector==1.7.7
      - pycodestyle==2.7.0
      - pydocstyle==6.1.1
      - pyflakes==2.3.1
      - pygments==2.17.2
      - pylint==2.17.7
      - pylint-celery==0.3
      - pylint-django==2.5.3
      - pylint-flask==0.6
      - pylint-plugin-utils==0.7
      - pyproject-api==1.5.3
      - pytest==7.4.4
      - pyyaml==6.0.1
      - regex==2024.4.16
      - requests==2.31.0
      - requirements-detector==0.7
      - rich==13.8.1
      - setoptconf-tmp==0.3.1
      - six==1.17.0
      - smmap==5.0.2
      - smmap2==3.0.1
      - snowballstemmer==2.2.0
      - stevedore==3.5.2
      - toml==0.10.2
      - tomli==2.0.1
      - tomlkit==0.12.5
      - tox==4.8.0
      - typed-ast==1.5.5
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - virtualenv==20.26.6
      - websocket-client==1.6.1
      - wrapt==1.16.0
      - zipp==3.15.0
prefix: /opt/conda/envs/tern

tests/test_analyze_common.py::TestAnalyzeCommon::testGetShellCommands
tests/test_analyze_common.py::TestAnalyzeCommon::testConsolidateCommandsWithDifferentCommands tests/test_analyze_common.py::TestAnalyzeCommon::testConsolidateCommandsWithSameCommands tests/test_analyze_common.py::TestAnalyzeCommon::testFilterInstallCommands tests/test_analyze_common.py::TestAnalyzeCommon::testGetGitURL tests/test_analyze_common.py::TestAnalyzeCommon::testGetInstalledPackageNamesWithInstallFlag tests/test_analyze_common.py::TestAnalyzeCommon::testGetInstalledPackageNamesWithRemoveFlag tests/test_analyze_common.py::TestAnalyzeCommon::testLoadFilesFromCache tests/test_analyze_common.py::TestAnalyzeCommon::testLoadFromCache tests/test_analyze_common.py::TestAnalyzeCommon::testLoadNoticesFromCache tests/test_analyze_common.py::TestAnalyzeCommon::testLoadPackagesFromCache tests/test_analyze_common.py::TestAnalyzeCommon::testRemoveIgnoredCommandsWithIgnoreFlag tests/test_analyze_common.py::TestAnalyzeCommon::testRemoveIgnoredCommandsWithoutIgnoreFlag tests/test_analyze_common.py::TestAnalyzeCommon::testRemoveUnrecognizedCommandsWithFlag tests/test_analyze_common.py::TestAnalyzeCommon::testRemoveUnrecognizedCommandsWithoutFlag tests/test_analyze_common.py::TestAnalyzeCommon::testSaveToCache tests/test_analyze_common.py::TestAnalyzeCommon::testUpdateMasterListWithPackages tests/test_analyze_common.py::TestAnalyzeCommon::testUpdateMasterListWithoutPackages
tern/analyze/common.py
tern/analyze/common.py