diff --git a/Dockerfile b/Dockerfile
index c43d93e..c6d23f4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM alpine:3.3
+FROM alpine:3.5
 RUN apk add --update sudo bash py-setuptools git && rm -rf /var/cache/apk/*
 
 ENV DOGEN_VERSION master
diff --git a/dogen/generator.py b/dogen/generator.py
index 7205db8..7e10cc5 100644
--- a/dogen/generator.py
+++ b/dogen/generator.py
@@ -48,12 +48,12 @@ class Generator(object):
         self.ssl_verify to False.
         """
 
-        self.log.debug("Fetching '%s' file..." % location)
+        self.log.info("Fetching '%s' file..." % location)
 
         if not output:
             output = tempfile.mktemp("-dogen")
 
-        self.log.debug("Fetched file will be saved as '%s'..." % output)
+        self.log.info("Fetched file will be saved as '%s'..." % os.path.basename(output))
 
         with open(output, 'wb') as f:
             f.write(requests.get(location, verify=self.ssl_verify).content)
@@ -289,7 +289,14 @@ class Generator(object):
 
         for source in self.cfg['sources']:
             url = source['url']
+            target = source.get('target')
+
             basename = os.path.basename(url)
+
+            # In case we specify target name for the artifact - use it
+            if target:
+                basename = target
+
             files.append(basename)
             filename = ("%s/%s" % (self.output, basename))
             passed = False
@@ -297,7 +304,8 @@ class Generator(object):
                 if os.path.exists(filename):
                     self.check_sum(filename, source['md5sum'])
                     passed = True
-            except:
+            except Exception as e:
+                self.log.warn(str(e))
                 passed = False
 
             if not passed:
@@ -306,9 +314,7 @@ class Generator(object):
                     self.log.info("Using '%s' as cached location for sources" % sources_cache)
                     url = "%s/%s" % (sources_cache, basename)
 
-                self.log.info("Downloading '%s'..." % url)
-                with open(filename, 'wb') as f:
-                    f.write(requests.get(url, verify=self.ssl_verify).content)
+                self._fetch_file(url, filename)
                 self.check_sum(filename, source['md5sum'])
 
         return files
diff --git a/dogen/schema/kwalify_schema.yaml b/dogen/schema/kwalify_schema.yaml
index 628631b..d308680 100644
--- a/dogen/schema/kwalify_schema.yaml
+++ b/dogen/schema/kwalify_schema.yaml
@@ -63,6 +63,7 @@ map:
       - map:
           url: {type: str}
           md5sum: {type: str}
+          target: {type: str}
   packages:
     seq:
       - {type: str}

Make it possible to rename the target artifact
diff --git a/tests/test_unit_generate_configuration.py b/tests/test_unit_generate_configuration.py
index adcbafd..bf26c55 100644
--- a/tests/test_unit_generate_configuration.py
+++ b/tests/test_unit_generate_configuration.py
@@ -262,3 +262,53 @@ class TestConfig(unittest.TestCase):
         generator.configure()
         generator._handle_scripts()
         # success if no stack trace thrown
+
+    @mock.patch('dogen.generator.Generator.check_sum')
+    @mock.patch('dogen.generator.Generator._fetch_file')
+    def test_handling_sources(self, mock_fetch_file, mock_check_sum):
+        with self.descriptor as f:
+            f.write("sources:\n  - url: http://somehost.com/file.zip\n    md5sum: e9013fc202c87be48e3b302df10efc4b".encode())
+
+        generator = Generator(self.log, self.args)
+        generator.configure()
+        generator.handle_sources()
+
+        mock_fetch_file.assert_called_with('http://somehost.com/file.zip', 'target/file.zip')
+
+    @mock.patch('dogen.generator.os.path.exists', return_value=True)
+    @mock.patch('dogen.generator.Generator.check_sum')
+    @mock.patch('dogen.generator.Generator._fetch_file')
+    def test_handling_sources_when_local_file_exists_and_is_correct(self, mock_fetch_file, mock_check_sum, mock_path):
+        with self.descriptor as f:
+            f.write("sources:\n  - url: http://somehost.com/file.zip\n    md5sum: e9013fc202c87be48e3b302df10efc4b".encode())
+
+        generator = Generator(self.log, self.args)
+        generator.configure()
+        generator.handle_sources()
+
+        self.assertEqual(mock_fetch_file.call_count, 0)
+
+    @mock.patch('dogen.generator.os.path.exists', return_value=True)
+    @mock.patch('dogen.generator.Generator.check_sum', side_effect=[Exception("Bleh"), None])
+    @mock.patch('dogen.generator.Generator._fetch_file')
+    def test_handling_sources_when_local_file_exists_and_is_broken(self, mock_fetch_file, mock_check_sum, mock_path):
+        with self.descriptor as f:
+            f.write("sources:\n  - url: http://somehost.com/file.zip\n    md5sum: e9013fc202c87be48e3b302df10efc4b".encode())
+
+        generator = Generator(self.log, self.args)
+        generator.configure()
+        generator.handle_sources()
+
+        mock_fetch_file.assert_called_with('http://somehost.com/file.zip', 'target/file.zip')
+
+    @mock.patch('dogen.generator.Generator.check_sum')
+    @mock.patch('dogen.generator.Generator._fetch_file')
+    def test_handling_sources_with_target_filename(self, mock_fetch_file, mock_check_sum):
+        with self.descriptor as f:
+            f.write("sources:\n  - url: http://somehost.com/file.zip\n    md5sum: e9013fc202c87be48e3b302df10efc4b\n    target: target.zip".encode())
+
+        generator = Generator(self.log, self.args)
+        generator.configure()
+        generator.handle_sources()
+
+        mock_fetch_file.assert_called_with('http://somehost.com/file.zip', 'target/target.zip')
diff --git a/tests/test_unit_generate_handle_files.py b/tests/test_unit_generate_handle_files.py
index 51bd803..749eee1 100644
--- a/tests/test_unit_generate_handle_files.py
+++ b/tests/test_unit_generate_handle_files.py
@@ -41,8 +41,8 @@ class TestFetchFile(unittest.TestCase):
             mock_requests.assert_called_with('https://host/file.tmp', verify=None)
             mock_file().write.assert_called_once_with("file-content")
 
-        self.log.debug.assert_any_call("Fetching 'https://host/file.tmp' file...")
-        self.log.debug.assert_any_call("Fetched file will be saved as 'some-file'...")
+        self.log.info.assert_any_call("Fetching 'https://host/file.tmp' file...")
+        self.log.info.assert_any_call("Fetched file will be saved as 'some-file'...")
 
 
     @mock.patch('dogen.generator.tempfile.mktemp', return_value="tmpfile")
@@ -56,8 +56,8 @@ class TestFetchFile(unittest.TestCase):
             mock_requests.assert_called_with('https://host/file.tmp', verify=None)
             mock_file().write.assert_called_once_with("file-content")
 
-        self.log.debug.assert_any_call("Fetching 'https://host/file.tmp' file...")
-        self.log.debug.assert_any_call("Fetched file will be saved as 'tmpfile'...")
+        self.log.info.assert_any_call("Fetching 'https://host/file.tmp' file...")
+        self.log.info.assert_any_call("Fetched file will be saved as 'tmpfile'...")
 
 class TestCustomTemplateHandling(unittest.TestCase):
     def setUp(self):

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov mock
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi==2025.1.31
charset-normalizer==3.4.1
coverage==7.8.0
docopt==0.6.2
-e git+https://github.com/jboss-dockerfiles/dogen.git@fca08f2027ef422c447cfd0f0def681b88a31890#egg=dogen
exceptiongroup==1.2.2
idna==3.10
iniconfig==2.1.0
Jinja2==3.1.6
MarkupSafe==3.0.2
mock==5.2.0
packaging==24.2
pluggy==1.5.0
pykwalify==1.8.0
pytest==8.3.5
pytest-cov==6.0.0
python-dateutil==2.9.0.post0
PyYAML==6.0.2
requests==2.32.3
ruamel.yaml==0.18.10
ruamel.yaml.clib==0.2.12
six==1.17.0
tomli==2.2.1
urllib3==2.3.0

name: dogen
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - coverage==7.8.0
      - docopt==0.6.2
      - exceptiongroup==1.2.2
      - idna==3.10
      - iniconfig==2.1.0
      - jinja2==3.1.6
      - markupsafe==3.0.2
      - mock==5.2.0
      - packaging==24.2
      - pluggy==1.5.0
      - pykwalify==1.8.0
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - python-dateutil==2.9.0.post0
      - pyyaml==6.0.2
      - requests==2.32.3
      - ruamel-yaml==0.18.10
      - ruamel-yaml-clib==0.2.12
      - six==1.17.0
      - tomli==2.2.1
      - urllib3==2.3.0
prefix: /opt/conda/envs/dogen

tests/test_unit_generate_configuration.py::TestConfig::test_handling_sources tests/test_unit_generate_configuration.py::TestConfig::test_handling_sources_when_local_file_exists_and_is_broken tests/test_unit_generate_configuration.py::TestConfig::test_handling_sources_with_target_filename tests/test_unit_generate_handle_files.py::TestFetchFile::test_fetching_with_filename tests/test_unit_generate_handle_files.py::TestFetchFile::test_fetching_with_tmpfile
tests/test_unit_generate_configuration.py::TestConfig::test_custom_additional_scripts_in_cli_should_override_in_descriptor tests/test_unit_generate_configuration.py::TestConfig::test_custom_additional_scripts_in_descriptor tests/test_unit_generate_configuration.py::TestConfig::test_custom_script_exec tests/test_unit_generate_configuration.py::TestConfig::test_custom_script_exec_not_env tests/test_unit_generate_configuration.py::TestConfig::test_custom_script_user_not_default tests/test_unit_generate_configuration.py::TestConfig::test_custom_script_user_not_env tests/test_unit_generate_configuration.py::TestConfig::test_custom_scripts_dir_in_cli_should_override_in_descriptor tests/test_unit_generate_configuration.py::TestConfig::test_custom_scripts_dir_in_descriptor tests/test_unit_generate_configuration.py::TestConfig::test_custom_template_in_cli_should_override_in_descriptor tests/test_unit_generate_configuration.py::TestConfig::test_custom_template_in_descriptor tests/test_unit_generate_configuration.py::TestConfig::test_default_script_exec tests/test_unit_generate_configuration.py::TestConfig::test_default_script_user tests/test_unit_generate_configuration.py::TestConfig::test_default_values tests/test_unit_generate_configuration.py::TestConfig::test_do_not_skip_ssl_verification_in_cli_false_should_override_descriptor tests/test_unit_generate_configuration.py::TestConfig::test_do_not_skip_ssl_verification_in_descriptor tests/test_unit_generate_configuration.py::TestConfig::test_env_provided_script_user tests/test_unit_generate_configuration.py::TestConfig::test_env_supplied_script_exec tests/test_unit_generate_configuration.py::TestConfig::test_fail_if_version_mismatch tests/test_unit_generate_configuration.py::TestConfig::test_handling_sources_when_local_file_exists_and_is_correct tests/test_unit_generate_configuration.py::TestConfig::test_no_scripts_defined tests/test_unit_generate_configuration.py::TestConfig::test_scripts_dir_found_by_convention tests/test_unit_generate_configuration.py::TestConfig::test_skip_ssl_verification_in_descriptor tests/test_unit_generate_handle_files.py::TestURL::test_local_file tests/test_unit_generate_handle_files.py::TestURL::test_remote_http_file tests/test_unit_generate_handle_files.py::TestURL::test_remote_https_file tests/test_unit_generate_handle_files.py::TestCustomTemplateHandling::test_do_not_fail_if_no_template_is_provided tests/test_unit_generate_handle_files.py::TestCustomTemplateHandling::test_fetch_template_success tests/test_unit_generate_handle_files.py::TestCustomTemplateHandling::test_fetch_template_with_error
dogen/schema/kwalify_schema.yaml Dockerfile dogen/generator.py
dogen/schema/kwalify_schema.yaml Dockerfile dogen/generator.py