Using external files and modules in perl PAR Packer - perl

I'm having some trouble using the pp command to create standalone executables on a Linux machine. It seems that every tutorial says a different thing and I'm a bit confused. I'd like your help regarding two issues:
1. I'm trying to include a module created by me (.pm file), but not sure how to do so and keep getting error messages. Should I use the -M option? or should it be -B? And once the module is included, how do I call it from the script? the usual way (i.e. "use module" and then "module::sub")?
2. I want to include some text files too. So far, I've tried -a and -l options, but not sure if they actually work. Which one should I use? Also, how do I open these files? For instance, if I pack the file tmp.txt, what should the open command look like?
Thank you very much!

Adding modules with the -M option and use the module as usual.
Adding your text file with the -a option, from pp's manual:
By default, files are placed under / inside the package with their original names.
so you should be able to read these text files with:
my $content = PAR::read_file('your_file.txt');

Related

How to Build an RPM from Source in One Line without Spec Files etc?

I've been reading about building RPMs, and the process is quite complex. Is there any program/software that works like this:
Download tar.gz file. Extract to directory
cd into directory
Run
RPM file is output into the directory
Does any such program exist? It seems as if it should. After all, when I run make, make install etc, I don't need to specify spec files, provide locations for where the software has to be installed. So why should I have to do all that for creating RPMs?
I've tried using checkinstall, but I keep getting errors like "Directory not found: /root/rpmbuild/BUILDROOT/hello-2.10-1.x86_64/usr"
So is there an easier way?
No. There is no easier way.
Sometimes upstream provide 'make rpm' target. Sometime checkinstall works. But often you have to create the spec file manually.
BTW that error from checkinstall reveals two things:
you are running that command as root. That is very very unwise.
you should create few build directories. Run command rpmdev-setuptree it will create them for you.

How to make my Perl module's README file compatible with Github's Markdown display?

I've authored the README file in my Perl module in Markdown. Github treats this README file as plain text. I tried renaming the file to "README.md"—which looks great on Github, but is invisible to Perl tools that look for a file named "README."
Is there any way I can have both a README file, and have my Markdown formatting be interpreted correctly by Github?
The only option I could come up with was to have both a README and a README.md, but I'd prefer not to have to manually keep the two files in sync.
Thanks for your help.
Format your README in pod, rename it README.pod and then it works both places! Example
For my purposes I actually just generate my README.pod from the main pod by doing
$ podselect lib/My/Main/Module.pm > README.pod
One caveat, named external links don't work correctly L<GitHub|http://github.com> will unfortunately point to search.cpan.org looking for a GitHub module. I have tried to inform them of this glitch but it got me nowhere. Instead you can just use plain external links (i.e. GitHub: L<http://github.com>) and they work fine.
Good news, it appears that they have fixed this since the last time I checked!
Just a question, what parts of the Perl toolchain expect a README file? If you mean including it in your tarball, just be sure to add the file to your MANIFEST and it should get included.
Have you heard of POD? This is the standard documentation tool in Perl. POD is a simple text documentation format that actually lives in your code. One of the commands that come with perl is perldoc. You can use it to get the information of any Perl command. Try these:
$ perldoc File::Find
$ perldoc -f split
All Perl modules in CPAN are required to incorporate POD documentation. In fact, this is how the CPAN webpages themselves are built.
So, where am I going with this and how is this going to help you?
You should include POD documentation in your Perl program. Then, you can use the pod2text command to create your README for your Perl program:
$ pod2text myperl.pl > README
That handles half of your issue.
The other half is a bit more tricky. You need to install from CPAN the Pod::Markdown on your system. Then, you can run the pod2markdown command that comes with this module to create the markdown version of your file:
$ pod2markdown myperl.pl > README.md
The results:
Your documentation lives, as it should, in your Perl program.
Users can use the perldoc program to print out complete documentation of your program.
You can use the pod2text tool to create your README file.
You can use the pod2markdown tool to create your README.md file.
As a bonus, you can use the Pod::Usage module that comes with Perl to show the POD documentation (or bits and pieces of it) as help text that's displayed when a user runs your program with the -help parameter.
So, one place where your documentation lives, and you're using a couple of helper programs to create the files Github and whatever Perl tools you use need.
If you don't mind using Dist::Zilla you can pretty much do away with maintaining a README entirely. For example Dist::Zilla::Plugin::ReadmeFromPod can create your README file by extracting the Pod from your main module. This means never having to write a README again.
I've never tried it myself, but you could look at something like Dist::Zilla::Plugin::ReadmeMarkdownFromPod to create your README automatically in markdown.
This may not be the exact answer you're looking for, but I think using this sort of a tool can save you a lot of time as it allows you avoid repeating yourself in your documentation.
Another solution if you really want to distribute your module with a Markdown README, that doesn't involve Pod is to :
rename your README file to README.md
update the previous change in the MANIFEST file
I think it can be an interesting solution because more people know Markdown syntax than Pod one. As the aim of the README file is to be read by anyone, Markdown should be considered.
I was just looking for a solution for this problem and decided to use Dist::Zilla::Plugin::ReadmeAnyFromPod as it understands =attr and =method tags from Pod::Weaver.
The only option I could come up with was to have both a README and a
README.md, but I'd prefer not to have to manually keep the two files
in sync.
Then automatically keep them in sync?

What is the proper way to test perl modules during development?

I'm working on a personal Perl module to build a basic script framework and to help me learn more about the language. I've created a new module called "AWSTools::Framework" with ExtUtils::ModuleMaker via the command line tool modulemaker. I'm trying to figure out the appropriate way to test it during development.
The directory structure that was created includes the following:
./AWSTOOLS/Framework/lib/AWSTools/Framework.pm
./AWSTOOLS/Framework/t/001_load.t
The autogenerated 001_load.t file looks like this:
# -*- perl -*-
# t/001_load.t - check module loading and create testing directory
use Test::More tests => 2;
BEGIN { use_ok( 'AWSTools::Framework' ); }
my $object = AWSTools::Framework->new ();
isa_ok ($object, 'AWSTools::Framework');
If I try to run the script directly (either from the command line or inside my TextMate editor), it fails with:
Can't locate AWSTools/Framework.pm in #INC....
If I try to run prove in the ./AWSTOOLS/Framework directory, it fails as well.
The question is: What is the proper way to run the tests on Perl modules while developing them?
If you want to run a single test file, you need to tell perl where to find your modules just like you would for any other program. I use the blib to automatically add the right paths:
$ perl Makefile.PL; make; perl -Mblib t/some_test.t
You can also use prove to do the same thing. I don't use prove, but you can read its documentation to figure it out. The -b switch should do that, but I've had problems with it not doing the right thing (could just be my own idiocy).
If you're using the typical toolchain (ExtUtils::MakeMaker) it will be perl Makefile.PL to generate a makefile, then make test every time afterward. Those commands should be run from the root directory of the module. See http://search.cpan.org/perldoc?ExtUtils::MakeMaker#make_test
Edit: and don't do it all manually, or you will come to hate testing. (Well, more than usual.) You will also want to look at least briefly at Test::Tutorial and https://www.socialtext.net/perl5/testing
You may also want to ask the friendly* people in #perl or related channels on your preferred IRC networks.
*Not actually friendly
I actually think that Dist::Zilla is sufficiently flexible enough to allow you to use it for all development. If you aren't uploading to CPAN, just make sure you don't have [UploadToCPAN] in your dist.ini. Also make sure to [#Filter] it out of any plugin bundles which provide it.
Dist::Zilla may be too much to install for only one quick module that you aren't going to touch very often. If you have more than one dist in development then it is definitely worth a look.
You can easily interface it with your VCS using plugins. (Including Git)
You can create a plugin to deploy onto your server. Which would allow you to make sure that all your test files pass before allowing you to deploy ([TestRelease]).
If you don't like tabs in your source files, you can test for that without writing the test yourself ([NoTabsTests]).
Minimal dist.ini for non-CPAN dist
name = Your-Library
author = E. Xavier Ample <example#example.org>
license = Perl_5
copyright_holder = E. Xavier Ample <example#example.org>
copyright_year = 2012
version = 0.001
[GatherDir]
[PruneCruft]
[PruneFiles]
filename = dist.ini
filename = TODO.txt
match = ^.*[.]te?mp$
[NoTabsTests]
[TestRelease]
[CheckExtraTests]
[ModuleBuild]
[FakeRelease]
Test the dist:
dzil test
dzil xtest
If at a later date, you decide to upload it to CPAN:
Replace [FakeRelease] with [UploadToCPAN].
Get a PAUSE id, and set ~/.pause.
user YOUR-PAUSE-ID
password YOUR-PAUSE-PASSWORD
Run dzil release
DONE
In a quick attempt to help you, I would recommend looking at Testing Files and Test Modules.
Continuing to dig around and experiment, I've found the following two things which work for me:
Use prove -l in the './AWSTOOLS/Framework' directory. According to the prove perldoc page, it adds the "lib" directory to the path when Perl runs all the tests in the "t" directory.
To run the script individually/directly, I'm adding the following to the start of the script above the use Test::More line:
use FindBin qw($Bin);
use lib "$Bin/../lib";
This let's me run the script directly via the commad line and in my editor (TextMate). This is based off this page from the Programming Perl book.
Using the -l flag for prove seems very much like the correct thing to do.
As for the "use lib" solution, I doubt that's actually a best practice. If it was, I would expect that modulemaker would have created the 001_load.t test file with that to begin with.

Matlab deployment: add files to source control?

I've created a deployment project which works rather well and now I want to add it to source control repository for others to use.
The main problem I'm facing is that the .prj file which deploytool creates contains absolute paths which will not work on other computers. So far I've tried the following:
Create the stand alone exe using just mcc without deploytool. This works great but I could find a way to create the final _pkg.exe which contains everything. mcc doesn't seem to be able to create this file and there doesn't seem to be any other tool which does. Is this really the case?
Edit the .prj file to include relative paths instead of absolute paths. This only works partially because the .prj file contains a section called MATLABPath which is always replaced with the current setpath of matlab. anyone which uses this file will have to check it out since it is being changed when used.
Find a way to generate the .prj file. the mcc documentation say: Project files created using either mcc or deploytool are eligible to use this option. suggesting there is a way to create a .prj file using mcc but I wasn't able to find how this can be done.
Is there a solution to this situation?
We ran into the same thing with Matlab Builder JA. Not only are the paths absolute, Matlab also adds other toolboxes that it finds on the path, which is irritating, as the build machine doesn't have licenses for a lot of them.
So what we do is:
Edit the prj file by hand to get rid of the absolute paths
Check it into source control and build with mcc
NEVER EVER check in the prj file after it has been touched by deploytool (do all changes by hand in an editor)
Our revision control lets you modify files without an explicit checkout, so using deploytool is not a problem. But why would you want to?
Not sure what the final packager does, but if it just bundles the MCR with the compiled binary, I would just write a replacement.
I personally use Visual Studio 2005 project to maintain my deployment projects and then convert the VCPROJ to PRJ on the fly using build command step
http://younsi.blogspot.com/2011/11/matlab-relative-path-issue-in-prj.html
Here's the mcc option documentation.
What I've found most useful is creating a standalone exe using mcc:
mcc -C -m <function.m> -a <fig> -a <dll> -a <etc> -d <outputPath>
The -C option tells mcc to generate the ctf file (which is the archive of all the compiled MATLAB stuff) as a separate file. I've had trouble on some target computers using a single exe with everything compiled in.
The -m option tells mcc to make an exe.
The -a options tell mcc to include the specified file in the package. For instance, if your script uses two fig files and a data file, you need a -a for each to make sure they get put in the output package.
To tell mcc to use a project file (I've never done this myself):
mcc -F <projectfile>
Also, if you're using R2009a on Windows, there's a known bug that requires some manifest manipulation.

How can I force Perl to run the module from the test directory only?

I have perl module file and test script pl which I use to run some function, and after browsing through the use lib and this previous question here...
I still don't know how to do this.
Basically I have a production directory which contains the module file, and I have a test directory file which contains the same module and the test script file. each time I try to run the script file, it will automatically calls the module in the directory. by printing out the #INC, it seems that the production directory is hosted in there. thus I try to remove it by using
no lib qw(prod_dir);
and while printing out the #INC shows that the directory is no longer there, somehow the script is still calling that other module...
I know this probably sounds really dumb, but hope someone can help me see the light here :)
thanks.
After you have required or used the module, check %INC to see where it came from.
For example:
use Data::Dumper;
print $INC{'Data/Dumper.pm'}."\n";
Note that "::" becomes "/" and you append ".pm". That might give you a clue.
Remember that the current directory (".") is usually an entry in #INC. But the first step is finding out what directory the module was loaded from.
Another thing to remember is that the directories in #INC are searched in order. use lib prepends to that list (making it the first-searched directory), so you may just need to add the appropriate directory.
Can you say more about what you are trying to do and how you are trying to do it? Is this stuff in a standard Perl distribution structure? If you aren't using the standard distribution structure, can you show us a directory listing so we know where things are? Can you also include the code you use to try to load the module? Just update your original question when you pull together the details.
Typically, I run tests through the build runner, which automatically sets up the right #INC.
If I want to run one test in my distribution, I use the blib module to find the build library which has the development versions of my modules:
% perl -Mblib t/test.t
Some people do the same thing with prove.
If you aren't using the basic distribution set-up, consider using it. The tools and best techniques rely on it.
If you just have your module and test file in the same directory, have you tried adding the current directory to #INC with PERL5LIB?