Tip:
Highlight text to annotate it
X
Hi, and welcome back to the channel.
And this time I'm going to show you a little
contribution, how you can contribute a little
code to CPAN module.
So the other day I was trying to install MIME::Lite.
And this is the way I would install it.
I'd type in on the command line 'cpan MIME::Lite'.
And what I noticed is that it gives me a message here,
telling me that there are certain modules that it would
like to install.
These are optional but highly recommended.
My problem with this is that...
There are two problems at least.
One of them is the 'File::Basename' here,
that's the standard module.
Why is it mentioned here?
The other problem is that,
actually most of these modules if not all of them are already in my system.
So I'm now confused by this.
It's going to upgrade them?
Which one exactly is going to be upgraded or
what's going to happen?
So I would rather not see this.
I would rather fix this,
Makefile.PL that generates this.
So, I quit the script. What can I do?
I could fetch the source code of this distribution from CPAN,
and try to fix it there.
But,
there might have been changes
to the modules
since it was uploaded last time to CPAN.
So, first of all, let's go to : metacpan.org.
And look for the module 'mime-lite'.
This is actually the distribution I'm looking for right now.
So here is the documentation of the module, and what can I see?
Normally here on the left hand side,
there should be a link to the version control system of the distribution.
In this module you don't see it.
If I just look for another one,
So, 'metacpan.org'.
If I just look for another module, for example padre.
Then you will see, here, clicking on here,
that here there is a clone repository link,
that leads to the subversion repository of padre.
We don't see it here.
So some people don't add it to their META.yml file, or not yet.
In some cases you can find the repository
in the documentation but if you click through this documentation
you won't find any of the references.
So, because I know Ricardo, and
I know that he is using github a lot.
So I assume that this module is also kept in the repository.
So I go to github.
Github, and there I type his nickname 'rjbs'.
And I look for the module.
So, I look for 'mime-lite'.
And here it is, 'mime-lite'.
I click on it.
This is the repository basically of the module,
I could fetch it from here.
for this are the links I could use,
but I'd rather use the more standard way here.
It is clicking on this fork button.
For this obviously I have to be registered and logged in to github,
but I have already done that.
So, I click on the fork button,
and it will generate me a fork of this project,
which is actually a good thing in here.
And once the fork has been done,
then it will give me the url for where I can fetch the repository.
So I go back to my console.
Here I'd rather go into this 'tmp' directory.
And type in 'git clone'
and the url that I fetched from the github repository.
Now this will bring over all the repository of that specific module.
And here it is already.
And now I can go into the module.
Into the directory and type 'perl Makefile.PL', the standard way to install.
And see that the thing is still here.
Although the File::Basename entry was taken already out.
So indeed,
things have changed since the latest release
that are not released to CPAN yet.
So let's go and take a look at the source code.
Here what I can see is that...
Well, first of all I don't see 'use strict' 'use warnings'.
And then here is a huge print statement printing out the names of the modules.
Then the prerequisites which are the requirements.
And then prompting
whether I want to add the additional prerequisites.
These ones.
So it is slightly confusing here.
And then here it says the actual names.
So let's do a slight refactoring here.
What I really want here is:
go over the names of the modules that are optional,
check that they are already installed,
check whether the installed is the right version number,
and display here only the ones that are either not installed yet,
or that I installed but they are old versions.
And if they are all installed with all the good versions,
then I don't want the whole thing to appear.
And I don't want the prompt.
So first of all let's move the definitions to the top.
I take this prerequisites and I put them in the top.
And then let's unite the two lists.
So there is the list of the modules and here is the same list again.
Let's create all lists.
So here I put in '%optional'.
And take the four values,
and create the hash here.
So,
that still should be exactly the same.
Now, as I'm going to compare version numbers.
I think I'd rather have here 0s instead of 'undef'.
Which, basically these just mean
that we don't get a rich version
of the module installed, we just want to have that module we installed.
So now I still have the same code.
If I save the file and put the editor in the background.
Now I can run the script just checking out that everything is still the same.
So it looks so far ok, I haven't broken anything.
Now , instead of these four values, let's put in here a String.
So here I just put in some kind of a string,
that I would like to print.
And let's fill that String here
So I have
the 'str', which should be empty
at the beginning
and then I go over 'foreach my', sorry that should be a dollar sign '$name'.
All the keys of the optional hash.
So I go over all that entries,
and I can just add them to the String.
So I just add '\t $name \n' to the String.
So basically this is still the same right?
Now I can remove this,
and I can run the code and it is still the same. So far so good.
Now comes the issue that I would like to check whether I include
this '%str' only the ones that
are not installed or that are to old.
So what do I do?
First of all I need to use the module.
Sorry that should be '$name'. So use the name.
And I put the whole thing into an eval String.
So it would catch an exception if the module is not installed.
Then I check whether the module is installed or not.
Now if it is not installed, then I need to put in the String right?
So let's see, if there was no error message, then everything is ok.
If there was an error message,
then keep it like this, put it in the String.
Ok?
But if there was no error message,
then we still need to check
whether the version number is correct.
So we say 'elsif' and then we put the '$name->VERSION',
this is the actual version number of the installed module.
And we would like to check whether it is smaller than
the version
declared here '$optional{$name}'.
If it's smaller, then we would like to add the same thing.
So let's copy here.
Otherwise we just don't edit.
So let's see what happens now.
If I run the script,
then it tells me the beginning of the report and the end of it
and there are no modules listed.
So probably it means that either I made a bug here
or actually all the modules are installed.
Let's check that out.
So, what happens if I just change the name?
Indeed, so if the module name is something that's not installed
then it would show up here.
That's good so I didn't break that part.
And what happens if I put here 10 instead of version 1.
Then it catches that module,
so apparently that module is still not at version 10.
So both parts are working and they are both including the message.
Now what I would like here is to display this whole thing the print and the prompt
only if there were any values there.
And that's not too bad because...
not too difficult because
'$str' String is going to be empty
if we haven't added anything to it.
So we can actually check whether 'if($str)' and only if the '$str' is there,
only then
print the prompt.
Only then print out anything,
and only then prompt.
So if I now try this out again,
then it won't ask me anything
because all the modules are already installed.
And if I go back and do my little test,
and put here let's say this version number.
And run the script again
then it will tell me these modules need to be installed.
Not because this module is not there but because it is an older version.
A slight improvement would be to actually see.
So in this case when the version is incorrect
then I would like to see the actual version number.
So, actually here too,
I would like to see not only the name of the module but also the required version.
So I put in
the required version, here I do the same,
right?
So in both cases I print out the name of the module that has to be installed
and the version number to be installed.
But in this case I also would like to put in 'we found'
and here I would like to put in the version number
and that version number should be 'my $version' this '$optional{$name}',
right?
So if I run the script now it should tell me that
we want to have 'MIME::Types 10.28'
we found, oh!
That's not good!
We found the same version number so, not the optional name,
we need here the '$name->VERSION',
right? This is what we found.
So if I run this again.
Then indeed, it's better.
So we want, this one, but we found this version.
So that's it I think,
except that I have to put it back to the right version number.
And it now seems too that I've added all the necessary changes.
Now, a little bit more of what I want is the 'use strict'
and 'use warnings'
and let's try to run the script again and now it says '@EXES',
something that is an error.
So let's look where this error, this array can be found.
I use 'ack' to look for 'EXES'.
And the only place where it appears in this code is the 'Makefile.pl'
so probably is just some leftover from an earlier version.
And I think I can safely comment it out.
Well let's leave it for now.
Let's comment these out.
And let's leave it for Ricardo to make the actual changes.
So now if I try it again.
It looks like it's working.
Go back to the editor,
I quit the editor.
'git st' git status, so these are the files that have been changed.
Actually this was the file that has been changed,
this is a new file that was generated it is not really interesting.
So what I need now is 'git add Makefile.PL'.
That this file should be added back to the repository.
And now you see that's green.
And 'git ci -m “make optional modules optional”' ok.
And that's it so I checked in on my local git repository.
And then I can git push.
Push the repository out to github.
And once that's done.
Ok, so it's sent out to my git repository.
And I go back to see if I manage to do that.
I go back to my repository.
I can actually refresh the screen and then
we'll see that this is the last change in the repository.
And now I can send the pull request.
It's basically a message to Ricardo to integrate the changes.
'make optional module prompt optional'
and that's it so I send the pull request.
This will send a message to Ricardo and
hopefully he will integrate the modules soon.
I hope that you learned how to have this CPAN module here.
I'll try to do some other stuff with the same idea later on.
Thank you for listening.
Bye bye.