Repository: jboss-dockerfiles/dogen

Issue:
Dogen fails if md5 is not set for 'local' artifacts
Using dogen 2.0. In my image.yaml, if I have the following:

````
sources:
    - artifact: myfile.tar.gz
````

I run dogen mounting `pwd` into /tmp/output inside the dogen container, and put the myfile.tar.gz inside the build/ folder. Dogen is invoked with /tmp/output/build as the destination folder.

I would expect that the local file myfile.tar.gz is added to the resulting image. However, dogen throws an error of not being able to find the artifact. In addition, the helpful hint on where to download it, i.e. "Please download the 'myfile.tar.gz' artifact manually and save it as '/tmp/output/build/myfile.tar.gz' is missing unless I also add the 'hint' field. 

If I do this:

```
sources:
    - artifact: myfile.tar.gz
      md5: <md5sum of myfile.tar.gz>
```

Then dogen is successful creating the Dockerfile. 

I would like to be able to omit the md5 field and still be able to generate the Dockerfile, as this is useful for generating Dockerfiles for locally built artifacts.

A detailed example can be found here: https://pastebin.com/31fqRGUa


Discussion:

Patch:
diff --git a/dogen/generator.py b/dogen/generator.py
index 0562cd8..415dcb0 100644
--- a/dogen/generator.py
+++ b/dogen/generator.py
@@ -313,9 +313,10 @@ class Generator(object):
                 algorithms.append(supported_algorithm)
 
             try:
-                if os.path.exists(filename) and algorithms:
-                    for algorithm in algorithms:
-                        self.check_sum(filename, source[algorithm], algorithm)
+                if os.path.exists(filename):
+                    if algorithms:
+                        for algorithm in algorithms:
+                            self.check_sum(filename, source[algorithm], algorithm)
                     passed = True
             except Exception as e:
                 self.log.debug(str(e))
@@ -361,7 +362,7 @@ class Generator(object):
         else:
             if hint:
                 self.log.info(hint)
-                self.log.info("Please download the '%s' artifact manually and save it as '%s'" % (artifact, filename))
+            self.log.info("Please download the '%s' artifact manually and save it as '%s'" % (artifact, filename))
             raise Error("Artifact '%s' could not be fetched!" % artifact)
 
     def check_sum(self, filename, checksum, algorithm):


Test patch:
diff --git a/tests/test_unit_generate_handle_files.py b/tests/test_unit_generate_handle_files.py
index daf240a..e811ebb 100644
--- a/tests/test_unit_generate_handle_files.py
+++ b/tests/test_unit_generate_handle_files.py
@@ -155,6 +155,17 @@ class TestHandleSources(unittest.TestCase):
         self.assertEquals(str(cm.exception), "Could not download artifact from orignal location, reason: original")
         mock_fetch_file.assert_has_calls([mock.call('http://cache/get?#algorithm#=#hash#', 'target/jboss-eap.zip'), mock.call('http://host.com/jboss-eap.zip', 'target/jboss-eap.zip')])
 
+    @mock.patch('dogen.generator.Generator._fetch_file')
+    def test_fetch_artifact_should_fail_with_nice_message_when_artifact_without_url_is_not_found_locally(self, mock_fetch_file):
+        self.generator.cfg = {'sources': [{'artifact': 'jboss-eap.zip'}]}
+
+        with self.assertRaises(Error) as cm:
+            self.generator.handle_sources()
+
+        self.assertEquals(str(cm.exception), "Artifact 'jboss-eap.zip' could not be fetched!")
+        mock_fetch_file.assert_not_called()
+        self.log.info.assert_any_call("Please download the 'jboss-eap.zip' artifact manually and save it as 'target/jboss-eap.zip'")
+
     @mock.patch('dogen.generator.Generator._fetch_file')
     def test_fetch_artifact_should_fetch_file_from_cache(self, mock_fetch_file):
         self.generator.cfg = {'sources': [{'artifact': 'http://host.com/jboss-eap.zip'}]}
@@ -169,7 +180,8 @@ class TestHandleSources(unittest.TestCase):
         mock_fetch_file.assert_called_with('http://cache/get?jboss-eap.zip', 'target/jboss-eap.zip')
 
     @mock.patch('dogen.generator.Generator._fetch_file')
-    def test_fetch_artifact_should_fetch_file(self, mock_fetch_file):
+    @mock.patch('dogen.generator.os.path.exists', return_value=False)
+    def test_fetch_artifact_should_fetch_file(self, mock_path_exists, mock_fetch_file):
         self.generator.cfg = {'sources': [{'artifact': 'http://host.com/jboss-eap.zip'}]}
         self.generator.handle_sources()
         # No checksum provided and computed
@@ -187,3 +199,12 @@ class TestHandleSources(unittest.TestCase):
 
         self.assertEquals(self.generator.cfg['artifacts'], {'jboss-eap.zip': None})
         mock_fetch_file.assert_has_calls([mock.call('http://cache/get?#algorithm#=#hash#', 'target/jboss-eap.zip'), mock.call('http://host.com/jboss-eap.zip', 'target/jboss-eap.zip')])
+
+    @mock.patch('dogen.generator.Generator._fetch_file')
+    @mock.patch('dogen.generator.os.path.exists', return_value=True)
+    def test_fetch_artifact_should_not_fetch_file_if_exists(self, mock_path_exists, mock_fetch_file):
+        self.generator.cfg = {'sources': [{'artifact': 'http://host.com/jboss-eap.zip'}]}
+        self.generator.handle_sources()
+        # No checksum provided and computed
+        self.assertEquals(self.generator.cfg['artifacts'], {'jboss-eap.zip': None})
+        mock_fetch_file.assert_not_called()