Repository: buildbot/buildbot

Issue:
Giving a Property as workersrcs to MultipleFileUpload breaks
This issue was introduced by 4173daceb97c6e2583e7be9bc63ed4dcf7ba8f2e.

I give a Property parameter to MultipleFileUploads, the property resolves to a list.

Due to the mentioned commit, The value is now a list of list, and this breaks.

``` pytb
2017-05-02 12:55:50+0200 [-] MultipleFileUpload started, from worker [[u'build/filename']] to master '/home/buildsystem/master/public_html/destination'
2017-05-02 12:55:50+0200 [-] BuildStep.failed; traceback follows
        Traceback (most recent call last):
          File "/home/buildsystem/bb-master/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1357, in gotResult
            _inlineCallbacks(r, g, deferred)
          File "/home/buildsystem/bb-master/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1301, in _inlineCallbacks
            result = g.send(result)
          File "/home/buildsystem/bb-master/local/lib/python2.7/site-packages/buildbot/process/buildstep.py", line 547, in startStep
            self.results = yield self.run()
          File "/home/buildsystem/bb-master/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1447, in unwindGenerator
            return _inlineCallbacks(None, gen, Deferred())
        --- <exception caught here> ---
          File "/home/buildsystem/bb-master/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1301, in _inlineCallbacks
            result = g.send(result)
          File "/home/buildsystem/bb-master/local/lib/python2.7/site-packages/buildbot/process/buildstep.py", line 677, in run
            results = yield self._start_deferred
        exceptions.AttributeError: 'list' object has no attribute 'rfind'
```


Discussion:
@noc0lour
I'd be in favor of reverting the said commit. Why should ``MultipleFileUploads`` be able to **magically** behave as if it weren't *Multiple* ?
I think we can easily add
```and not IRenderable.providedBy(workersrc))```
like in https://github.com/buildbot/buildbot/blob/master/master/buildbot/steps/cmake.py#L52

The commit is part of the more general and useful PR: 

transfer: add glob parameter to MultipleFileUpload #2635

If we do that the given renderable will **have to** render as a list. Bypassing the magical part (i.e. a property that render as a string will not work). IMHO, glob support (granted, useful) doesn't require the type of the parameter to be a string. Additionally, it's not even documented that a string can be given as parameter. Lastly, even the tests don't exerce the combination glob + string.
@benallard make sense.  @noc0lour please defend your design :)
I don't see why `MultipleFileUpload` shouldn't be able to upload just one file. e.g. your `renderable` returns only one item or `None`. 
Probably this check is better placed `start()`. 
Can you add the test? I'll submit a PR with a proposed fix which should resolve your issue.

Resolving patch:
diff --git a/master/buildbot/steps/transfer.py b/master/buildbot/steps/transfer.py
--- a/master/buildbot/steps/transfer.py
+++ b/master/buildbot/steps/transfer.py
@@ -294,7 +294,7 @@ def __init__(self, workersrcs=None, masterdest=None,
 
         _TransferBuildStep.__init__(self, workdir=workdir, **buildstep_kwargs)
 
-        self.workersrcs = workersrcs if isinstance(workersrcs, list) else [workersrcs]
+        self.workersrcs = workersrcs
         self._registerOldWorkerAttr("workersrcs")
         self.masterdest = masterdest
         self.maxsize = maxsize
@@ -394,7 +394,7 @@ def start(self):
         self.checkWorkerHasCommand("stat")
 
         masterdest = os.path.expanduser(self.masterdest)
-        sources = self.workersrcs
+        sources = self.workersrcs if isinstance(self.workersrcs, list) else [self.workersrcs]
 
         if self.keepstamp and self.workerVersionIsOlderThan("uploadFile", "2.13"):
             m = ("This worker (%s) does not support preserving timestamps. "


Test patch: