So it has been about two weeks since the start of the coding phase 2. I am really happy to announce that I have passed the evaluation of coding phase 1. I received very nice feedback from my mentors suggesting me some points to improve on. I'm constantly trying to improve from the feedback.
Cool things, if I had to give a short answer. I'm really working on a very cool
project which has some cool ideas, difficult ones but certainly, they are quite
the challenge.
This time I'm implementing two bears in phase 2, namely the
RequirementsCheckBear
and RegexLintBear
both of which are quite useful in
project management. So let's discuss the bears and how challenging they were to
code them.
This is one of my favorites bear to code. One of the worst and very very old
problems for pip
is that it doesn't have any sort of conflict resolving
system. There are works going on, but till now the solution hasn't come out.
coala-bears
have lot of pip-dependencies, after every change in the versions
the build breaks, it is quite difficult to maintain builds because of the
conflict arising every now and then. This bear, of course, doesn't resolve the
conflicts, since I think pip would have that in the coming years. The job of the
bear is to find such conflicts in project requirements.
The bear collects the requirements from the files provided and compiles all such requirements without actually installing them. Installation of the requirements would've been a much better solution overall but since coala already has a lot of restrictions and the fact that the virtualenv package would break the coala build, it becomes harder to get it to work. Besides, without installing we're probably improving the performance of the bear.
So, how did I do it:
The answer was quite simple, pip-compile is one such tool which helped me get there. As the name suggests, pip-compile can compile the requirements of the project without actually installing them. Then I simply parsed the output to check if there's any conflict present in the requirements. As easy as it sounds, it was much harder to finalize this solution. I spend almost a week figuring out the best way to implement this bear. I wasn't particularly happy with any of the approaches but for this bear, I finalized this to be sufficient and efficient at the same time.
Here is the code for the bear, have a look:
import os
from coalib.bears.GlobalBear import GlobalBear
from coalib.results.Result import Result, RESULT_SEVERITY
from sarge import capture_both
class RequirementsCheckBear(GlobalBear):
"""
The bear to check and find any conflicting dependencies.
"""
LANGUAGES = {
'Python Requirements',
'Python 2 Requirements',
'Python 3 Requirements',
}
REQUIREMENTS = {PipRequirement('pip-tools', '3.8.0')}
AUTHORS = {'The coala developers'}
AUTHORS_EMAILS = {'coala-devel@googlegroups.com'}
LICENSE = 'AGPL-3.0'
def run(self, req_files: tuple):
"""
:param req_files:
Tuple of requirements files.
"""
data = ''
orig_file = ''
for req_file in req_files:
if not os.path.isfile(req_file):
raise ValueError('The file {} doesn\'t exist.'.format(req_file))
with open(req_file) as req:
cont = req.read()
if not orig_file:
orig_file = cont
else:
data += cont
with open(req_files[0], 'a+') as temp_file:
temp_file.write(data)
out = capture_both('pip-compile {} -n --no-annotate --no-header '
'--no-index --allow-unsafe'.format(req_files[0]))
if out.stderr.text and not out.stdout.text:
yield Result(self,
message=out.stderr.text.split('\n')[0],
severity=RESULT_SEVERITY.MAJOR,
)
with open(req_files[0], 'w+') as temp_file:
temp_file.write(orig_file)
The RegexLintBearis still in works. I have been researching it for a couple of days. I'm sure of one approach, now I want to make sure its the best one. The bear needs to be generic which is the main problem. Getting all or most languages to work for a single code is a bit of a difficult task, but that is what makes things interesting. :D
So I guess that wraps up this post. I will be writing one more post at the end of phase 2. I will be completing the RegexLintBear by then and I will post all the discussions around that in the next post.
Thanks for reading, see you later!