prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Local runner should write makefile to temporary dir
  Instead, it writes it to the `root_uri` which might be an S3 URI, and `make`, which is used by the local runner cannot handle that.
  Makefile error when `root_uri` is an S3 path
  ## 🐛 Bug
  When running training command and having `root_uri` set to an S3 folder, this error shows up:
  ```
  make: s3://<random_bucket_name>/predictions/Makefile: No such file or directory
  make: *** No rule to make target 's3://<random_bucket_name>/predictions/Makefile'.  Stop.
  ```
  
  This error disappears when `root_uri` is a local path. AWS config is right as it is able to read and write the files.
  
  ## To Reproduce
  
  Steps to reproduce the behavior:
  
  1. I ran the following command inside the container:
  `python -m rastervision.pipeline.cli run local code/local_exp.py -a raw_uri s3://<random_bucket_name>/datafortesting/data/ -a root_uri s3://<random_bucket_name>/predictions -a test False`
  
  <!-- Please provide the command executed, source of the get_config() function, error messages, and/or full stack traces if at all possible -->
  
  ## Expected behavior
  
  It should run normally like it is running when `root_uri` is a local path.
  
  ## Environment
  
  Running with docker.  **Image**: quay.io/azavea/raster-vision:pytorch-v0.13.1
  
  ## Additional context
  
  This might be a relevant issue: #991 
  
  
  </issue>
  <code>
  [start of rastervision_pipeline/rastervision/pipeline/runner/local_runner.py]
  1 import sys
  2 from os.path import dirname, join
  3 from subprocess import Popen
  4 
  5 from rastervision.pipeline.file_system import str_to_file
  6 from rastervision.pipeline.runner.runner import Runner
  7 from rastervision.pipeline.utils import terminate_at_exit
  8 
  9 LOCAL = 'local'
  10 
  11 
  12 class LocalRunner(Runner):
  13     """Runs each command locally using different processes for each command/split.
  14 
  15     This is implemented by generating a Makefile and then running it using make.
  16     """
  17 
  18     def run(self,
  19             cfg_json_uri,
  20             pipeline,
  21             commands,
  22             num_splits=1,
  23             pipeline_run_name: str = 'raster-vision'):
  24         num_commands = 0
  25         for command in commands:
  26             if command in pipeline.split_commands and num_splits > 1:
  27                 num_commands += num_splits
  28             else:
  29                 num_commands += 1
  30 
  31         makefile = '.PHONY: '
  32         makefile += ' '.join([str(ci) for ci in range(num_commands)])
  33         makefile += '\n\n'
  34 
  35         makefile += 'all: '
  36         makefile += ' '.join([str(ci) for ci in range(num_commands)])
  37         makefile += '\n\n'
  38 
  39         prev_command_inds = []
  40         curr_command_ind = 0
  41         for command in commands:
  42 
  43             curr_command_inds = []
  44             if command in pipeline.split_commands and num_splits > 1:
  45                 for split_ind in range(num_splits):
  46                     makefile += '{}: '.format(curr_command_ind)
  47                     makefile += ' '.join([str(ci) for ci in prev_command_inds])
  48                     makefile += '\n'
  49                     invocation = (
  50                         'python -m rastervision.pipeline.cli run_command '
  51                         '{} {} --split-ind {} --num-splits {}').format(
  52                             cfg_json_uri, command, split_ind, num_splits)
  53                     makefile += '\t{}\n\n'.format(invocation)
  54                     curr_command_inds.append(curr_command_ind)
  55                     curr_command_ind += 1
  56             else:
  57                 makefile += '{}: '.format(curr_command_ind)
  58                 makefile += ' '.join([str(ci) for ci in prev_command_inds])
  59                 makefile += '\n'
  60                 invocation = (
  61                     'python -m rastervision.pipeline.cli run_command '
  62                     '{} {}'.format(cfg_json_uri, command))
  63                 makefile += '\t{}\n\n'.format(invocation)
  64                 curr_command_inds.append(curr_command_ind)
  65                 curr_command_ind += 1
  66 
  67             prev_command_inds = curr_command_inds
  68 
  69         makefile_path = join(dirname(cfg_json_uri), 'Makefile')
  70         str_to_file(makefile, makefile_path)
  71         process = Popen(['make', '-j', '-f', makefile_path])
  72         terminate_at_exit(process)
  73         exitcode = process.wait()
  74         if exitcode != 0:
  75             sys.exit(exitcode)
  76         else:
  77             return 0
  78
  [end of rastervision_pipeline/rastervision/pipeline/runner/local_runner.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/rastervision_pipeline/rastervision/pipeline/runner/local_runner.py b/rastervision_pipeline/rastervision/pipeline/runner/local_runner.py
  --- a/rastervision_pipeline/rastervision/pipeline/runner/local_runner.py
  +++ b/rastervision_pipeline/rastervision/pipeline/runner/local_runner.py
  @@ -2,7 +2,7 @@
   from os.path import dirname, join
   from subprocess import Popen
   
  -from rastervision.pipeline.file_system import str_to_file
  +from rastervision.pipeline.file_system import str_to_file, download_if_needed
   from rastervision.pipeline.runner.runner import Runner
   from rastervision.pipeline.utils import terminate_at_exit
   
  @@ -68,7 +68,8 @@
   
           makefile_path = join(dirname(cfg_json_uri), 'Makefile')
           str_to_file(makefile, makefile_path)
  -        process = Popen(['make', '-j', '-f', makefile_path])
  +        makefile_path_local = download_if_needed(makefile_path)
  +        process = Popen(['make', '-j', '-f', makefile_path_local])
           terminate_at_exit(process)
           exitcode = process.wait()
           if exitcode != 0:
  
verification_info: {"golden_diff": "diff --git a/rastervision_pipeline/rastervision/pipeline/runner/local_runner.py b/rastervision_pipeline/rastervision/pipeline/runner/local_runner.py\n--- a/rastervision_pipeline/rastervision/pipeline/runner/local_runner.py\n+++ b/rastervision_pipeline/rastervision/pipeline/runner/local_runner.py\n@@ -2,7 +2,7 @@\n from os.path import dirname, join\n from subprocess import Popen\n \n-from rastervision.pipeline.file_system import str_to_file\n+from rastervision.pipeline.file_system import str_to_file, download_if_needed\n from rastervision.pipeline.runner.runner import Runner\n from rastervision.pipeline.utils import terminate_at_exit\n \n@@ -68,7 +68,8 @@\n \n         makefile_path = join(dirname(cfg_json_uri), 'Makefile')\n         str_to_file(makefile, makefile_path)\n-        process = Popen(['make', '-j', '-f', makefile_path])\n+        makefile_path_local = download_if_needed(makefile_path)\n+        process = Popen(['make', '-j', '-f', makefile_path_local])\n         terminate_at_exit(process)\n         exitcode = process.wait()\n         if exitcode != 0:\n", "issue": "Local runner should write makefile to temporary dir\nInstead, it writes it to the `root_uri` which might be an S3 URI, and `make`, which is used by the local runner cannot handle that.\nMakefile error when `root_uri` is an S3 path\n## \ud83d\udc1b Bug\r\nWhen running training command and having `root_uri` set to an S3 folder, this error shows up:\r\n```\r\nmake: s3://<random_bucket_name>/predictions/Makefile: No such file or directory\r\nmake: *** No rule to make target 's3://<random_bucket_name>/predictions/Makefile'.  Stop.\r\n```\r\n\r\nThis error disappears when `root_uri` is a local path. AWS config is right as it is able to read and write the files.\r\n\r\n## To Reproduce\r\n\r\nSteps to reproduce the behavior:\r\n\r\n1. I ran the following command inside the container:\r\n`python -m rastervision.pipeline.cli run local code/local_exp.py -a raw_uri s3://<random_bucket_name>/datafortesting/data/ -a root_uri s3://<random_bucket_name>/predictions -a test False`\r\n\r\n<!-- Please provide the command executed, source of the get_config() function, error messages, and/or full stack traces if at all possible -->\r\n\r\n## Expected behavior\r\n\r\nIt should run normally like it is running when `root_uri` is a local path.\r\n\r\n## Environment\r\n\r\nRunning with docker.  **Image**: quay.io/azavea/raster-vision:pytorch-v0.13.1\r\n\r\n## Additional context\r\n\r\nThis might be a relevant issue: #991 \r\n\n", "before_files": [{"content": "import sys\nfrom os.path import dirname, join\nfrom subprocess import Popen\n\nfrom rastervision.pipeline.file_system import str_to_file\nfrom rastervision.pipeline.runner.runner import Runner\nfrom rastervision.pipeline.utils import terminate_at_exit\n\nLOCAL = 'local'\n\n\nclass LocalRunner(Runner):\n    \"\"\"Runs each command locally using different processes for each command/split.\n\n    This is implemented by generating a Makefile and then running it using make.\n    \"\"\"\n\n    def run(self,\n            cfg_json_uri,\n            pipeline,\n            commands,\n            num_splits=1,\n            pipeline_run_name: str = 'raster-vision'):\n        num_commands = 0\n        for command in commands:\n            if command in pipeline.split_commands and num_splits > 1:\n                num_commands += num_splits\n            else:\n                num_commands += 1\n\n        makefile = '.PHONY: '\n        makefile += ' '.join([str(ci) for ci in range(num_commands)])\n        makefile += '\\n\\n'\n\n        makefile += 'all: '\n        makefile += ' '.join([str(ci) for ci in range(num_commands)])\n        makefile += '\\n\\n'\n\n        prev_command_inds = []\n        curr_command_ind = 0\n        for command in commands:\n\n            curr_command_inds = []\n            if command in pipeline.split_commands and num_splits > 1:\n                for split_ind in range(num_splits):\n                    makefile += '{}: '.format(curr_command_ind)\n                    makefile += ' '.join([str(ci) for ci in prev_command_inds])\n                    makefile += '\\n'\n                    invocation = (\n                        'python -m rastervision.pipeline.cli run_command '\n                        '{} {} --split-ind {} --num-splits {}').format(\n                            cfg_json_uri, command, split_ind, num_splits)\n                    makefile += '\\t{}\\n\\n'.format(invocation)\n                    curr_command_inds.append(curr_command_ind)\n                    curr_command_ind += 1\n            else:\n                makefile += '{}: '.format(curr_command_ind)\n                makefile += ' '.join([str(ci) for ci in prev_command_inds])\n                makefile += '\\n'\n                invocation = (\n                    'python -m rastervision.pipeline.cli run_command '\n                    '{} {}'.format(cfg_json_uri, command))\n                makefile += '\\t{}\\n\\n'.format(invocation)\n                curr_command_inds.append(curr_command_ind)\n                curr_command_ind += 1\n\n            prev_command_inds = curr_command_inds\n\n        makefile_path = join(dirname(cfg_json_uri), 'Makefile')\n        str_to_file(makefile, makefile_path)\n        process = Popen(['make', '-j', '-f', makefile_path])\n        terminate_at_exit(process)\n        exitcode = process.wait()\n        if exitcode != 0:\n            sys.exit(exitcode)\n        else:\n            return 0\n", "path": "rastervision_pipeline/rastervision/pipeline/runner/local_runner.py"}]}