title: Bazel combine multiple rules in macro
body: <p>My project structure has multiple sub-modules within it, these are essentially folders that are projects within their own right too.</p>
  
  <p>For a given python project, each with sub projects. I would like to be able to write a macro that can create a set of actions to be taken on a given sub-project.</p>
  
  <p>Essentially something along these lines inside the WORKSPACE:</p>
  
  <pre><code>load("@io_bazel_rules_python//:python/pip.bzl",
     "pip_import"
  )
  
  pip_import(
     name = "foo",
     requirements = "@subprojectname//:requirements.txt",
  )
  
  load("@foo//:requirements.bzl", "pip_install")
  pip_install()
  </code></pre>
  
  <p>There are multiple sub-projects I would like to do the above actions for.  However, if I put all the code into a function inside a bzl file. </p>
  
  <p>pyrules.bzl </p>
  
  <pre><code>load("@io_bazel_rules_python//:python/pip.bzl",
     "pip_import"
  )
  
  
  def doit(name):
      pip_import(
         name = "foo",
         requirements = "@{repo}//:requirements.txt".format(repo=name)
      )
  
      load("@foo//:requirements.bzl", "pip_install")
      pip_install()
  </code></pre>
  
  <p>I cannot use the second, load command due to "syntax error at 'load': expected expression". Without then having multiple bzl files that are loaded into the parent WORKSPACE, is there any other way to create reusable chunks of logic?</p>
  
  <p><strong>Update 1.</strong>
  Comments requested more information on the workflow. Warning, I have a non standard layout to how Bazel seems to be used else where i.e. not a monorepo. But it should come to a similar practical layout. </p>
  
  <p>Projects are laid out as:</p>
  
  <pre><code>projectname/
      WORKSPACE
      BUILD
      src/
         stuff
      submodule/ # &lt; git modules that are checked out into folder
          subproject1/
              BUILD
              src/
                  stuff
          subproject2/
              BUILD
              src/ 
                  stuff
  </code></pre>
  
  <p>Firstly, I have a repository_rule that is loaded in the WORKSPACE that finds all projects in the submodule folder and adds them as repositories. Within the subproject, some of these are python. I would like to load its requirements.txt files. Hence the overall question of where these requirements.txt files are and doing a pip install on them. Ideally I would like the py_library definitions in the subprojects BUILD files to know that there is a dependency on the requirements file of the subproject, but this likely doesn't matter as the parent BUILD file is the only thing that creates par_binaries and so on, so as long as the pip_install and setting the dependencies happens, the project itself should be usable. </p>
  
  <p>Bazel doesn't appear to allow a child project to define their own repository actions like the above pip_install. I assume this is because you cant have repository actions in a BUILD file, and child WORKSPACE files don't seem to have any effect. So I ended up having to add this to the parent WORKSPACE file. </p>
  
  <p>If it is in the parent WORKSPACE, I have to copy paste the pip actions for each of the subprojects I want to use.  However, I would prefer to just set up a general rule which would locate the requirements file and pip install them. Trying to make a macro from this however means that I cannot use the load call within it. All the pip  actions seem to need to interact with repository actions which then need to be called only from a parent WORKSPACE file. </p>