Repository: raiden-network/raiden-contracts

Issue:
join-contracts.py should complain about  missing imports
Currently, `join-contracts.py` succeeds silently when some of the imported files are not found. This issue keeps track of making `join-contracts.py` fail for missing imports.


#### Current behavior
`TokenNetwork.sol` imports many contracts, but it gets smaller after `join-contracts.py` processing.

```
$ utils/join-contracts.py contracts/TokenNetwork.sol flat.sol && wc -l contracts/TokenNetwork.sol flat.sol
Reading contracts/TokenNetwork.sol
  1684 contracts/TokenNetwork.sol
  1679 flat.sol
  3363 total
```

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=h1) Report
> Merging [#1213](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=desc) into [master](https://codecov.io/gh/raiden-network/raiden-contracts/commit/a1993ade92c46d117801628a58409be4e480a3a8?src=pr&el=desc) will **decrease** coverage by `0.11%`.
> The diff coverage is `0%`.

[![Impacted file tree graph](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213/graphs/tree.svg?width=650&token=q8aKDUjiN7&height=150&src=pr)](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1213      +/-   ##
==========================================
- Coverage   81.14%   81.03%   -0.12%     
==========================================
  Files          21       21              
  Lines        1453     1455       +2     
  Branches      191      192       +1     
==========================================
  Hits         1179     1179              
- Misses        231      232       +1     
- Partials       43       44       +1
```


| [Impacted Files](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [raiden\_contracts/utils/join-contracts.py](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213/diff?src=pr&el=tree#diff-cmFpZGVuX2NvbnRyYWN0cy91dGlscy9qb2luLWNvbnRyYWN0cy5weQ==) | `90.9% <0%> (-3.44%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=footer). Last update [a1993ad...31f0d5c](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

codecov[bot]: # [Codecov](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=h1) Report
> Merging [#1213](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=desc) into [master](https://codecov.io/gh/raiden-network/raiden-contracts/commit/a1993ade92c46d117801628a58409be4e480a3a8?src=pr&el=desc) will **decrease** coverage by `0.11%`.
> The diff coverage is `0%`.

[![Impacted file tree graph](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213/graphs/tree.svg?width=650&token=q8aKDUjiN7&height=150&src=pr)](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1213      +/-   ##
==========================================
- Coverage   81.14%   81.03%   -0.12%     
==========================================
  Files          21       21              
  Lines        1453     1455       +2     
  Branches      191      192       +1     
==========================================
  Hits         1179     1179              
- Misses        231      232       +1     
- Partials       43       44       +1
```


| [Impacted Files](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [raiden\_contracts/utils/join-contracts.py](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213/diff?src=pr&el=tree#diff-cmFpZGVuX2NvbnRyYWN0cy91dGlscy9qb2luLWNvbnRyYWN0cy5weQ==) | `90.9% <0%> (-3.44%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=footer). Last update [a1993ad...31f0d5c](https://codecov.io/gh/raiden-network/raiden-contracts/pull/1213?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

pirapira: CodeCov complains.  It's a good time to add tests.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eadd9e3..cf336c0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,8 @@ Documents changes that result in:
 
 ## Unreleased
 
+- [#1213](https://github.com/raiden-network/raiden-contracts/pull/1213) etherscan_verify.py now fails when a source imports a nonexistent file.
+
 ## [0.31.0](https://github.com/raiden-network/raiden-contracts/releases/tag/v0.31.0) - 2019-08-20
 
 - [#1163](https://github.com/raiden-network/raiden-contracts/pull/1163) MonitoringService.monitor() no longer works for service providers that are not registered in ServiceRegistry
diff --git a/raiden_contracts/utils/join_contracts.py b/raiden_contracts/utils/join_contracts.py
index b5cdd61..1a42e03 100755
--- a/raiden_contracts/utils/join_contracts.py
+++ b/raiden_contracts/utils/join_contracts.py
@@ -1,6 +1,5 @@
 #!/usr/bin/env python
 import json
-import os
 import re
 import sys
 from typing import Dict, List, Set, TextIO
@@ -61,9 +60,8 @@ class ContractJoiner:
             for prefix, path in self.import_map.items():
                 if next_file.startswith(prefix):
                     next_file = next_file.replace(prefix, path)
-            if next_file and os.path.exists(next_file):
-                with open(next_file) as next_contract:
-                    out.extend(self.join(next_contract))
+            with open(next_file) as next_contract:
+                out.extend(self.join(next_contract))
 
 
 @click.command()


Test patch:
diff --git a/raiden_contracts/tests/test_contract_joiner.py b/raiden_contracts/tests/test_contract_joiner.py
new file mode 100644
index 0000000..cce4c3d
--- /dev/null
+++ b/raiden_contracts/tests/test_contract_joiner.py
@@ -0,0 +1,25 @@
+from tempfile import NamedTemporaryFile
+
+import pytest
+
+from raiden_contracts.utils.join_contracts import ContractJoiner
+
+
+def test_contract_joiner_with_non_existent_import() -> None:
+    """ Using ContractJoiner on a source importing a nonexistent file """
+    joiner = ContractJoiner()
+    source_with_missing_import = """
+        import "NonExistent.sol";
+    """
+    with NamedTemporaryFile() as source_file:
+        source_file.write(bytearray(source_with_missing_import, "ascii"))
+        source_file.flush()
+        with pytest.raises(FileNotFoundError):
+            joiner.join(open(source_file.name))
+
+
+def test_contract_joiner_with_empty_file() -> None:
+    """ Using ContractJoiner on an empty source """
+    joiner = ContractJoiner()
+    with NamedTemporaryFile() as source_file:
+        assert [] == joiner.join(open(source_file.name))