Просмотр исходного кода

Merge pull request #3136 from dnephin/add_workdir_to_run

Add workdir to run
Aanand Prasad 10 лет назад
Родитель
Сommit
1696506ff4

+ 41 - 32
compose/cli/main.py

@@ -527,6 +527,7 @@ class TopLevelCommand(object):
                                   to the host.
             -T                    Disable pseudo-tty allocation. By default `docker-compose run`
                                   allocates a TTY.
+            -w, --workdir=""      Working directory inside the container
         """
         service = self.project.get_service(options['SERVICE'])
         detach = options['-d']
@@ -537,45 +538,18 @@ class TopLevelCommand(object):
                 "Please pass the -d flag when using `docker-compose run`."
             )
 
-        if options['COMMAND']:
-            command = [options['COMMAND']] + options['ARGS']
-        else:
-            command = service.options.get('command')
-
-        container_options = {
-            'command': command,
-            'tty': not (detach or options['-T'] or not sys.stdin.isatty()),
-            'stdin_open': not detach,
-            'detach': detach,
-        }
-
-        if options['-e']:
-            container_options['environment'] = parse_environment(options['-e'])
-
-        if options['--entrypoint']:
-            container_options['entrypoint'] = options.get('--entrypoint')
-
-        if options['--rm']:
-            container_options['restart'] = None
-
-        if options['--user']:
-            container_options['user'] = options.get('--user')
-
-        if not options['--service-ports']:
-            container_options['ports'] = []
-
-        if options['--publish']:
-            container_options['ports'] = options.get('--publish')
-
         if options['--publish'] and options['--service-ports']:
             raise UserError(
                 'Service port mapping and manual port mapping '
                 'can not be used togather'
             )
 
-        if options['--name']:
-            container_options['name'] = options['--name']
+        if options['COMMAND']:
+            command = [options['COMMAND']] + options['ARGS']
+        else:
+            command = service.options.get('command')
 
+        container_options = build_container_options(options, detach, command)
         run_one_off_container(container_options, self.project, service, options)
 
     def scale(self, options):
@@ -776,6 +750,41 @@ def build_action_from_opts(options):
     return BuildAction.none
 
 
+def build_container_options(options, detach, command):
+    container_options = {
+        'command': command,
+        'tty': not (detach or options['-T'] or not sys.stdin.isatty()),
+        'stdin_open': not detach,
+        'detach': detach,
+    }
+
+    if options['-e']:
+        container_options['environment'] = parse_environment(options['-e'])
+
+    if options['--entrypoint']:
+        container_options['entrypoint'] = options.get('--entrypoint')
+
+    if options['--rm']:
+        container_options['restart'] = None
+
+    if options['--user']:
+        container_options['user'] = options.get('--user')
+
+    if not options['--service-ports']:
+        container_options['ports'] = []
+
+    if options['--publish']:
+        container_options['ports'] = options.get('--publish')
+
+    if options['--name']:
+        container_options['name'] = options['--name']
+
+    if options['--workdir']:
+        container_options['working_dir'] = options['--workdir']
+
+    return container_options
+
+
 def run_one_off_container(container_options, project, service, options):
     if not options['--no-deps']:
         deps = service.get_dependency_names()

+ 1 - 0
docs/reference/run.md

@@ -26,6 +26,7 @@ Options:
 -p, --publish=[]      Publish a container's port(s) to the host
 --service-ports       Run command with the service's ports enabled and mapped to the host.
 -T                    Disable pseudo-tty allocation. By default `docker-compose run` allocates a TTY.
+-w, --workdir=""      Working directory inside the container
 ```
 
 Runs a one-time command against a service. For example, the following command starts the `web` service and runs `bash` as its command.

+ 18 - 0
tests/acceptance/cli_test.py

@@ -1025,6 +1025,24 @@ class CLITestCase(DockerClientTestCase):
         container, = service.containers(stopped=True, one_off=True)
         self.assertEqual(container.name, name)
 
+    def test_run_service_with_workdir_overridden(self):
+        self.base_dir = 'tests/fixtures/run-workdir'
+        name = 'service'
+        workdir = '/var'
+        self.dispatch(['run', '--workdir={workdir}'.format(workdir=workdir), name])
+        service = self.project.get_service(name)
+        container = service.containers(stopped=True, one_off=True)[0]
+        self.assertEqual(workdir, container.get('Config.WorkingDir'))
+
+    def test_run_service_with_workdir_overridden_short_form(self):
+        self.base_dir = 'tests/fixtures/run-workdir'
+        name = 'service'
+        workdir = '/var'
+        self.dispatch(['run', '-w', workdir, name])
+        service = self.project.get_service(name)
+        container = service.containers(stopped=True, one_off=True)[0]
+        self.assertEqual(workdir, container.get('Config.WorkingDir'))
+
     @v2_only()
     def test_run_interactive_connects_to_network(self):
         self.base_dir = 'tests/fixtures/networks'

+ 4 - 0
tests/fixtures/run-workdir/docker-compose.yml

@@ -0,0 +1,4 @@
+service:
+  image: busybox:latest
+  working_dir: /etc
+  command: /bin/true

+ 3 - 0
tests/unit/cli_test.py

@@ -102,6 +102,7 @@ class CLITestCase(unittest.TestCase):
                 '--publish': [],
                 '--rm': None,
                 '--name': None,
+                '--workdir': None,
             })
 
         _, _, call_kwargs = mock_run_operation.mock_calls[0]
@@ -135,6 +136,7 @@ class CLITestCase(unittest.TestCase):
             '--publish': [],
             '--rm': None,
             '--name': None,
+            '--workdir': None,
         })
 
         self.assertEquals(
@@ -156,6 +158,7 @@ class CLITestCase(unittest.TestCase):
             '--publish': [],
             '--rm': True,
             '--name': None,
+            '--workdir': None,
         })
 
         self.assertFalse(