view release on metacpan or search on metacpan
This file documents the revision history for Perl extension Gitalist.
0.005001 2014-02-11
- Stable version of dev release, now depends on latest Git::Gitalist.
0.005000_01 2014-02-05
- Depend on Git::Gitalist to provide git logic.
0.004004 2014-01-25
- Move away from Class::MOP::load_class (Zoffix Znet)
0.004003 2013-09-04
- Handle non-trivial tags when displaying associated tree.
0.004002 2013-04-01
- Update gitalist_app.psgi with working copy.
- Fix the bare.git test repo.
- The branch selector now sends you to the correct url (Dennis Kaarsemaker)
- Massive tree action speedup (Dennis Kaarsemaker)
- Have line numbers in blob displays (Dennis Kaarsemaker)
- Syntax higlighting improvements (Dennis Kaarsemaker)
0.004001 2013-03-15
- Depend on new Catalyst::Runtime and drop use of Catalyst::Controller::ActionRole
- Stop calling tags branches (Dennis Kaarsemaker)
- Stop breaking trees when submodules are encountered (Dennis Kaarsemaker)
- Correctly handle utf-8 encoded .git/description files (Dennis Kaarsemaker)
- Controller::ActionRole is dead (Tomas Doran)
- Add gitalist.psgi (Tomas Doran)
0.003009 2012-03-18
- Don't use MooseX::Types::ISO8601 to serialize DateTime objects as its
coercion function is now stricter than the object provided.
- Make tests pass with more recent versions of Catalyst.
0.003008 2012-01-29
- Now with Changes.
0.003007 2012-01-28
- Allow the model to be user defined,
- Use new Catalyst features.
- Make repo_dir work consistently with GITALIST_REPO_DIR (Tomas Doran).
- Add the Vhost collection of repositories (Tomas Doran).
0.003006 2011-10-18
- Fix lies in docs, make config more obvious (Tomas Doran)
- Avoid "Use of qw(...) as parentheses is deprecated" warning with
perl-5.14 (Gisle Aas)
0.003005 2011-07-13
- Provide option to disable gravatars.
- Tweaks to make Gitalist fit for debian (Jonas Genannt).
- Fixes to enable Gitalist to run on Win32 (Christian Walde).
- Fix content-type of core.css handler (Christian Walde).
0.003004 2011-06-07
- Fix dependency typo in Makefile.PL.
0.003003 2011-06-06
- Fixed ownership assertions in t/02git_object.t (Christian Walde).
- Change default local config to not search recursively.
- Don't attempt to syntax highlight anything big.
- Fix for infinite loop bug in blame.
0.003002 2011-05-23
- Add JSON serialization and expose via .json (Tomas Doran).
- Provide .psgi for Plack goodness (Francoise Dehinbo).
0.003001 2011-03-13
- Reinstate FromDirectory in model.
- Drop unneeded deps in Makefile.PL.
- Add support for multiple repos with the same name (Jose Luis Martinez).
- Make paging work for history (Lian Wan Situ),
- Respect paging.log config settings.
0.002009 2011-03-06
- Document the available configuration options.
- Provide switch in config for forcing recursive repo searching.
- Assume UTF8 encoded blobs.
0.002008 2011-02-26
- Add the ability to provide a whitelist of repos.
- Add support for export-ok config option.
- Ignore ancient/malformed tags.
- Use the correct perl binary we installed against (Tom Hukins)
0.002007 2011-02-19
- Add support for recursively searching for git repos (Dipesh Patel)
- Cleaned up model code in Gitalist::Git:: (Zachary Stevens)
- Improve POD mark-up, some typos (Lars Dɪá´á´á´á´á´¡ 迪ææ¯)
- Regenerated README and fixed tests for bootstrapped checkouts.
- Add Test::Exception dep.
0.002006 2010-10-17
- Added notes regarding slash encoding in Catalyst
- Fixed typo in core.css
- Updated formatting in Gitalist.pm
- Modified README with more details on FCGI deployment with Apache
- Fix broken env includes in script/gitalist*.pl.
0.002005 2010-08-13
- Limit the number of branches/tags listed by default.
0.002004 2010-08-02
- Fix misnamed variable which was giving a syntax error in
Gitalist::Controller::Fragment::Ref.
- Fix blame view to display syntax highlighted blobs correctly
instead of outputting raw HTML.
0.002003 2010-08-02
- Fix for distribution not including script/env causing Makefile.PL
and scripts to die.
0.002002 2010-08-01
- Fix dist packaging issues.
0.002001 2010-07-03
- Fix for loadCommitInfo.
- Fix tests to work with local-libbery.
- Correct example link and FCGI script.
- Bumping version and updated Changes appropriately.
- Throttle the commit info loading.
- Update bootstrapping for local::lib 1.006000.
- Fixed author_* barewords in Makefile.PL.
- Handle merges in the diff view.
- Add script/{bootstrap.pl,env} to MANIFEST.SKIP.
0.001008 2010-06-03
- Add a requires_external_bin for the git command so we won't try running
tests unless it's present.
- Remove MooseX::MultiMethods as it has been broken by a recent Moose
change. The new code is smaller and will be faster.
- Add diagnostics to the tests to print out the version of git that
people are using.
- Make tests which commonly fail with older/different versions of git
fail with the output of their git command to make debugging the tests
from automated reports possible.
0.001007 2010-05-15
- Set the use_request_uri_for_path configuration variable to be compatible
with Catalyst 5.80024.
0.001006 2010-05-13
- Fix Catalyst::Action::REST dependency (there wasn't one previously)
- Depend on latest Catalyst::View::TT due to a previous bad version
breaking things.
- Add render_die => 1 in the View::TT config as we do want real exceptions
when we call ->render ourselves.
0.001005 2010-05-11
- Depend on latest MX::Declare to fix issues for people who upgrade
MooseX::Types::Structured to a newer version.
- Add some padding below, so file icons are not chopped off
- Updated favicon to cope with dark grey backgrounds
0.001004 2010-05-06
- Remove unneeded dependencies:
- XML::OPML::SimpleGen
- XML::Atom
- XML::RSS
- Fixed author_* barewords in Makefile.PL so that users checking out from
git without the author modules works correctly.
0.001003 2010-04-21
- Added folder / file icons in tree view (Foxtons)
- Added favicon
- Fix for non uri_for hard coded links for running at not root locations.
(RT#56747)
0.001002 2010-04-20
- Fix link for the project_index action.
- Add missing images to MANIFEST.
0.001001 2010-04-15
- Bumping version number to a format I understand, thanks to mst for
pointing me in the right direction and t0m for the new number.
- Cleaned up the search results - removed search from the homepage as
wasn't working (Foxtons).
- Provide a link for an atom entry. switch mode=xml to type=xhtml (Brian
Cassidy).
0.000006.1 2010-04-14
- Documentation fixes for the --repo-dir flag (Dagfinn Ilmari Mannsåker).
0.000006 2010-04-10
- Major frontend redesign, thanks to ranguard and the web designers at
Foxtons for making this happen.
- Major URI overhaul, Gitalist has gone from old gitweb style CGI
parameters to proper URIs, however the old URIs are still supported
and will redirect appropriately (Tomas Doran).
- With the URI overhaul also came breaking up actions into fragments
for use with Catalyst::View::Component::SubInclude.
- BIG BREAKING CHANGE - Gitalist::Model::GitRepos has been renamed
Gitalist::Model::CollectionOfRepos. You need to fix your config and
if you have actually installed Gitalist - remove the old model file.
- Bump required version of Git::PurePerl for Encoding fixes.
- Fix Makefile.PL to not need release deps when checking out of Git.
0.000005 2010-01-09
- Require Git::PurePerl for Win32 compatibility.
- Switch to IPC::Run::start for streamed mode, fixing RT#52658
and the tests with FreeBSD.
- Require new FCGI release in the FCGI script for upstream bug fixes.
- Fix tests with older versions of git.
- Allow the model to be configured with a list of repositories rather
then a directory containing repositories.
- Fix syntax highlighting CSS link
- Add per line link for previous version of a line in blame.
0.000004 2009-12-19
- Support being able to pass a list of repositories to view via
configuration, rather than having a static directory.
- Installation and configuration documentation has been enhanced.
- Project has been renamed Repository to correspond with normal git
terminology.
- Repos has been refactored into a CollectionOfRepositories role
and two differnet concrete implementations (the Catalyst model
chooses which type to build based on the config).
- Remove all tabs and fix no tabs test (Dagfinn Ilmari Mannsåker)
- Decode getpwuid values correctly (Dagfinn Ilmari Mannsåker)
- Generate correct provides information in META.yml so that search.cpan
indexes the classes contained in Gitalist correctly.
- Dropped the dependency on File::Stat::ModeString
0.000003 2009-12-09
- Officially switch repository to Shadowcat
- Officially switch bug tracker to rt.cpan.org
- Start streamlining and generally rejiging the layout.
- Hacked in syntax highlighting to the blame view.
- Further tweaks to the blame view, making it more informative.
- Move all POD below the code, for ::Repo and ::Project.
0.000002 2009-12-06
- Add documentation about how to configure a Gitalist instance.
- Fix so that invalid repository directory will be detected at application
startup and a helpful error message will be displayed.
- Add --repos_dir command line parameter to all of the scripts which can
be used to force the repository directory, overriding config and
environment.
- Add GITALIST_REPOS_DIR environment variable which will determine the
repository path (overriding normal config) if set.
- Change so that no default repos path is in the config when installed from
CPAN (when checked out of git, behavior of browsing AppDir/../ is
maintained).
- Do not allow directory traversal via the p param.
0.000001 2009-12-02
- No changes since last dev release.
0.000000_02 2009-12-01
- Fixed history action, other minor cleanups.
0.000000_01 2009-11-25
- Initial release to CPAN
Changes
gitalist.conf
inc/File/Copy/Recursive.pm
inc/Module/AutoInstall.pm
inc/Module/Install.pm
inc/Module/Install/AuthorRequires.pm
inc/Module/Install/AuthorTests.pm
inc/Module/Install/AutoInstall.pm
inc/Module/Install/Base.pm
inc/Module/Install/Can.pm
inc/Module/Install/Catalyst.pm
inc/Module/Install/External.pm
inc/Module/Install/Fetch.pm
inc/Module/Install/Include.pm
inc/Module/Install/Makefile.pm
inc/Module/Install/Metadata.pm
inc/Module/Install/Scripts.pm
inc/Module/Install/Win32.pm
inc/Module/Install/WriteAll.pm
lib/Gitalist.pm
lib/Gitalist/ActionRole/FilenameArgs.pm
lib/Gitalist/ContentMangler/Resolver.pm
lib/Gitalist/ContentMangler/Resolver/Default.pm
lib/Gitalist/ContentMangler/Transformer/SyntaxHighlight.pm
lib/Gitalist/Controller.pm
lib/Gitalist/Controller/Fragment.pm
lib/Gitalist/Controller/Fragment/Ref.pm
lib/Gitalist/Controller/Fragment/Repository.pm
lib/Gitalist/Controller/LegacyURI.pm
lib/Gitalist/Controller/OPML.pm
lib/Gitalist/Controller/Ref.pm
lib/Gitalist/Controller/Repository.pm
lib/Gitalist/Controller/Root.pm
lib/Gitalist/Faq.pod
lib/Gitalist/Git/CollectionOfRepositories.pm
lib/Gitalist/Git/CollectionOfRepositories/FromDirectory.pm
lib/Gitalist/Git/CollectionOfRepositories/FromDirectory/WhiteList.pm
lib/Gitalist/Git/CollectionOfRepositories/FromDirectoryRecursive.pm
lib/Gitalist/Git/CollectionOfRepositories/FromListOfDirectories.pm
lib/Gitalist/Git/CollectionOfRepositories/Role/Context.pm
lib/Gitalist/Git/CollectionOfRepositories/Vhost.pm
lib/Gitalist/Git/CollectionOfRepositoriesWithRequestState.pm
lib/Gitalist/Git/Types.pm
lib/Gitalist/Model/CollectionOfRepos.pm
lib/Gitalist/Model/ContentMangler.pm
lib/Gitalist/TraitFor/Script.pm
lib/Gitalist/TraitFor/Script/FastCGI.pm
lib/Gitalist/URIStructure/Fragment/WithLog.pm
lib/Gitalist/URIStructure/Ref.pm
lib/Gitalist/URIStructure/Repository.pm
lib/Gitalist/URIStructure/WithLog.pm
lib/Gitalist/Utils.pm
lib/Gitalist/View/Default.pm
lib/Gitalist/View/SyntaxHighlight.pm
Makefile.PL
MANIFEST This list of files
META.yml
MYMETA.json
MYMETA.yml
README
root/_diff.tt2
root/_diff_plain.tt2
root/_diff_tree.tt2
root/_header_feeds.tt2
root/_log_pager.tt2
root/_refs.tt2
root/fragment/collectionofrepositories.tt2
root/fragment/ref/blame.tt2
root/fragment/ref/blob.tt2
root/fragment/ref/commit.tt2
root/fragment/ref/diff_fancy.tt2
root/fragment/ref/diff_plain.tt2
root/fragment/ref/history.tt2
root/fragment/ref/longlog.tt2
root/fragment/ref/shortlog.tt2
root/fragment/ref/tree.tt2
root/fragment/repository/heads.tt2
root/fragment/repository/longlog.tt2
root/fragment/repository/shortlog.tt2
root/fragment/repository/summary.tt2
root/fragment/repository/tags.tt2
root/inc/chroma_hash.tt2
root/inc/footer_feeds.tt2
root/inc/gravatar.tt2
root/inc/history_pager.tt2
root/inc/log_pager.tt2
root/inc/syntax_highlight_css.tt2
root/index.tt2
root/logo.png
root/nav/actions.tt2
root/nav/path.tt2
root/nav/search.tt2
root/opml.tt2
root/ref/blame.tt2
root/ref/blob.tt2
root/ref/commit.tt2
root/ref/diff_fancy.tt2
root/ref/diff_plain.tt2
root/ref/history.tt2
root/ref/longlog.tt2
root/ref/shortlog.tt2
root/ref/tree.tt2
root/repository/atom.tt2
root/repository/heads.tt2
root/repository/longlog.tt2
root/repository/reflog.tt2
root/repository/rss.tt2
root/repository/search.tt2
root/repository/shortlog.tt2
root/repository/summary.tt2
root/repository/tags.tt2
root/search.tt2
root/search_help.tt2
root/static/css/core.css
root/static/css/syntax/Code.css
root/static/css/syntax/Diff.css
root/static/favicon.ico
root/static/git-favicon.png
root/static/i/arrow_down_white.gif
root/static/i/arrow_grey.gif
root/static/i/arrow_grey_left.gif
root/static/i/bg.png
root/static/i/bg_bottom.png
root/static/i/bg_content.png
root/static/i/bg_top.png
root/static/i/buttons/search.png
root/static/i/favicon.gif
root/static/i/favicon.png
root/static/i/icons/attention.png
root/static/i/icons/blame.png
root/static/i/icons/blob.png
root/static/i/icons/button_sha1.png
root/static/i/icons/button_sha1_invert.png
root/static/i/icons/commit.png
root/static/i/icons/diff.png
root/static/i/icons/diffcurrent.png
root/static/i/icons/file.png
root/static/i/icons/folder.png
root/static/i/icons/fulllog.gif
root/static/i/icons/history.png
root/static/i/icons/longlog.png
root/static/i/icons/raw.png
root/static/i/icons/shortlog.gif
root/static/i/icons/shortlog.png
root/static/i/icons/tree.gif
root/static/i/icons/tree.png
root/static/i/logo.png
root/static/js/jquery.min.js
root/static/js/site.js
root/wrapper.tt2
script/gitalist_app.psgi
script/gitalist_cgi.pl
script/gitalist_create.pl
script/gitalist_fastcgi.pl
script/gitalist_server.pl
script/gitalist_test.pl
t/00git_version.t
t/01app.t
t/02git_CollectionOfRepositories_FromDirectory.t
t/02git_CollectionOfRepositories_FromDirectory_WhiteList.t
t/02git_CollectionOfRepositories_FromDirectoryRecursive.t
t/03legacy_uri.t
t/app-mech-rootpage.t
t/atom.t
t/author/notabs.t
t/author/pod.t
t/author/podcoverage.t
t/gitalist.conf
t/json_view.t
t/lib/repositories/bare.git/config
t/lib/repositories/bare.git/description
t/lib/repositories/bare.git/HEAD
t/lib/repositories/bare.git/hooks/applypatch-msg.sample
t/lib/repositories/bare.git/hooks/commit-msg.sample
t/lib/repositories/bare.git/hooks/post-commit.sample
t/lib/repositories/bare.git/hooks/post-receive.sample
t/lib/repositories/bare.git/hooks/post-update.sample
t/lib/repositories/bare.git/hooks/pre-applypatch.sample
t/lib/repositories/bare.git/hooks/pre-commit.sample
t/lib/repositories/bare.git/hooks/pre-rebase.sample
t/lib/repositories/bare.git/hooks/prepare-commit-msg.sample
t/lib/repositories/bare.git/hooks/update.sample
t/lib/repositories/bare.git/info/exclude
t/lib/repositories/bare.git/objects/14/d4a45fe754bb3050e30b9395e93141e4fe9966
t/lib/repositories/bare.git/objects/6f/ed92d478142d92f155adbcfa0d368cf926b890
t/lib/repositories/bare.git/objects/e0/1ab12f8706746dc92e9901ee555984c9597693
t/lib/repositories/bare.git/packed-refs
t/lib/repositories/empty.git/README
t/lib/repositories/file
t/lib/repositories/nodescription/config
t/lib/repositories/nodescription/HEAD
t/lib/repositories/nodescription/hooks/applypatch-msg
t/lib/repositories/nodescription/hooks/commit-msg
t/lib/repositories/nodescription/hooks/post-commit
t/lib/repositories/nodescription/hooks/post-update
t/lib/repositories/nodescription/hooks/pre-applypatch
t/lib/repositories/nodescription/hooks/pre-commit
t/lib/repositories/nodescription/hooks/pre-rebase
t/lib/repositories/nodescription/hooks/update
t/lib/repositories/nodescription/info/exclude
t/lib/repositories/nodescription/objects/14/5dc3ef5d307be84cb9b325d70bd08aeed0eceb
t/lib/repositories/nodescription/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99
t/lib/repositories/nodescription/objects/36/c6c6708b8360d7023e8a1649c45bcf9b3bd818
t/lib/repositories/nodescription/objects/3b/c0634310b9c62222bb0e724c11ffdfb297b4ac
t/lib/repositories/nodescription/objects/3f/7567c7bdf7e7ebf410926493b92d398333116e
t/lib/repositories/nodescription/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6
t/lib/repositories/nodescription/objects/72/9a7c3f6ba5453b42d16a43692205f67fb23bc1
t/lib/repositories/nodescription/objects/82/b5fee28277349b6d46beff5fdf6a7152347ba0
t/lib/repositories/nodescription/objects/90/62594aebb5df0de7fb92413f17a9eced196c22
t/lib/repositories/nodescription/objects/pack/.gitignore
t/lib/repositories/nodescription/refs/heads/master
t/lib/repositories/projects.list
t/lib/repositories/recursive/barerecursive.git/config
t/lib/repositories/recursive/barerecursive.git/description
t/lib/repositories/recursive/barerecursive.git/HEAD
t/lib/repositories/recursive/barerecursive.git/hooks/applypatch-msg.sample
t/lib/repositories/recursive/barerecursive.git/hooks/commit-msg.sample
t/lib/repositories/recursive/barerecursive.git/hooks/post-commit.sample
t/lib/repositories/recursive/barerecursive.git/hooks/post-receive.sample
t/lib/repositories/recursive/barerecursive.git/hooks/post-update.sample
t/lib/repositories/recursive/barerecursive.git/hooks/pre-applypatch.sample
t/lib/repositories/recursive/barerecursive.git/hooks/pre-commit.sample
t/lib/repositories/recursive/barerecursive.git/hooks/pre-rebase.sample
t/lib/repositories/recursive/barerecursive.git/hooks/prepare-commit-msg.sample
t/lib/repositories/recursive/barerecursive.git/hooks/update.sample
t/lib/repositories/recursive/barerecursive.git/info/exclude
t/lib/repositories/recursive/goingdeeper/scratch.git/config
t/lib/repositories/recursive/goingdeeper/scratch.git/description
t/lib/repositories/recursive/goingdeeper/scratch.git/HEAD
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/applypatch-msg.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/commit-msg.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/post-commit.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/post-receive.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/post-update.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/pre-applypatch.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/pre-commit.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/pre-rebase.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/prepare-commit-msg.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/update.sample
t/lib/repositories/recursive/goingdeeper/scratch.git/info/exclude
t/lib/repositories/recursive/goingdeeper2/scratch.git/config
t/lib/repositories/recursive/goingdeeper2/scratch.git/description
t/lib/repositories/recursive/goingdeeper2/scratch.git/HEAD
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/applypatch-msg.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/commit-msg.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/post-commit.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/post-receive.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/post-update.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/pre-applypatch.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/pre-commit.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/pre-rebase.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/prepare-commit-msg.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/hooks/update.sample
t/lib/repositories/recursive/goingdeeper2/scratch.git/info/exclude
t/lib/repositories/recursive/nothinginhere/emptyfile
t/lib/repositories/recursive/other_bare.git/config
t/lib/repositories/recursive/other_bare.git/description
t/lib/repositories/recursive/other_bare.git/HEAD
t/lib/repositories/recursive/other_bare.git/hooks/applypatch-msg.sample
t/lib/repositories/recursive/other_bare.git/hooks/commit-msg.sample
t/lib/repositories/recursive/other_bare.git/hooks/post-commit.sample
t/lib/repositories/recursive/other_bare.git/hooks/post-receive.sample
t/lib/repositories/recursive/other_bare.git/hooks/post-update.sample
t/lib/repositories/recursive/other_bare.git/hooks/pre-applypatch.sample
t/lib/repositories/recursive/other_bare.git/hooks/pre-commit.sample
t/lib/repositories/recursive/other_bare.git/hooks/pre-rebase.sample
t/lib/repositories/recursive/other_bare.git/hooks/prepare-commit-msg.sample
t/lib/repositories/recursive/other_bare.git/hooks/update.sample
t/lib/repositories/recursive/other_bare.git/info/exclude
t/lib/repositories/repo1/config
t/lib/repositories/repo1/description
t/lib/repositories/repo1/export-ok
t/lib/repositories/repo1/HEAD
t/lib/repositories/repo1/hooks/applypatch-msg
t/lib/repositories/repo1/hooks/commit-msg
t/lib/repositories/repo1/hooks/post-commit
t/lib/repositories/repo1/hooks/post-update
t/lib/repositories/repo1/hooks/pre-applypatch
t/lib/repositories/repo1/hooks/pre-commit
t/lib/repositories/repo1/hooks/pre-rebase
t/lib/repositories/repo1/hooks/update
t/lib/repositories/repo1/info/exclude
t/lib/repositories/repo1/objects/07/10a7c8ee11c73e8098d08f9384c2a839c65e4e
t/lib/repositories/repo1/objects/14/5dc3ef5d307be84cb9b325d70bd08aeed0eceb
t/lib/repositories/repo1/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99
t/lib/repositories/repo1/objects/36/c6c6708b8360d7023e8a1649c45bcf9b3bd818
t/lib/repositories/repo1/objects/3b/c0634310b9c62222bb0e724c11ffdfb297b4ac
t/lib/repositories/repo1/objects/3f/7567c7bdf7e7ebf410926493b92d398333116e
t/lib/repositories/repo1/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6
t/lib/repositories/repo1/objects/72/9a7c3f6ba5453b42d16a43692205f67fb23bc1
t/lib/repositories/repo1/objects/76/018072e09c5d31c8c6e3113b8aa0fe625195ca
t/lib/repositories/repo1/objects/82/b5fee28277349b6d46beff5fdf6a7152347ba0
t/lib/repositories/repo1/objects/90/62594aebb5df0de7fb92413f17a9eced196c22
t/lib/repositories/repo1/objects/96/edc8ba5ae50f4c9f66cba1d0c0a03dd7317c9c
t/lib/repositories/repo1/objects/d6/ddf8b26be63066e01d96a0922c87cd8d6e2270
t/lib/repositories/repo1/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
t/lib/repositories/repo1/objects/f6/fc60f3f43501e81ff865b425b3c6c5a4142dd2
t/lib/repositories/repo1/objects/pack/.gitignore
t/lib/repositories/repo1/refs/heads/branch1
t/lib/repositories/repo1/refs/heads/master
t/lib/repositories/repo1/refs/tags/0.01
t/lib/repositories_sets/catgit/Catalyst-Runtime/config
t/lib/repositories_sets/catgit/Catalyst-Runtime/description
t/lib/repositories_sets/catgit/Catalyst-Runtime/export-ok
t/lib/repositories_sets/catgit/Catalyst-Runtime/HEAD
t/lib/repositories_sets/catgit/Catalyst-Runtime/info/exclude
t/lib/repositories_sets/catgit/Catalyst-Runtime/refs/heads/branch1
t/lib/repositories_sets/catgit/Catalyst-Runtime/refs/heads/master
t/lib/repositories_sets/catgit/Catalyst-Runtime/refs/tags/0.01
t/lib/repositories_sets/moose/Moose/config
t/lib/repositories_sets/moose/Moose/description
t/lib/repositories_sets/moose/Moose/export-ok
t/lib/repositories_sets/moose/Moose/HEAD
t/lib/repositories_sets/moose/Moose/info/exclude
t/lib/repositories_sets/moose/Moose/refs/heads/branch1
t/lib/repositories_sets/moose/Moose/refs/heads/master
t/lib/repositories_sets/moose/Moose/refs/tags/0.01
t/lib/TestGitalist.pm
t/lib/TestModelFancy.pm
t/lib/TestModelSimple.pm
t/model_collectionofrepos.t
t/opml.t
t/rss.t
t/script/gitalist_server.pl
t/view_Default.t
---
abstract: 'A modern git web viewer'
author:
- 'AND COPYRIGHT'
- 'Dan Brook <broq@cpan.org>'
build_requires:
ExtUtils::MakeMaker: 6.36
Test::Exception: 0.31
Test::More: 0.88
configure_requires:
ExtUtils::MakeMaker: 6.36
distribution_type: module
dynamic_config: 1
generated_by: 'Module::Install version 1.06'
license: gpl2
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
name: Gitalist
no_index:
directory:
- inc
- t
provides:
Gitalist:
file: lib/Gitalist.pm
version: 0.005001
Gitalist::ActionRole::FilenameArgs:
file: lib/Gitalist/ActionRole/FilenameArgs.pm
Gitalist::ContentMangler::Resolver:
file: lib/Gitalist/ContentMangler/Resolver.pm
Gitalist::ContentMangler::Resolver::Default:
file: lib/Gitalist/ContentMangler/Resolver/Default.pm
Gitalist::ContentMangler::Transformer::SyntaxHighlight:
file: lib/Gitalist/ContentMangler/Transformer/SyntaxHighlight.pm
Gitalist::Controller:
file: lib/Gitalist/Controller.pm
Gitalist::Controller::Fragment:
file: lib/Gitalist/Controller/Fragment.pm
Gitalist::Controller::Fragment::Ref:
file: lib/Gitalist/Controller/Fragment/Ref.pm
Gitalist::Controller::Fragment::Repository:
file: lib/Gitalist/Controller/Fragment/Repository.pm
Gitalist::Controller::LegacyURI:
file: lib/Gitalist/Controller/LegacyURI.pm
Gitalist::Controller::OPML:
file: lib/Gitalist/Controller/OPML.pm
Gitalist::Controller::Ref:
file: lib/Gitalist/Controller/Ref.pm
Gitalist::Controller::Repository:
file: lib/Gitalist/Controller/Repository.pm
Gitalist::Controller::Root:
file: lib/Gitalist/Controller/Root.pm
Gitalist::Git::CollectionOfRepositories:
file: lib/Gitalist/Git/CollectionOfRepositories.pm
Gitalist::Git::CollectionOfRepositories::FromDirectory:
file: lib/Gitalist/Git/CollectionOfRepositories/FromDirectory.pm
Gitalist::Git::CollectionOfRepositories::FromDirectory::WhiteList:
file: lib/Gitalist/Git/CollectionOfRepositories/FromDirectory/WhiteList.pm
Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive:
file: lib/Gitalist/Git/CollectionOfRepositories/FromDirectoryRecursive.pm
Gitalist::Git::CollectionOfRepositories::FromListOfDirectories:
file: lib/Gitalist/Git/CollectionOfRepositories/FromListOfDirectories.pm
Gitalist::Git::CollectionOfRepositories::Role::Context:
file: lib/Gitalist/Git/CollectionOfRepositories/Role/Context.pm
Gitalist::Git::CollectionOfRepositories::Vhost:
file: lib/Gitalist/Git/CollectionOfRepositories/Vhost.pm
Gitalist::Git::CollectionOfRepositoriesWithRequestState:
file: lib/Gitalist/Git/CollectionOfRepositoriesWithRequestState.pm
Gitalist::Git::Types:
file: lib/Gitalist/Git/Types.pm
Gitalist::Model::CollectionOfRepos:
file: lib/Gitalist/Model/CollectionOfRepos.pm
Gitalist::Model::ContentMangler:
file: lib/Gitalist/Model/ContentMangler.pm
Gitalist::TraitFor::Script:
file: lib/Gitalist/TraitFor/Script.pm
Gitalist::TraitFor::Script::FastCGI:
file: lib/Gitalist/TraitFor/Script/FastCGI.pm
Gitalist::URIStructure::Fragment::WithLog:
file: lib/Gitalist/URIStructure/Fragment/WithLog.pm
Gitalist::URIStructure::Ref:
file: lib/Gitalist/URIStructure/Ref.pm
Gitalist::URIStructure::Repository:
file: lib/Gitalist/URIStructure/Repository.pm
Gitalist::URIStructure::WithLog:
file: lib/Gitalist/URIStructure/WithLog.pm
Gitalist::Utils:
file: lib/Gitalist/Utils.pm
Gitalist::View::Default:
file: lib/Gitalist/View/Default.pm
Gitalist::View::SyntaxHighlight:
file: lib/Gitalist/View/SyntaxHighlight.pm
requires:
CGI: 0
Catalyst::Action::REST: 0
Catalyst::Action::RenderView: 0
Catalyst::Component::InstancePerContext: 0
Catalyst::Plugin::ConfigLoader: 0
Catalyst::Plugin::StackTrace: 0
Catalyst::Plugin::Static::Simple: 0
Catalyst::Plugin::SubRequest: 0.15
Catalyst::Plugin::Unicode::Encoding: 0
Catalyst::Runtime: 5.90013
Catalyst::View::Component::SubInclude: 0.07
Catalyst::View::TT: 0.34
Class::Load: 0.20
Config::General: 0
DateTime: 0
File::Copy::Recursive: 0
File::Type: 0
File::Type::WebImages: 0
Git::Gitalist: 0.000002
HTML::Entities: 0
IPC::Run: 0
JSON: 0
JSON::XS: 0
Moose: 0
Moose::Autobox: 0
MooseX::Declare: 0.32
MooseX::Storage: 0
MooseX::Types: 0
MooseX::Types::Common: 0
MooseX::Types::DateTime: 0.05
MooseX::Types::LoadableClass: 0
MooseX::Types::Path::Class: 0
Path::Class: 0.17
Syntax::Highlight::Engine::Kate: 0
Sys::Hostname: 0
Template: 2.22
Template::Plugin::Cycle: 0
Template::Plugin::UTF8Decode: 0
Try::Tiny: 0
aliased: 0
namespace::autoclean: 0
resources:
bugtracker: http://rt.cpan.org/Public/Dist/Display.html?Name=Gitalist
license: http://opensource.org/licenses/gpl-2.0.php
repository: git://git.shadowcat.co.uk/catagits/Gitalist.git
version: 0.005001
MYMETA.json view on Meta::CPAN
{
"abstract" : "A modern git web viewer",
"author" : [
"AND COPYRIGHT, Dan Brook <broq@cpan.org>"
],
"dynamic_config" : 0,
"generated_by" : "ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.120921",
"license" : [
"unknown"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : "2"
},
"name" : "Gitalist",
"no_index" : {
"directory" : [
"t",
"inc"
]
},
"prereqs" : {
"build" : {
"requires" : {
"ExtUtils::MakeMaker" : "6.36",
"Test::Exception" : "0.31",
"Test::More" : "0.88"
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"requires" : {
"CGI" : "0",
"Catalyst::Action::REST" : "0",
"Catalyst::Action::RenderView" : "0",
"Catalyst::Component::InstancePerContext" : "0",
"Catalyst::Plugin::ConfigLoader" : "0",
"Catalyst::Plugin::StackTrace" : "0",
"Catalyst::Plugin::Static::Simple" : "0",
"Catalyst::Plugin::SubRequest" : "0.15",
"Catalyst::Plugin::Unicode::Encoding" : "0",
"Catalyst::Runtime" : "5.90013",
"Catalyst::View::Component::SubInclude" : "0.07",
"Catalyst::View::TT" : "0.34",
"Class::Load" : "0.20",
"Config::General" : "0",
"DateTime" : "0",
"File::Copy::Recursive" : "0",
"File::Type" : "0",
"File::Type::WebImages" : "0",
"Git::Gitalist" : "0.000002",
"HTML::Entities" : "0",
"IPC::Run" : "0",
"JSON" : "0",
"JSON::XS" : "0",
"Moose" : "0",
"Moose::Autobox" : "0",
"MooseX::Declare" : "0.32",
"MooseX::Storage" : "0",
"MooseX::Types" : "0",
"MooseX::Types::Common" : "0",
"MooseX::Types::DateTime" : "0.05",
"MooseX::Types::LoadableClass" : "0",
"MooseX::Types::Path::Class" : "0",
"Path::Class" : "0.17",
"Syntax::Highlight::Engine::Kate" : "0",
"Sys::Hostname" : "0",
"Template" : "2.22",
"Template::Plugin::Cycle" : "0",
"Template::Plugin::UTF8Decode" : "0",
"Try::Tiny" : "0",
"aliased" : "0",
"namespace::autoclean" : "0"
}
}
},
"release_status" : "stable",
"version" : "0.005001"
}
---
abstract: 'A modern git web viewer'
author:
- 'AND COPYRIGHT, Dan Brook <broq@cpan.org>'
build_requires:
ExtUtils::MakeMaker: 6.36
Test::Exception: 0.31
Test::More: 0.88
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 0
generated_by: 'ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.120921'
license: unknown
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
name: Gitalist
no_index:
directory:
- t
- inc
requires:
CGI: 0
Catalyst::Action::REST: 0
Catalyst::Action::RenderView: 0
Catalyst::Component::InstancePerContext: 0
Catalyst::Plugin::ConfigLoader: 0
Catalyst::Plugin::StackTrace: 0
Catalyst::Plugin::Static::Simple: 0
Catalyst::Plugin::SubRequest: 0.15
Catalyst::Plugin::Unicode::Encoding: 0
Catalyst::Runtime: 5.90013
Catalyst::View::Component::SubInclude: 0.07
Catalyst::View::TT: 0.34
Class::Load: 0.20
Config::General: 0
DateTime: 0
File::Copy::Recursive: 0
File::Type: 0
File::Type::WebImages: 0
Git::Gitalist: 0.000002
HTML::Entities: 0
IPC::Run: 0
JSON: 0
JSON::XS: 0
Moose: 0
Moose::Autobox: 0
MooseX::Declare: 0.32
MooseX::Storage: 0
MooseX::Types: 0
MooseX::Types::Common: 0
MooseX::Types::DateTime: 0.05
MooseX::Types::LoadableClass: 0
MooseX::Types::Path::Class: 0
Path::Class: 0.17
Syntax::Highlight::Engine::Kate: 0
Sys::Hostname: 0
Template: 2.22
Template::Plugin::Cycle: 0
Template::Plugin::UTF8Decode: 0
Try::Tiny: 0
aliased: 0
namespace::autoclean: 0
version: 0.005001
Makefile.PL view on Meta::CPAN
#!/usr/bin/env perl
use FindBin;
BEGIN {
my $env = "$FindBin::Bin/script/env";
if (-r $env) {
do $env or die $@;
}
}
use strict;
use warnings;
use inc::Module::Install 0.91;
name 'Gitalist';
all_from 'lib/Gitalist.pm';
author 'Dan Brook <broq@cpan.org>';
license 'gpl2';
if ($ENV{GITALIST_RELEASE_TESTING}) {
# Nasty hack as Module::Install kindly re-loads all of these :/
local $SIG{__WARN__} = sub { return if $_[0] =~ /redefined/; warn shift };
require Module::Install::AuthorRequires;
require Module::Install::AuthorTests;
author_tests('t/author');
author_requires('Test::NoTabs');
author_requires('Test::Pod' => '1.14');
author_requires('Test::Pod::Coverage' => '1.04');
require File::Find;
require FindBin;
require ExtUtils::MM_Unix;
# Fill in provides info so that indexing works right (in the face of MX::Declare)
# by just smashing filenames to package names and not trying to be smart..
File::Find::find(sub {
return unless /^\w.*?\.pm$/;
my $fn = $File::Find::name;
my $ver = ExtUtils::MM_Unix->parse_version($fn);
$fn =~ s/.+?lib/lib/;
my $pn = $fn;
$pn =~ s|^lib/||;
$pn =~ s|/|::|g;
$pn =~ s/\.pm$//;
provides(
$pn => {
file => $fn,
# Ewww
$ver ne 'undef' ? (version => $ver) : (),
},
);
}, $FindBin::Bin . "/lib");
}
requires 'Catalyst::Runtime' => '5.90013';
requires 'Catalyst::Plugin::ConfigLoader';
requires 'Catalyst::Plugin::StackTrace';
requires 'Catalyst::Plugin::Static::Simple';
requires 'Catalyst::Plugin::Unicode::Encoding';
requires 'Catalyst::Plugin::SubRequest' => '0.15';
requires 'Catalyst::Action::RenderView';
requires 'Catalyst::Action::REST';
requires 'Catalyst::Component::InstancePerContext';
requires 'Catalyst::View::Component::SubInclude' => '0.07';
requires 'Catalyst::View::TT' => '0.34';
requires 'Try::Tiny';
requires 'Template' => '2.22';
requires 'Template::Plugin::Cycle';
requires 'Template::Plugin::UTF8Decode';
requires 'Config::General';
requires 'Moose';
requires 'Moose::Autobox';
requires 'MooseX::Declare' => '0.32';
requires 'MooseX::Storage';
requires 'MooseX::Types';
requires 'MooseX::Types::Common';
requires 'MooseX::Types::Path::Class';
requires 'MooseX::Types::DateTime' => '0.05';
requires 'MooseX::Types::LoadableClass';
requires 'namespace::autoclean';
requires 'Class::Load' => '0.20';
requires 'Git::Gitalist' => '0.000002';
requires 'aliased';
requires 'CGI';
requires 'DateTime';
requires 'File::Copy::Recursive';
requires 'File::Type';
requires 'File::Type::WebImages';
requires 'HTML::Entities';
requires 'IPC::Run';
requires 'JSON';
requires 'JSON::XS';
requires 'Path::Class' => '0.17';
requires 'Syntax::Highlight::Engine::Kate';
requires 'Sys::Hostname';
requires_external_bin 'git';
test_requires 'Test::More' => '0.88';
test_requires 'Test::Exception' => '0.31';
resources bugtracker => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Gitalist';
resources repository => 'git://git.shadowcat.co.uk/catagits/Gitalist.git';
catalyst;
if ($Module::Install::AUTHOR) {
system("pod2text lib/Gitalist.pm > README")
and die $!;
include 'File::Copy::Recursive';
}
if ($ENV{GITALIST_RELEASE_TESTING}) {
author_tests('t/author');
author_requires('Test::NoTabs');
author_requires('Test::Pod' => '1.14');
author_requires('Test::Pod::Coverage' => '1.04');
author_requires('Test::WWW::Mechanize::Catalyst' => '0.51');
author_requires('HTML::TreeBuilder::XPath');
author_requires('WWW::Mechanize::TreeBuilder');
}
install_script glob('script/*.p{l,sgi}');
auto_install;
{ # Make sure you REALLY REALLY have to have the env variable set to run
# any of the dist actions.
package # PAUSE HIDE
MY;
sub dist_core { # MakeMaker is awesome fun to customise. And when I say
my ($self, @args) = @_; # fun I mean OH GOD MY EYES.
my $text = $self->SUPER::dist_core(@args);
my @lines = split /\n/, $text;
unless ($ENV{GITALIST_RELEASE_TESTING}) {
my ($printed, @out_lines);
foreach my $in (@lines) {
if ($in =~ /^\S/) {
undef $printed;
$in =~ s/:.*$/:/g;
push @out_lines, $in;
}
elsif ($in =~ /^\s+$/) {
push @out_lines, $in;
}
elsif (!$printed) {
push @out_lines, "\techo Get stuffed mate - set GITALIST_RELEASE_TESTING if you really want to do this..";
$printed = 1;
}
else {}
}
@lines = @out_lines;
}
return join "\n", @lines;
}
}
WriteAll;
NAME
Gitalist - A modern git web viewer
SYNOPSIS
perl script/gitalist_server.pl --repo_dir /home/me/code/git
INSTALL
As Gitalist follows the usual Perl module format the usual approach for
installation should work, e.g.:
perl Makefile.PL
make
make test
make install
or
cpan -i Gitalist
You can also check Gitalist out from its git repository and run it, in
this case you'll additionally need the author modules, but no
configuration will be needed as it will default to looking for
repositories the directory above the checkout.
DESCRIPTION
Gitalist is a web frontend for git repositories based on gitweb.cgi
<https://git.wiki.kernel.org/index.php/Gitweb> and backed by Catalyst.
History
This project started off as an attempt to port *gitweb.cgi* to a
Catalyst app in a piecemeal fashion. As it turns out, thanks largely to
Florian Ragwitz's earlier effort, it was easier to use *gitweb.cgi* as a
template for building a new Catalyst application.
GETTING GITALIST
You can install Gitalist from CPAN in the usual way:
cpan -i Gitalist
Alternatively, you can get Gitalist using git.
The canonical repository for the master branch is:
git://git.shadowcat.co.uk/catagits/Gitalist.git
Gitalist is also mirrored to GitHub at
<https://github.com/broquaint/Gitalist>, and a number of people have
active forks with branches and/or new features in the master branch.
BOOTSTRAPPING
As of 0.002001 Gitalist can now be bootstrapped to run out of its own
directory by installing its prerequisites locally with the help of
local::lib. So instead of installing the prerequisites to the system
path with CPAN they are installed under the Gitalist directory.
To do this clone Gitalist from the Shadowcat repository mentioned above
or grab a snapshot from broquaint's GitHub repository:
https://github.com/broquaint/Gitalist/downloads
With the source acquired and unpacked run the following from within the
Gitalist directory:
perl script/bootstrap.pl
This will install the necessary modules for the build process which in
turn installs the prerequisites locally.
NB: The relevant bootstrap scripts aren't available in the CPAN dist as
the bootstrap scripts should not be installed.
INITIAL CONFIGURATION
Gitalist is configured using Catalyst::Plugin::Configloader. The
supplied sample configuration is in Config::General format, however it
is possible to configure Gitalist using other config file formats (such
as YAML) if you prefer.
WHEN CHECKING GITALIST OUT OF GIT
Gitalist from git includes a minimal "gitalist_local.conf", which sets
the repository directory to one directory higher than the Gitalist
repository.
This means that if you check Gitalist out next to your other git
checkouts, then starting the demo server needs no parameters at all:
Gitalist [master]$ perl script/gitalist_server.pl
You can connect to your server at http://localhost:3000
FOR CPAN INSTALLS
Gitalist can be supplied with a config file by setting the
"GITALIST_CONFIG" environment variable to point to a configuration file.
If you install Gitalist from CPAN, a default configuration is installed
along with gitalist, which is complete except for a repository
directory. You can get a copy of this configuration by running:
cp `perl -Ilib -MGitalist -e'print Gitalist->path_to("gitalist.conf")'` gitalist.conf
You can then edit this configuration, adding a "repo_dir" path and
customising other settings as desired.
You can then start the Gitalist demo server by setting
"GITALIST_CONFIG". For example:
GITALIST_CONFIG=/usr/local/etc/gitalist.conf gitalist_server.pl
Alternatively, if you only want to set a repository directory and are
otherwise happy with the default configuration, then you can set the
"GITALIST_REPO_DIR" environment variable, or pass the "--repo_dir" flag
to any of the scripts.
GITALIST_REPO_DIR=/home/myuser/code/git gitalist_server.pl
gitalist_server.pl --repo_dir home/myuser/code/git
The "GITALIST_REPO_DIR" environment variable will override the
repository directory set in configuration, and will itself be overridden
by he "--repo_dir" flag.
RUNNING
Once you have followed the instructions above to install and configure
Gitalist, you may want to run it in a more production facing environment
than using the single threaded developement server.
The recommended deployment method for Gitalist is FastCGI, although
Gitalist can also be run under mod_perl <https://perl.apache.org/> or as
pure Perl with Catalyst::Engine::PreFork.
Assuming that you have installed Gitalist's dependencies into a
local::lib, and you are running from a git checkout, adding a trivial
FCGI script as "script/gitalist.fcgi" (this file is specifically in
".gitignore" so you can have your own copy):
#!/bin/sh
exec /home/t0m/public_html/Gitalist/script/gitalist_fastcgi.pl
This example can be seen live here:
http://example.gitalist.com
Plack
If you would like to run Gitalist under Plack then one need only make
use of plackup and the ".psgi" found under "scripts/":
plackup script/gitalist_app.psgi
CONFIGURATION
The Gitalist config is loaded with Catalyst::Plugin::ConfigLoader and
the available config options are:
no_gravatars
If true don't display gravatars. May be desirable if you are worried
about leaking repo names via the browser referer headers.
Model::CollectionOfRepos
repo_dir
A directory containing the directories to show.
repos
A list of directories containing repositories to show.
search_recursively
A boolean indicating whether to always search recursively for
repositories within "repo_dir".
whitelist
Path a file containing a list of repositories that can be shown.
Each line in the file will represent the name of a repo to show e.g
Gitalist
some-bare-repo.git
This is compatible with "gitweb"'s "projects.list".
export_ok
If provided every must contain a file of the same name to be
visible. This is similar to "gitweb"'s functionality.
class
If you want a different way of surfacing repositories you can use
your own model (i.e something that composes
Gitalist::Git::CollectionOfRepositories) and specify the class name
with this config option.
args
Any additional arguments to be passed into the Model constructor,
only of use when used in conjunction with "class" (see above).
paging
log The number of commits to show in the summary, shortlog and longlog
views.
FASTCGI
Running Gitalist in FastCGI mode requires a webserver with FastCGI
support (such as apache with mod_fcgi
<http://www.fastcgi.com/drupal/node/3> or mod_fcgid
<https://httpd.apache.org/mod_fcgid/>). Below is a sample configuration
using Apache2 with mod_fcgid in a dynamic configuration (as opposed to
static or standalone mode). More information on these modes and their
configuration can be found at "Standalone server mode" in
Catalyst::Engine::FastCGI.
In Apache's mime.conf, add "AddHandler fcgid-script .fcgi" (or
"AddHandler fastcgi-script .fcgi" for mod_fcgi).
And a quick VirtualHost configuration:
<VirtualHost *:80>
ServerName gitalist.yourdomain.com
DocumentRoot /path/to/gitalist.fcgi
<Directory "/path/to/gitalist.fcgi">
AllowOverride all
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
# Tell Apache this is a FastCGI application
<Files gitalist.fcgi>
#change the below to fastcgi-script if using mod_fcgi
SetHandler fcgid-script
</Files>
</VirtualHost>
Now to access your Gitalist instance, you'll go to
"gitalist.yourdomain.com/gitalist.fcgi/" (do not forget that trailing
"/"). If you'd like a different URL, of course, you'll likely want to
use mod_rewrite <https://httpd.apache.org/docs/mod/mod_rewrite.html> or
equivalent.
If you find the need to do some troubleshooting, you can call
"http://url_to_gitalist.fcgi?dump_info=1" and/or add export
"GITALIST_DEBUG=1" to the top of your gitalist.fcgi file (just below the
shebang line).
Apache config
Apache will refuse %2F in Gitalist URLs unless configured otherwise.
Make sure "AllowEncodedSlashes On" is in your httpd.conf file in order
for this to run smoothly.
To have the static content served statically by Apache, instead of
Gitalist, then add something like following line to your httpd.conf:
Alias /static /usr/local/share/perl/5.10.1/Gitalist/root/static
CONTRIBUTING
Patches are welcome, please feel free to fork on github and send pull
requests, send patches from git format-patch to the bug tracker, or host
your own copy of gitalist somewhere and ask us to pull from it.
SUPPORT
Gitalist has an active irc community in "#gitalist" on irc.perl.org,
please feel free to stop by and ask questions, report bugs or
installation issues or generally for a chat about where we plan to go
with the project.
SEE ALSO
Gitalist::Controller::Root
Git::Gitalist::Repository
Catalyst
AUTHORS AND COPYRIGHT
Catalyst application:
© 2009 Venda Ltd and Dan Brook <broq@cpan.org>
© 2009, Tom Doran <bobtfish@bobtfish.net>
© 2009, Zac Stevens <zts@cryptocracy.com>
Original gitweb.cgi from which this was derived:
© 2005-2006, Kay Sievers <kay.sievers@vrfy.org>
© 2005, Christian Gierke
Model based on http://github.com/rafl/gitweb
© 2008, Florian Ragwitz
LICENSE
Licensed under GNU GPL v2
gitalist.conf view on Meta::CPAN
name Gitalist
<Model::CollectionOfRepos>
#git /path/to/git
# Configure this to where your repositories are.
# NOTE - If you are running from a checkout, there is a gitalist_local.conf
# which will override settings here!!
# See: http://search.cpan.org/dist/Gitalist/lib/Gitalist.pm#WHEN_CHECKING_GITALIST_OUT_OF_GIT
# repo_dir __path_to(../)__
</Model::CollectionOfRepos>
sitename "A Gitalist"
<paging>
log = 20
summary = 17
</paging>
# Support gitweb patches action.
<patches>
max = 16
</patches>
inc/File/Copy/Recursive.pm view on Meta::CPAN
#line 1
package File::Copy::Recursive;
use strict;
BEGIN {
# Keep older versions of Perl from trying to use lexical warnings
$INC{'warnings.pm'} = "fake warnings entry for < 5.6 perl ($])" if $] < 5.006;
}
use warnings;
use Carp;
use File::Copy;
use File::Spec; #not really needed because File::Copy already gets it, but for good measure :)
use vars qw(
@ISA @EXPORT_OK $VERSION $MaxDepth $KeepMode $CPRFComp $CopyLink
$PFSCheck $RemvBase $NoFtlPth $ForcePth $CopyLoop $RMTrgFil $RMTrgDir
$CondCopy $BdTrgWrn $SkipFlop $DirPerms
);
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(fcopy rcopy dircopy fmove rmove dirmove pathmk pathrm pathempty pathrmdir);
$VERSION = '0.38';
$MaxDepth = 0;
$KeepMode = 1;
$CPRFComp = 0;
$CopyLink = eval { local $SIG{'__DIE__'};symlink '',''; 1 } || 0;
$PFSCheck = 1;
$RemvBase = 0;
$NoFtlPth = 0;
$ForcePth = 0;
$CopyLoop = 0;
$RMTrgFil = 0;
$RMTrgDir = 0;
$CondCopy = {};
$BdTrgWrn = 0;
$SkipFlop = 0;
$DirPerms = 0777;
my $samecheck = sub {
return 1 if $^O eq 'MSWin32'; # need better way to check for this on winders...
return if @_ != 2 || !defined $_[0] || !defined $_[1];
return if $_[0] eq $_[1];
my $one = '';
if($PFSCheck) {
$one = join( '-', ( stat $_[0] )[0,1] ) || '';
my $two = join( '-', ( stat $_[1] )[0,1] ) || '';
if ( $one eq $two && $one ) {
carp "$_[0] and $_[1] are identical";
return;
}
}
if(-d $_[0] && !$CopyLoop) {
$one = join( '-', ( stat $_[0] )[0,1] ) if !$one;
my $abs = File::Spec->rel2abs($_[1]);
my @pth = File::Spec->splitdir( $abs );
while(@pth) {
my $cur = File::Spec->catdir(@pth);
last if !$cur; # probably not necessary, but nice to have just in case :)
my $two = join( '-', ( stat $cur )[0,1] ) || '';
if ( $one eq $two && $one ) {
# $! = 62; # Too many levels of symbolic links
carp "Caught Deep Recursion Condition: $_[0] contains $_[1]";
return;
}
pop @pth;
}
}
return 1;
};
my $glob = sub {
my ($do, $src_glob, @args) = @_;
local $CPRFComp = 1;
my @rt;
for my $path ( glob($src_glob) ) {
my @call = [$do->($path, @args)] or return;
push @rt, \@call;
}
return @rt;
};
my $move = sub {
my $fl = shift;
my @x;
if($fl) {
@x = fcopy(@_) or return;
} else {
@x = dircopy(@_) or return;
}
if(@x) {
if($fl) {
unlink $_[0] or return;
} else {
pathrmdir($_[0]) or return;
}
if($RemvBase) {
my ($volm, $path) = File::Spec->splitpath($_[0]);
pathrm(File::Spec->catpath($volm,$path,''), $ForcePth, $NoFtlPth) or return;
}
}
return wantarray ? @x : $x[0];
};
my $ok_todo_asper_condcopy = sub {
my $org = shift;
my $copy = 1;
if(exists $CondCopy->{$org}) {
if($CondCopy->{$org}{'md5'}) {
}
if($copy) {
}
}
return $copy;
};
sub fcopy {
$samecheck->(@_) or return;
if($RMTrgFil && (-d $_[1] || -e $_[1]) ) {
my $trg = $_[1];
if( -d $trg ) {
my @trgx = File::Spec->splitpath( $_[0] );
$trg = File::Spec->catfile( $_[1], $trgx[ $#trgx ] );
}
$samecheck->($_[0], $trg) or return;
if(-e $trg) {
if($RMTrgFil == 1) {
unlink $trg or carp "\$RMTrgFil failed: $!";
} else {
unlink $trg or return;
}
}
}
my ($volm, $path) = File::Spec->splitpath($_[1]);
if($path && !-d $path) {
pathmk(File::Spec->catpath($volm,$path,''), $NoFtlPth);
}
if( -l $_[0] && $CopyLink ) {
carp "Copying a symlink ($_[0]) whose target does not exist"
if !-e readlink($_[0]) && $BdTrgWrn;
symlink readlink(shift()), shift() or return;
} else {
copy(@_) or return;
my @base_file = File::Spec->splitpath($_[0]);
my $mode_trg = -d $_[1] ? File::Spec->catfile($_[1], $base_file[ $#base_file ]) : $_[1];
chmod scalar((stat($_[0]))[2]), $mode_trg if $KeepMode;
}
return wantarray ? (1,0,0) : 1; # use 0's incase they do math on them and in case rcopy() is called in list context = no uninit val warnings
}
sub rcopy {
if (-l $_[0] && $CopyLink) {
goto &fcopy;
}
goto &dircopy if -d $_[0] || substr( $_[0], ( 1 * -1), 1) eq '*';
goto &fcopy;
}
sub rcopy_glob {
$glob->(\&rcopy, @_);
}
sub dircopy {
if($RMTrgDir && -d $_[1]) {
if($RMTrgDir == 1) {
pathrmdir($_[1]) or carp "\$RMTrgDir failed: $!";
} else {
pathrmdir($_[1]) or return;
}
}
my $globstar = 0;
my $_zero = $_[0];
my $_one = $_[1];
if ( substr( $_zero, ( 1 * -1 ), 1 ) eq '*') {
$globstar = 1;
$_zero = substr( $_zero, 0, ( length( $_zero ) - 1 ) );
}
$samecheck->( $_zero, $_[1] ) or return;
if ( !-d $_zero || ( -e $_[1] && !-d $_[1] ) ) {
$! = 20;
return;
}
if(!-d $_[1]) {
pathmk($_[1], $NoFtlPth) or return;
} else {
if($CPRFComp && !$globstar) {
my @parts = File::Spec->splitdir($_zero);
while($parts[ $#parts ] eq '') { pop @parts; }
$_one = File::Spec->catdir($_[1], $parts[$#parts]);
}
}
my $baseend = $_one;
my $level = 0;
my $filen = 0;
my $dirn = 0;
my $recurs; #must be my()ed before sub {} since it calls itself
$recurs = sub {
my ($str,$end,$buf) = @_;
$filen++ if $end eq $baseend;
$dirn++ if $end eq $baseend;
$DirPerms = oct($DirPerms) if substr($DirPerms,0,1) eq '0';
mkdir($end,$DirPerms) or return if !-d $end;
chmod scalar((stat($str))[2]), $end if $KeepMode;
if($MaxDepth && $MaxDepth =~ m/^\d+$/ && $level >= $MaxDepth) {
return ($filen,$dirn,$level) if wantarray;
return $filen;
}
$level++;
my @files;
if ( $] < 5.006 ) {
opendir(STR_DH, $str) or return;
@files = grep( $_ ne '.' && $_ ne '..', readdir(STR_DH));
closedir STR_DH;
}
else {
opendir(my $str_dh, $str) or return;
@files = grep( $_ ne '.' && $_ ne '..', readdir($str_dh));
closedir $str_dh;
}
for my $file (@files) {
my ($file_ut) = $file =~ m{ (.*) }xms;
my $org = File::Spec->catfile($str, $file_ut);
my $new = File::Spec->catfile($end, $file_ut);
if( -l $org && $CopyLink ) {
carp "Copying a symlink ($org) whose target does not exist"
if !-e readlink($org) && $BdTrgWrn;
symlink readlink($org), $new or return;
}
elsif(-d $org) {
$recurs->($org,$new,$buf) if defined $buf;
$recurs->($org,$new) if !defined $buf;
$filen++;
$dirn++;
}
else {
if($ok_todo_asper_condcopy->($org)) {
if($SkipFlop) {
fcopy($org,$new,$buf) or next if defined $buf;
fcopy($org,$new) or next if !defined $buf;
}
else {
fcopy($org,$new,$buf) or return if defined $buf;
fcopy($org,$new) or return if !defined $buf;
}
chmod scalar((stat($org))[2]), $new if $KeepMode;
$filen++;
}
}
}
1;
};
$recurs->($_zero, $_one, $_[2]) or return;
return wantarray ? ($filen,$dirn,$level) : $filen;
}
sub fmove { $move->(1, @_) }
sub rmove {
if (-l $_[0] && $CopyLink) {
goto &fmove;
}
goto &dirmove if -d $_[0] || substr( $_[0], ( 1 * -1), 1) eq '*';
goto &fmove;
}
sub rmove_glob {
$glob->(\&rmove, @_);
}
sub dirmove { $move->(0, @_) }
sub pathmk {
my @parts = File::Spec->splitdir( shift() );
my $nofatal = shift;
my $pth = $parts[0];
my $zer = 0;
if(!$pth) {
$pth = File::Spec->catdir($parts[0],$parts[1]);
$zer = 1;
}
for($zer..$#parts) {
$DirPerms = oct($DirPerms) if substr($DirPerms,0,1) eq '0';
mkdir($pth,$DirPerms) or return if !-d $pth && !$nofatal;
mkdir($pth,$DirPerms) if !-d $pth && $nofatal;
$pth = File::Spec->catdir($pth, $parts[$_ + 1]) unless $_ == $#parts;
}
1;
}
sub pathempty {
my $pth = shift;
return 2 if !-d $pth;
my @names;
my $pth_dh;
if ( $] < 5.006 ) {
opendir(PTH_DH, $pth) or return;
@names = grep !/^\.+$/, readdir(PTH_DH);
}
else {
opendir($pth_dh, $pth) or return;
@names = grep !/^\.+$/, readdir($pth_dh);
}
for my $name (@names) {
my ($name_ut) = $name =~ m{ (.*) }xms;
my $flpth = File::Spec->catdir($pth, $name_ut);
if( -l $flpth ) {
unlink $flpth or return;
}
elsif(-d $flpth) {
pathrmdir($flpth) or return;
}
else {
unlink $flpth or return;
}
}
if ( $] < 5.006 ) {
closedir PTH_DH;
}
else {
closedir $pth_dh;
}
1;
}
sub pathrm {
my $path = shift;
return 2 if !-d $path;
my @pth = File::Spec->splitdir( $path );
my $force = shift;
while(@pth) {
my $cur = File::Spec->catdir(@pth);
last if !$cur; # necessary ???
if(!shift()) {
pathempty($cur) or return if $force;
rmdir $cur or return;
}
else {
pathempty($cur) if $force;
rmdir $cur;
}
pop @pth;
}
1;
}
sub pathrmdir {
my $dir = shift;
if( -e $dir ) {
return if !-d $dir;
}
else {
return 2;
}
pathempty($dir) or return;
rmdir $dir or return;
}
1;
__END__
#line 696
inc/Module/AutoInstall.pm view on Meta::CPAN
#line 1
package Module::AutoInstall;
use strict;
use Cwd ();
use File::Spec ();
use ExtUtils::MakeMaker ();
use vars qw{$VERSION};
BEGIN {
$VERSION = '1.06';
}
# special map on pre-defined feature sets
my %FeatureMap = (
'' => 'Core Features', # XXX: deprecated
'-core' => 'Core Features',
);
# various lexical flags
my ( @Missing, @Existing, %DisabledTests, $UnderCPAN, $InstallDepsTarget, $HasCPANPLUS );
my (
$Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps,
$UpgradeDeps
);
my ( $PostambleActions, $PostambleActionsNoTest, $PostambleActionsUpgradeDeps,
$PostambleActionsUpgradeDepsNoTest, $PostambleActionsListDeps,
$PostambleActionsListAllDeps, $PostambleUsed, $NoTest);
# See if it's a testing or non-interactive session
_accept_default( $ENV{AUTOMATED_TESTING} or ! -t STDIN );
_init();
sub _accept_default {
$AcceptDefault = shift;
}
sub _installdeps_target {
$InstallDepsTarget = shift;
}
sub missing_modules {
return @Missing;
}
sub do_install {
__PACKAGE__->install(
[
$Config
? ( UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
: ()
],
@Missing,
);
}
# initialize various flags, and/or perform install
sub _init {
foreach my $arg (
@ARGV,
split(
/[\s\t]+/,
$ENV{PERL_AUTOINSTALL} || $ENV{PERL_EXTUTILS_AUTOINSTALL} || ''
)
)
{
if ( $arg =~ /^--config=(.*)$/ ) {
$Config = [ split( ',', $1 ) ];
}
elsif ( $arg =~ /^--installdeps=(.*)$/ ) {
__PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) );
exit 0;
}
elsif ( $arg =~ /^--upgradedeps=(.*)$/ ) {
$UpgradeDeps = 1;
__PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) );
exit 0;
}
elsif ( $arg =~ /^--default(?:deps)?$/ ) {
$AcceptDefault = 1;
}
elsif ( $arg =~ /^--check(?:deps)?$/ ) {
$CheckOnly = 1;
}
elsif ( $arg =~ /^--skip(?:deps)?$/ ) {
$SkipInstall = 1;
}
elsif ( $arg =~ /^--test(?:only)?$/ ) {
$TestOnly = 1;
}
elsif ( $arg =~ /^--all(?:deps)?$/ ) {
$AllDeps = 1;
}
}
}
# overrides MakeMaker's prompt() to automatically accept the default choice
sub _prompt {
goto &ExtUtils::MakeMaker::prompt unless $AcceptDefault;
my ( $prompt, $default ) = @_;
my $y = ( $default =~ /^[Yy]/ );
print $prompt, ' [', ( $y ? 'Y' : 'y' ), '/', ( $y ? 'n' : 'N' ), '] ';
print "$default\n";
return $default;
}
# the workhorse
sub import {
my $class = shift;
my @args = @_ or return;
my $core_all;
print "*** $class version " . $class->VERSION . "\n";
print "*** Checking for Perl dependencies...\n";
my $cwd = Cwd::cwd();
$Config = [];
my $maxlen = length(
(
sort { length($b) <=> length($a) }
grep { /^[^\-]/ }
map {
ref($_)
? ( ( ref($_) eq 'HASH' ) ? keys(%$_) : @{$_} )
: ''
}
map { +{@args}->{$_} }
grep { /^[^\-]/ or /^-core$/i } keys %{ +{@args} }
)[0]
);
# We want to know if we're under CPAN early to avoid prompting, but
# if we aren't going to try and install anything anyway then skip the
# check entirely since we don't want to have to load (and configure)
# an old CPAN just for a cosmetic message
$UnderCPAN = _check_lock(1) unless $SkipInstall || $InstallDepsTarget;
while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) {
my ( @required, @tests, @skiptests );
my $default = 1;
my $conflict = 0;
if ( $feature =~ m/^-(\w+)$/ ) {
my $option = lc($1);
# check for a newer version of myself
_update_to( $modules, @_ ) and return if $option eq 'version';
# sets CPAN configuration options
$Config = $modules if $option eq 'config';
# promote every features to core status
$core_all = ( $modules =~ /^all$/i ) and next
if $option eq 'core';
next unless $option eq 'core';
}
print "[" . ( $FeatureMap{ lc($feature) } || $feature ) . "]\n";
$modules = [ %{$modules} ] if UNIVERSAL::isa( $modules, 'HASH' );
unshift @$modules, -default => &{ shift(@$modules) }
if ( ref( $modules->[0] ) eq 'CODE' ); # XXX: bugward combatability
while ( my ( $mod, $arg ) = splice( @$modules, 0, 2 ) ) {
if ( $mod =~ m/^-(\w+)$/ ) {
my $option = lc($1);
$default = $arg if ( $option eq 'default' );
$conflict = $arg if ( $option eq 'conflict' );
@tests = @{$arg} if ( $option eq 'tests' );
@skiptests = @{$arg} if ( $option eq 'skiptests' );
next;
}
printf( "- %-${maxlen}s ...", $mod );
if ( $arg and $arg =~ /^\D/ ) {
unshift @$modules, $arg;
$arg = 0;
}
# XXX: check for conflicts and uninstalls(!) them.
my $cur = _version_of($mod);
if (_version_cmp ($cur, $arg) >= 0)
{
print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n";
push @Existing, $mod => $arg;
$DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
}
else {
if (not defined $cur) # indeed missing
{
print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n";
}
else
{
# no need to check $arg as _version_cmp ($cur, undef) would satisfy >= above
print "too old. ($cur < $arg)\n";
}
push @required, $mod => $arg;
}
}
next unless @required;
my $mandatory = ( $feature eq '-core' or $core_all );
if (
!$SkipInstall
and (
$CheckOnly
or ($mandatory and $UnderCPAN)
or $AllDeps
or $InstallDepsTarget
or _prompt(
qq{==> Auto-install the }
. ( @required / 2 )
. ( $mandatory ? ' mandatory' : ' optional' )
. qq{ module(s) from CPAN?},
$default ? 'y' : 'n',
) =~ /^[Yy]/
)
)
{
push( @Missing, @required );
$DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
}
elsif ( !$SkipInstall
and $default
and $mandatory
and
_prompt( qq{==> The module(s) are mandatory! Really skip?}, 'n', )
=~ /^[Nn]/ )
{
push( @Missing, @required );
$DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
}
else {
$DisabledTests{$_} = 1 for map { glob($_) } @tests;
}
}
if ( @Missing and not( $CheckOnly or $UnderCPAN) ) {
require Config;
my $make = $Config::Config{make};
if ($InstallDepsTarget) {
print
"*** To install dependencies type '$make installdeps' or '$make installdeps_notest'.\n";
}
else {
print
"*** Dependencies will be installed the next time you type '$make'.\n";
}
# make an educated guess of whether we'll need root permission.
print " (You may need to do that as the 'root' user.)\n"
if eval '$>';
}
print "*** $class configuration finished.\n";
chdir $cwd;
# import to main::
no strict 'refs';
*{'main::WriteMakefile'} = \&Write if caller(0) eq 'main';
return (@Existing, @Missing);
}
sub _running_under {
my $thing = shift;
print <<"END_MESSAGE";
*** Since we're running under ${thing}, I'll just let it take care
of the dependency's installation later.
END_MESSAGE
return 1;
}
# Check to see if we are currently running under CPAN.pm and/or CPANPLUS;
# if we are, then we simply let it taking care of our dependencies
sub _check_lock {
return unless @Missing or @_;
if ($ENV{PERL5_CPANM_IS_RUNNING}) {
return _running_under('cpanminus');
}
my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING};
if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) {
return _running_under($cpan_env ? 'CPAN' : 'CPANPLUS');
}
require CPAN;
if ($CPAN::VERSION > '1.89') {
if ($cpan_env) {
return _running_under('CPAN');
}
return; # CPAN.pm new enough, don't need to check further
}
# last ditch attempt, this -will- configure CPAN, very sorry
_load_cpan(1); # force initialize even though it's already loaded
# Find the CPAN lock-file
my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" );
return unless -f $lock;
# Check the lock
local *LOCK;
return unless open(LOCK, $lock);
if (
( $^O eq 'MSWin32' ? _under_cpan() : <LOCK> == getppid() )
and ( $CPAN::Config->{prerequisites_policy} || '' ) ne 'ignore'
) {
print <<'END_MESSAGE';
*** Since we're running under CPAN, I'll just let it take care
of the dependency's installation later.
END_MESSAGE
return 1;
}
close LOCK;
return;
}
sub install {
my $class = shift;
my $i; # used below to strip leading '-' from config keys
my @config = ( map { s/^-// if ++$i; $_ } @{ +shift } );
my ( @modules, @installed );
while ( my ( $pkg, $ver ) = splice( @_, 0, 2 ) ) {
# grep out those already installed
if ( _version_cmp( _version_of($pkg), $ver ) >= 0 ) {
push @installed, $pkg;
}
else {
push @modules, $pkg, $ver;
}
}
if ($UpgradeDeps) {
push @modules, @installed;
@installed = ();
}
return @installed unless @modules; # nothing to do
return @installed if _check_lock(); # defer to the CPAN shell
print "*** Installing dependencies...\n";
return unless _connected_to('cpan.org');
my %args = @config;
my %failed;
local *FAILED;
if ( $args{do_once} and open( FAILED, '.#autoinstall.failed' ) ) {
while (<FAILED>) { chomp; $failed{$_}++ }
close FAILED;
my @newmod;
while ( my ( $k, $v ) = splice( @modules, 0, 2 ) ) {
push @newmod, ( $k => $v ) unless $failed{$k};
}
@modules = @newmod;
}
if ( _has_cpanplus() and not $ENV{PERL_AUTOINSTALL_PREFER_CPAN} ) {
_install_cpanplus( \@modules, \@config );
} else {
_install_cpan( \@modules, \@config );
}
print "*** $class installation finished.\n";
# see if we have successfully installed them
while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
if ( _version_cmp( _version_of($pkg), $ver ) >= 0 ) {
push @installed, $pkg;
}
elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) {
print FAILED "$pkg\n";
}
}
close FAILED if $args{do_once};
return @installed;
}
sub _install_cpanplus {
my @modules = @{ +shift };
my @config = _cpanplus_config( @{ +shift } );
my $installed = 0;
require CPANPLUS::Backend;
my $cp = CPANPLUS::Backend->new;
my $conf = $cp->configure_object;
return unless $conf->can('conf') # 0.05x+ with "sudo" support
or _can_write($conf->_get_build('base')); # 0.04x
# if we're root, set UNINST=1 to avoid trouble unless user asked for it.
my $makeflags = $conf->get_conf('makeflags') || '';
if ( UNIVERSAL::isa( $makeflags, 'HASH' ) ) {
# 0.03+ uses a hashref here
$makeflags->{UNINST} = 1 unless exists $makeflags->{UNINST};
} else {
# 0.02 and below uses a scalar
$makeflags = join( ' ', split( ' ', $makeflags ), 'UNINST=1' )
if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } );
}
$conf->set_conf( makeflags => $makeflags );
$conf->set_conf( prereqs => 1 );
while ( my ( $key, $val ) = splice( @config, 0, 2 ) ) {
$conf->set_conf( $key, $val );
}
my $modtree = $cp->module_tree;
while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
print "*** Installing $pkg...\n";
MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall;
my $success;
my $obj = $modtree->{$pkg};
if ( $obj and _version_cmp( $obj->{version}, $ver ) >= 0 ) {
my $pathname = $pkg;
$pathname =~ s/::/\\W/;
foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) {
delete $INC{$inc};
}
my $rv = $cp->install( modules => [ $obj->{module} ] );
if ( $rv and ( $rv->{ $obj->{module} } or $rv->{ok} ) ) {
print "*** $pkg successfully installed.\n";
$success = 1;
} else {
print "*** $pkg installation cancelled.\n";
$success = 0;
}
$installed += $success;
} else {
print << ".";
*** Could not find a version $ver or above for $pkg; skipping.
.
}
MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall;
}
return $installed;
}
sub _cpanplus_config {
my @config = ();
while ( @_ ) {
my ($key, $value) = (shift(), shift());
if ( $key eq 'prerequisites_policy' ) {
if ( $value eq 'follow' ) {
$value = CPANPLUS::Internals::Constants::PREREQ_INSTALL();
} elsif ( $value eq 'ask' ) {
$value = CPANPLUS::Internals::Constants::PREREQ_ASK();
} elsif ( $value eq 'ignore' ) {
$value = CPANPLUS::Internals::Constants::PREREQ_IGNORE();
} else {
die "*** Cannot convert option $key = '$value' to CPANPLUS version.\n";
}
push @config, 'prereqs', $value;
} elsif ( $key eq 'force' ) {
push @config, $key, $value;
} elsif ( $key eq 'notest' ) {
push @config, 'skiptest', $value;
} else {
die "*** Cannot convert option $key to CPANPLUS version.\n";
}
}
return @config;
}
sub _install_cpan {
my @modules = @{ +shift };
my @config = @{ +shift };
my $installed = 0;
my %args;
_load_cpan();
require Config;
if (CPAN->VERSION < 1.80) {
# no "sudo" support, probe for writableness
return unless _can_write( MM->catfile( $CPAN::Config->{cpan_home}, 'sources' ) )
and _can_write( $Config::Config{sitelib} );
}
# if we're root, set UNINST=1 to avoid trouble unless user asked for it.
my $makeflags = $CPAN::Config->{make_install_arg} || '';
$CPAN::Config->{make_install_arg} =
join( ' ', split( ' ', $makeflags ), 'UNINST=1' )
if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } );
# don't show start-up info
$CPAN::Config->{inhibit_startup_message} = 1;
# set additional options
while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) {
( $args{$opt} = $arg, next )
if $opt =~ /^(?:force|notest)$/; # pseudo-option
$CPAN::Config->{$opt} = $arg;
}
if ($args{notest} && (not CPAN::Shell->can('notest'))) {
die "Your version of CPAN is too old to support the 'notest' pragma";
}
local $CPAN::Config->{prerequisites_policy} = 'follow';
while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall;
print "*** Installing $pkg...\n";
my $obj = CPAN::Shell->expand( Module => $pkg );
my $success = 0;
if ( $obj and _version_cmp( $obj->cpan_version, $ver ) >= 0 ) {
my $pathname = $pkg;
$pathname =~ s/::/\\W/;
foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) {
delete $INC{$inc};
}
my $rv = do {
if ($args{force}) {
CPAN::Shell->force( install => $pkg )
} elsif ($args{notest}) {
CPAN::Shell->notest( install => $pkg )
} else {
CPAN::Shell->install($pkg)
}
};
$rv ||= eval {
$CPAN::META->instance( 'CPAN::Distribution', $obj->cpan_file, )
->{install}
if $CPAN::META;
};
if ( $rv eq 'YES' ) {
print "*** $pkg successfully installed.\n";
$success = 1;
}
else {
print "*** $pkg installation failed.\n";
$success = 0;
}
$installed += $success;
}
else {
print << ".";
*** Could not find a version $ver or above for $pkg; skipping.
.
}
MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall;
}
return $installed;
}
sub _has_cpanplus {
return (
$HasCPANPLUS = (
$INC{'CPANPLUS/Config.pm'}
or _load('CPANPLUS::Shell::Default')
)
);
}
# make guesses on whether we're under the CPAN installation directory
sub _under_cpan {
require Cwd;
require File::Spec;
my $cwd = File::Spec->canonpath( Cwd::cwd() );
my $cpan = File::Spec->canonpath( $CPAN::Config->{cpan_home} );
return ( index( $cwd, $cpan ) > -1 );
}
sub _update_to {
my $class = __PACKAGE__;
my $ver = shift;
return
if _version_cmp( _version_of($class), $ver ) >= 0; # no need to upgrade
if (
_prompt( "==> A newer version of $class ($ver) is required. Install?",
'y' ) =~ /^[Nn]/
)
{
die "*** Please install $class $ver manually.\n";
}
print << ".";
*** Trying to fetch it from CPAN...
.
# install ourselves
_load($class) and return $class->import(@_)
if $class->install( [], $class, $ver );
print << '.'; exit 1;
*** Cannot bootstrap myself. :-( Installation terminated.
.
}
# check if we're connected to some host, using inet_aton
sub _connected_to {
my $site = shift;
return (
( _load('Socket') and Socket::inet_aton($site) ) or _prompt(
qq(
*** Your host cannot resolve the domain name '$site', which
probably means the Internet connections are unavailable.
==> Should we try to install the required module(s) anyway?), 'n'
) =~ /^[Yy]/
);
}
# check if a directory is writable; may create it on demand
sub _can_write {
my $path = shift;
mkdir( $path, 0755 ) unless -e $path;
return 1 if -w $path;
print << ".";
*** You are not allowed to write to the directory '$path';
the installation may fail due to insufficient permissions.
.
if (
eval '$>' and lc(`sudo -V`) =~ /version/ and _prompt(
qq(
==> Should we try to re-execute the autoinstall process with 'sudo'?),
((-t STDIN) ? 'y' : 'n')
) =~ /^[Yy]/
)
{
# try to bootstrap ourselves from sudo
print << ".";
*** Trying to re-execute the autoinstall process with 'sudo'...
.
my $missing = join( ',', @Missing );
my $config = join( ',',
UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
if $Config;
return
unless system( 'sudo', $^X, $0, "--config=$config",
"--installdeps=$missing" );
print << ".";
*** The 'sudo' command exited with error! Resuming...
.
}
return _prompt(
qq(
==> Should we try to install the required module(s) anyway?), 'n'
) =~ /^[Yy]/;
}
# load a module and return the version it reports
sub _load {
my $mod = pop; # method/function doesn't matter
my $file = $mod;
$file =~ s|::|/|g;
$file .= '.pm';
local $@;
return eval { require $file; $mod->VERSION } || ( $@ ? undef: 0 );
}
# report version without loading a module
sub _version_of {
my $mod = pop; # method/function doesn't matter
my $file = $mod;
$file =~ s|::|/|g;
$file .= '.pm';
foreach my $dir ( @INC ) {
next if ref $dir;
my $path = File::Spec->catfile($dir, $file);
next unless -e $path;
require ExtUtils::MM_Unix;
return ExtUtils::MM_Unix->parse_version($path);
}
return undef;
}
# Load CPAN.pm and it's configuration
sub _load_cpan {
return if $CPAN::VERSION and $CPAN::Config and not @_;
require CPAN;
# CPAN-1.82+ adds CPAN::Config::AUTOLOAD to redirect to
# CPAN::HandleConfig->load. CPAN reports that the redirection
# is deprecated in a warning printed at the user.
# CPAN-1.81 expects CPAN::HandleConfig->load, does not have
# $CPAN::HandleConfig::VERSION but cannot handle
# CPAN::Config->load
# Which "versions expect CPAN::Config->load?
if ( $CPAN::HandleConfig::VERSION
|| CPAN::HandleConfig->can('load')
) {
# Newer versions of CPAN have a HandleConfig module
CPAN::HandleConfig->load;
} else {
# Older versions had the load method in Config directly
CPAN::Config->load;
}
}
# compare two versions, either use Sort::Versions or plain comparison
# return values same as <=>
sub _version_cmp {
my ( $cur, $min ) = @_;
return -1 unless defined $cur; # if 0 keep comparing
return 1 unless $min;
$cur =~ s/\s+$//;
# check for version numbers that are not in decimal format
if ( ref($cur) or ref($min) or $cur =~ /v|\..*\./ or $min =~ /v|\..*\./ ) {
if ( ( $version::VERSION or defined( _load('version') )) and
version->can('new')
) {
# use version.pm if it is installed.
return version->new($cur) <=> version->new($min);
}
elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) )
{
# use Sort::Versions as the sorting algorithm for a.b.c versions
return Sort::Versions::versioncmp( $cur, $min );
}
warn "Cannot reliably compare non-decimal formatted versions.\n"
. "Please install version.pm or Sort::Versions.\n";
}
# plain comparison
local $^W = 0; # shuts off 'not numeric' bugs
return $cur <=> $min;
}
# nothing; this usage is deprecated.
sub main::PREREQ_PM { return {}; }
sub _make_args {
my %args = @_;
$args{PREREQ_PM} = { %{ $args{PREREQ_PM} || {} }, @Existing, @Missing }
if $UnderCPAN or $TestOnly;
if ( $args{EXE_FILES} and -e 'MANIFEST' ) {
require ExtUtils::Manifest;
my $manifest = ExtUtils::Manifest::maniread('MANIFEST');
$args{EXE_FILES} =
[ grep { exists $manifest->{$_} } @{ $args{EXE_FILES} } ];
}
$args{test}{TESTS} ||= 't/*.t';
$args{test}{TESTS} = join( ' ',
grep { !exists( $DisabledTests{$_} ) }
map { glob($_) } split( /\s+/, $args{test}{TESTS} ) );
my $missing = join( ',', @Missing );
my $config =
join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
if $Config;
$PostambleActions = (
($missing and not $UnderCPAN)
? "\$(PERL) $0 --config=$config --installdeps=$missing"
: "\$(NOECHO) \$(NOOP)"
);
my $deps_list = join( ',', @Missing, @Existing );
$PostambleActionsUpgradeDeps =
"\$(PERL) $0 --config=$config --upgradedeps=$deps_list";
my $config_notest =
join( ',', (UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config}),
'notest', 1 )
if $Config;
$PostambleActionsNoTest = (
($missing and not $UnderCPAN)
? "\$(PERL) $0 --config=$config_notest --installdeps=$missing"
: "\$(NOECHO) \$(NOOP)"
);
$PostambleActionsUpgradeDepsNoTest =
"\$(PERL) $0 --config=$config_notest --upgradedeps=$deps_list";
$PostambleActionsListDeps =
'@$(PERL) -le "print for @ARGV" '
. join(' ', map $Missing[$_], grep $_ % 2 == 0, 0..$#Missing);
my @all = (@Missing, @Existing);
$PostambleActionsListAllDeps =
'@$(PERL) -le "print for @ARGV" '
. join(' ', map $all[$_], grep $_ % 2 == 0, 0..$#all);
return %args;
}
# a wrapper to ExtUtils::MakeMaker::WriteMakefile
sub Write {
require Carp;
Carp::croak "WriteMakefile: Need even number of args" if @_ % 2;
if ($CheckOnly) {
print << ".";
*** Makefile not written in check-only mode.
.
return;
}
my %args = _make_args(@_);
no strict 'refs';
$PostambleUsed = 0;
local *MY::postamble = \&postamble unless defined &MY::postamble;
ExtUtils::MakeMaker::WriteMakefile(%args);
print << "." unless $PostambleUsed;
*** WARNING: Makefile written with customized MY::postamble() without
including contents from Module::AutoInstall::postamble() --
auto installation features disabled. Please contact the author.
.
return 1;
}
sub postamble {
$PostambleUsed = 1;
my $fragment;
$fragment .= <<"AUTO_INSTALL" if !$InstallDepsTarget;
config :: installdeps
\t\$(NOECHO) \$(NOOP)
AUTO_INSTALL
$fragment .= <<"END_MAKE";
checkdeps ::
\t\$(PERL) $0 --checkdeps
installdeps ::
\t$PostambleActions
installdeps_notest ::
\t$PostambleActionsNoTest
upgradedeps ::
\t$PostambleActionsUpgradeDeps
upgradedeps_notest ::
\t$PostambleActionsUpgradeDepsNoTest
listdeps ::
\t$PostambleActionsListDeps
listalldeps ::
\t$PostambleActionsListAllDeps
END_MAKE
return $fragment;
}
1;
__END__
#line 1193
inc/Module/Install.pm view on Meta::CPAN
#line 1
package Module::Install;
# For any maintainers:
# The load order for Module::Install is a bit magic.
# It goes something like this...
#
# IF ( host has Module::Install installed, creating author mode ) {
# 1. Makefile.PL calls "use inc::Module::Install"
# 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install
# 3. The installed version of inc::Module::Install loads
# 4. inc::Module::Install calls "require Module::Install"
# 5. The ./inc/ version of Module::Install loads
# } ELSE {
# 1. Makefile.PL calls "use inc::Module::Install"
# 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install
# 3. The ./inc/ version of Module::Install loads
# }
use 5.005;
use strict 'vars';
use Cwd ();
use File::Find ();
use File::Path ();
use vars qw{$VERSION $MAIN};
BEGIN {
# All Module::Install core packages now require synchronised versions.
# This will be used to ensure we don't accidentally load old or
# different versions of modules.
# This is not enforced yet, but will be some time in the next few
# releases once we can make sure it won't clash with custom
# Module::Install extensions.
$VERSION = '1.06';
# Storage for the pseudo-singleton
$MAIN = undef;
*inc::Module::Install::VERSION = *VERSION;
@inc::Module::Install::ISA = __PACKAGE__;
}
sub import {
my $class = shift;
my $self = $class->new(@_);
my $who = $self->_caller;
#-------------------------------------------------------------
# all of the following checks should be included in import(),
# to allow "eval 'require Module::Install; 1' to test
# installation of Module::Install. (RT #51267)
#-------------------------------------------------------------
# Whether or not inc::Module::Install is actually loaded, the
# $INC{inc/Module/Install.pm} is what will still get set as long as
# the caller loaded module this in the documented manner.
# If not set, the caller may NOT have loaded the bundled version, and thus
# they may not have a MI version that works with the Makefile.PL. This would
# result in false errors or unexpected behaviour. And we don't want that.
my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
unless ( $INC{$file} ) { die <<"END_DIE" }
Please invoke ${\__PACKAGE__} with:
use inc::${\__PACKAGE__};
not:
use ${\__PACKAGE__};
END_DIE
# This reportedly fixes a rare Win32 UTC file time issue, but
# as this is a non-cross-platform XS module not in the core,
# we shouldn't really depend on it. See RT #24194 for detail.
# (Also, this module only supports Perl 5.6 and above).
eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006;
# If the script that is loading Module::Install is from the future,
# then make will detect this and cause it to re-run over and over
# again. This is bad. Rather than taking action to touch it (which
# is unreliable on some platforms and requires write permissions)
# for now we should catch this and refuse to run.
if ( -f $0 ) {
my $s = (stat($0))[9];
# If the modification time is only slightly in the future,
# sleep briefly to remove the problem.
my $a = $s - time;
if ( $a > 0 and $a < 5 ) { sleep 5 }
# Too far in the future, throw an error.
my $t = time;
if ( $s > $t ) { die <<"END_DIE" }
Your installer $0 has a modification time in the future ($s > $t).
This is known to create infinite loops in make.
Please correct this, then run $0 again.
END_DIE
}
# Build.PL was formerly supported, but no longer is due to excessive
# difficulty in implementing every single feature twice.
if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
Module::Install no longer supports Build.PL.
It was impossible to maintain duel backends, and has been deprecated.
Please remove all Build.PL files and only use the Makefile.PL installer.
END_DIE
#-------------------------------------------------------------
# To save some more typing in Module::Install installers, every...
# use inc::Module::Install
# ...also acts as an implicit use strict.
$^H |= strict::bits(qw(refs subs vars));
#-------------------------------------------------------------
unless ( -f $self->{file} ) {
foreach my $key (keys %INC) {
delete $INC{$key} if $key =~ /Module\/Install/;
}
local $^W;
require "$self->{path}/$self->{dispatch}.pm";
File::Path::mkpath("$self->{prefix}/$self->{author}");
$self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
$self->{admin}->init;
@_ = ($class, _self => $self);
goto &{"$self->{name}::import"};
}
local $^W;
*{"${who}::AUTOLOAD"} = $self->autoload;
$self->preload;
# Unregister loader and worker packages so subdirs can use them again
delete $INC{'inc/Module/Install.pm'};
delete $INC{'Module/Install.pm'};
# Save to the singleton
$MAIN = $self;
return 1;
}
sub autoload {
my $self = shift;
my $who = $self->_caller;
my $cwd = Cwd::cwd();
my $sym = "${who}::AUTOLOAD";
$sym->{$cwd} = sub {
my $pwd = Cwd::cwd();
if ( my $code = $sym->{$pwd} ) {
# Delegate back to parent dirs
goto &$code unless $cwd eq $pwd;
}
unless ($$sym =~ s/([^:]+)$//) {
# XXX: it looks like we can't retrieve the missing function
# via $$sym (usually $main::AUTOLOAD) in this case.
# I'm still wondering if we should slurp Makefile.PL to
# get some context or not ...
my ($package, $file, $line) = caller;
die <<"EOT";
Unknown function is found at $file line $line.
Execution of $file aborted due to runtime errors.
If you're a contributor to a project, you may need to install
some Module::Install extensions from CPAN (or other repository).
If you're a user of a module, please contact the author.
EOT
}
my $method = $1;
if ( uc($method) eq $method ) {
# Do nothing
return;
} elsif ( $method =~ /^_/ and $self->can($method) ) {
# Dispatch to the root M:I class
return $self->$method(@_);
}
# Dispatch to the appropriate plugin
unshift @_, ( $self, $1 );
goto &{$self->can('call')};
};
}
sub preload {
my $self = shift;
unless ( $self->{extensions} ) {
$self->load_extensions(
"$self->{prefix}/$self->{path}", $self
);
}
my @exts = @{$self->{extensions}};
unless ( @exts ) {
@exts = $self->{admin}->load_all_extensions;
}
my %seen;
foreach my $obj ( @exts ) {
while (my ($method, $glob) = each %{ref($obj) . '::'}) {
next unless $obj->can($method);
next if $method =~ /^_/;
next if $method eq uc($method);
$seen{$method}++;
}
}
my $who = $self->_caller;
foreach my $name ( sort keys %seen ) {
local $^W;
*{"${who}::$name"} = sub {
${"${who}::AUTOLOAD"} = "${who}::$name";
goto &{"${who}::AUTOLOAD"};
};
}
}
sub new {
my ($class, %args) = @_;
delete $INC{'FindBin.pm'};
{
# to suppress the redefine warning
local $SIG{__WARN__} = sub {};
require FindBin;
}
# ignore the prefix on extension modules built from top level.
my $base_path = Cwd::abs_path($FindBin::Bin);
unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
delete $args{prefix};
}
return $args{_self} if $args{_self};
$args{dispatch} ||= 'Admin';
$args{prefix} ||= 'inc';
$args{author} ||= ($^O eq 'VMS' ? '_author' : '.author');
$args{bundle} ||= 'inc/BUNDLES';
$args{base} ||= $base_path;
$class =~ s/^\Q$args{prefix}\E:://;
$args{name} ||= $class;
$args{version} ||= $class->VERSION;
unless ( $args{path} ) {
$args{path} = $args{name};
$args{path} =~ s!::!/!g;
}
$args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm";
$args{wrote} = 0;
bless( \%args, $class );
}
sub call {
my ($self, $method) = @_;
my $obj = $self->load($method) or return;
splice(@_, 0, 2, $obj);
goto &{$obj->can($method)};
}
sub load {
my ($self, $method) = @_;
$self->load_extensions(
"$self->{prefix}/$self->{path}", $self
) unless $self->{extensions};
foreach my $obj (@{$self->{extensions}}) {
return $obj if $obj->can($method);
}
my $admin = $self->{admin} or die <<"END_DIE";
The '$method' method does not exist in the '$self->{prefix}' path!
Please remove the '$self->{prefix}' directory and run $0 again to load it.
END_DIE
my $obj = $admin->load($method, 1);
push @{$self->{extensions}}, $obj;
$obj;
}
sub load_extensions {
my ($self, $path, $top) = @_;
my $should_reload = 0;
unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) {
unshift @INC, $self->{prefix};
$should_reload = 1;
}
foreach my $rv ( $self->find_extensions($path) ) {
my ($file, $pkg) = @{$rv};
next if $self->{pathnames}{$pkg};
local $@;
my $new = eval { local $^W; require $file; $pkg->can('new') };
unless ( $new ) {
warn $@ if $@;
next;
}
$self->{pathnames}{$pkg} =
$should_reload ? delete $INC{$file} : $INC{$file};
push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
}
$self->{extensions} ||= [];
}
sub find_extensions {
my ($self, $path) = @_;
my @found;
File::Find::find( sub {
my $file = $File::Find::name;
return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
my $subpath = $1;
return if lc($subpath) eq lc($self->{dispatch});
$file = "$self->{path}/$subpath.pm";
my $pkg = "$self->{name}::$subpath";
$pkg =~ s!/!::!g;
# If we have a mixed-case package name, assume case has been preserved
# correctly. Otherwise, root through the file to locate the case-preserved
# version of the package name.
if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
my $content = Module::Install::_read($subpath . '.pm');
my $in_pod = 0;
foreach ( split //, $content ) {
$in_pod = 1 if /^=\w/;
$in_pod = 0 if /^=cut/;
next if ($in_pod || /^=cut/); # skip pod text
next if /^\s*#/; # and comments
if ( m/^\s*package\s+($pkg)\s*;/i ) {
$pkg = $1;
last;
}
}
}
push @found, [ $file, $pkg ];
}, $path ) if -d $path;
@found;
}
#####################################################################
# Common Utility Functions
sub _caller {
my $depth = 0;
my $call = caller($depth);
while ( $call eq __PACKAGE__ ) {
$depth++;
$call = caller($depth);
}
return $call;
}
# Done in evals to avoid confusing Perl::MinimumVersion
eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
sub _read {
local *FH;
open( FH, '<', $_[0] ) or die "open($_[0]): $!";
my $string = do { local $/; <FH> };
close FH or die "close($_[0]): $!";
return $string;
}
END_NEW
sub _read {
local *FH;
open( FH, "< $_[0]" ) or die "open($_[0]): $!";
my $string = do { local $/; <FH> };
close FH or die "close($_[0]): $!";
return $string;
}
END_OLD
sub _readperl {
my $string = Module::Install::_read($_[0]);
$string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg;
$string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s;
$string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg;
return $string;
}
sub _readpod {
my $string = Module::Install::_read($_[0]);
$string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg;
return $string if $_[0] =~ /\.pod\z/;
$string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg;
$string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg;
$string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg;
$string =~ s/^\n+//s;
return $string;
}
# Done in evals to avoid confusing Perl::MinimumVersion
eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
sub _write {
local *FH;
open( FH, '>', $_[0] ) or die "open($_[0]): $!";
foreach ( 1 .. $#_ ) {
print FH $_[$_] or die "print($_[0]): $!";
}
close FH or die "close($_[0]): $!";
}
END_NEW
sub _write {
local *FH;
open( FH, "> $_[0]" ) or die "open($_[0]): $!";
foreach ( 1 .. $#_ ) {
print FH $_[$_] or die "print($_[0]): $!";
}
close FH or die "close($_[0]): $!";
}
END_OLD
# _version is for processing module versions (eg, 1.03_05) not
# Perl versions (eg, 5.8.1).
sub _version ($) {
my $s = shift || 0;
my $d =()= $s =~ /(\.)/g;
if ( $d >= 2 ) {
# Normalise multipart versions
$s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg;
}
$s =~ s/^(\d+)\.?//;
my $l = $1 || 0;
my @v = map {
$_ . '0' x (3 - length $_)
} $s =~ /(\d{1,3})\D?/g;
$l = $l . '.' . join '', @v if @v;
return $l + 0;
}
sub _cmp ($$) {
_version($_[1]) <=> _version($_[2]);
}
# Cloned from Params::Util::_CLASS
sub _CLASS ($) {
(
defined $_[0]
and
! ref $_[0]
and
$_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s
) ? $_[0] : undef;
}
1;
# Copyright 2008 - 2012 Adam Kennedy.
inc/Module/Install/AuthorRequires.pm view on Meta::CPAN
#line 1
use strict;
use warnings;
package Module::Install::AuthorRequires;
use base 'Module::Install::Base';
# cargo cult
BEGIN {
our $VERSION = '0.02';
our $ISCORE = 1;
}
sub author_requires {
my $self = shift;
return $self->{values}->{author_requires}
unless @_;
my @added;
while (@_) {
my $mod = shift or last;
my $version = shift || 0;
push @added, [$mod => $version];
}
push @{ $self->{values}->{author_requires} }, @added;
$self->admin->author_requires(@added);
return map { @$_ } @added;
}
1;
__END__
#line 92
inc/Module/Install/AuthorTests.pm view on Meta::CPAN
#line 1
package Module::Install::AuthorTests;
use 5.005;
use strict;
use Module::Install::Base;
use Carp ();
#line 16
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
$VERSION = '0.002';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
#line 42
sub author_tests {
my ($self, @dirs) = @_;
_add_author_tests($self, \@dirs, 0);
}
#line 56
sub recursive_author_tests {
my ($self, @dirs) = @_;
_add_author_tests($self, \@dirs, 1);
}
sub _wanted {
my $href = shift;
sub { /\.t$/ and -f $_ and $href->{$File::Find::dir} = 1 }
}
sub _add_author_tests {
my ($self, $dirs, $recurse) = @_;
return unless $Module::Install::AUTHOR;
my @tests = $self->tests ? (split / /, $self->tests) : 't/*.t';
# XXX: pick a default, later -- rjbs, 2008-02-24
my @dirs = @$dirs ? @$dirs : Carp::confess "no dirs given to author_tests";
@dirs = grep { -d } @dirs;
if ($recurse) {
require File::Find;
my %test_dir;
File::Find::find(_wanted(\%test_dir), @dirs);
$self->tests( join ' ', @tests, map { "$_/*.t" } sort keys %test_dir );
} else {
$self->tests( join ' ', @tests, map { "$_/*.t" } sort @dirs );
}
}
#line 107
1;
inc/Module/Install/AutoInstall.pm view on Meta::CPAN
#line 1
package Module::Install::AutoInstall;
use strict;
use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
sub AutoInstall { $_[0] }
sub run {
my $self = shift;
$self->auto_install_now(@_);
}
sub write {
my $self = shift;
$self->auto_install(@_);
}
sub auto_install {
my $self = shift;
return if $self->{done}++;
# Flatten array of arrays into a single array
my @core = map @$_, map @$_, grep ref,
$self->build_requires, $self->requires;
my @config = @_;
# We'll need Module::AutoInstall
$self->include('Module::AutoInstall');
require Module::AutoInstall;
my @features_require = Module::AutoInstall->import(
(@config ? (-config => \@config) : ()),
(@core ? (-core => \@core) : ()),
$self->features,
);
my %seen;
my @requires = map @$_, map @$_, grep ref, $self->requires;
while (my ($mod, $ver) = splice(@requires, 0, 2)) {
$seen{$mod}{$ver}++;
}
my @build_requires = map @$_, map @$_, grep ref, $self->build_requires;
while (my ($mod, $ver) = splice(@build_requires, 0, 2)) {
$seen{$mod}{$ver}++;
}
my @configure_requires = map @$_, map @$_, grep ref, $self->configure_requires;
while (my ($mod, $ver) = splice(@configure_requires, 0, 2)) {
$seen{$mod}{$ver}++;
}
my @deduped;
while (my ($mod, $ver) = splice(@features_require, 0, 2)) {
push @deduped, $mod => $ver unless $seen{$mod}{$ver}++;
}
$self->requires(@deduped);
$self->makemaker_args( Module::AutoInstall::_make_args() );
my $class = ref($self);
$self->postamble(
"# --- $class section:\n" .
Module::AutoInstall::postamble()
);
}
sub installdeps_target {
my ($self, @args) = @_;
$self->include('Module::AutoInstall');
require Module::AutoInstall;
Module::AutoInstall::_installdeps_target(1);
$self->auto_install(@args);
}
sub auto_install_now {
my $self = shift;
$self->auto_install(@_);
Module::AutoInstall::do_install();
}
1;
inc/Module/Install/Base.pm view on Meta::CPAN
#line 1
package Module::Install::Base;
use strict 'vars';
use vars qw{$VERSION};
BEGIN {
$VERSION = '1.06';
}
# Suspend handler for "redefined" warnings
BEGIN {
my $w = $SIG{__WARN__};
$SIG{__WARN__} = sub { $w };
}
#line 42
sub new {
my $class = shift;
unless ( defined &{"${class}::call"} ) {
*{"${class}::call"} = sub { shift->_top->call(@_) };
}
unless ( defined &{"${class}::load"} ) {
*{"${class}::load"} = sub { shift->_top->load(@_) };
}
bless { @_ }, $class;
}
#line 61
sub AUTOLOAD {
local $@;
my $func = eval { shift->_top->autoload } or return;
goto &$func;
}
#line 75
sub _top {
$_[0]->{_top};
}
#line 90
sub admin {
$_[0]->_top->{admin}
or
Module::Install::Base::FakeAdmin->new;
}
#line 106
sub is_admin {
! $_[0]->admin->isa('Module::Install::Base::FakeAdmin');
}
sub DESTROY {}
package Module::Install::Base::FakeAdmin;
use vars qw{$VERSION};
BEGIN {
$VERSION = $Module::Install::Base::VERSION;
}
my $fake;
sub new {
$fake ||= bless(\@_, $_[0]);
}
sub AUTOLOAD {}
sub DESTROY {}
# Restore warning handler
BEGIN {
$SIG{__WARN__} = $SIG{__WARN__}->();
}
1;
#line 159
inc/Module/Install/Can.pm view on Meta::CPAN
#line 1
package Module::Install::Can;
use strict;
use Config ();
use ExtUtils::MakeMaker ();
use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
# check if we can load some module
### Upgrade this to not have to load the module if possible
sub can_use {
my ($self, $mod, $ver) = @_;
$mod =~ s{::|\\}{/}g;
$mod .= '.pm' unless $mod =~ /\.pm$/i;
my $pkg = $mod;
$pkg =~ s{/}{::}g;
$pkg =~ s{\.pm$}{}i;
local $@;
eval { require $mod; $pkg->VERSION($ver || 0); 1 };
}
# Check if we can run some command
sub can_run {
my ($self, $cmd) = @_;
my $_cmd = $cmd;
return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));
for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
next if $dir eq '';
require File::Spec;
my $abs = File::Spec->catfile($dir, $cmd);
return $abs if (-x $abs or $abs = MM->maybe_command($abs));
}
return;
}
# Can our C compiler environment build XS files
sub can_xs {
my $self = shift;
# Ensure we have the CBuilder module
$self->configure_requires( 'ExtUtils::CBuilder' => 0.27 );
# Do we have the configure_requires checker?
local $@;
eval "require ExtUtils::CBuilder;";
if ( $@ ) {
# They don't obey configure_requires, so it is
# someone old and delicate. Try to avoid hurting
# them by falling back to an older simpler test.
return $self->can_cc();
}
# Do we have a working C compiler
my $builder = ExtUtils::CBuilder->new(
quiet => 1,
);
unless ( $builder->have_compiler ) {
# No working C compiler
return 0;
}
# Write a C file representative of what XS becomes
require File::Temp;
my ( $FH, $tmpfile ) = File::Temp::tempfile(
"compilexs-XXXXX",
SUFFIX => '.c',
);
binmode $FH;
print $FH <<'END_C';
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
int main(int argc, char **argv) {
return 0;
}
int boot_sanexs() {
return 1;
}
END_C
close $FH;
# Can the C compiler access the same headers XS does
my @libs = ();
my $object = undef;
eval {
local $^W = 0;
$object = $builder->compile(
source => $tmpfile,
);
@libs = $builder->link(
objects => $object,
module_name => 'sanexs',
);
};
my $result = $@ ? 0 : 1;
# Clean up all the build files
foreach ( $tmpfile, $object, @libs ) {
next unless defined $_;
1 while unlink;
}
return $result;
}
# Can we locate a (the) C compiler
sub can_cc {
my $self = shift;
my @chunks = split(/ /, $Config::Config{cc}) or return;
# $Config{cc} may contain args; try to find out the program part
while (@chunks) {
return $self->can_run("@chunks") || (pop(@chunks), next);
}
return;
}
# Fix Cygwin bug on maybe_command();
if ( $^O eq 'cygwin' ) {
require ExtUtils::MM_Cygwin;
require ExtUtils::MM_Win32;
if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) {
*ExtUtils::MM_Cygwin::maybe_command = sub {
my ($self, $file) = @_;
if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) {
ExtUtils::MM_Win32->maybe_command($file);
} else {
ExtUtils::MM_Unix->maybe_command($file);
}
}
}
}
1;
__END__
#line 236
inc/Module/Install/Catalyst.pm view on Meta::CPAN
#line 1
package Module::Install::Catalyst;
use strict;
use base qw/ Module::Install::Base /;
our @ISA;
require Module::Install::Base;
use File::Find;
use FindBin;
use File::Copy::Recursive;
use File::Spec ();
use Getopt::Long ();
use Data::Dumper;
my $SAFETY = 0;
our @IGNORE =
qw/Build Build.PL Changes MANIFEST META.yml Makefile.PL Makefile README
_build blib lib script t inc .*\.svn \.git _darcs \.bzr \.hg
debian build-stamp install-stamp configure-stamp/;
#line 52
sub catalyst {
my $self = shift;
if($Module::Install::AUTHOR) {
$self->include("File::Copy::Recursive");
}
print <<EOF;
*** Module::Install::Catalyst
EOF
$self->catalyst_files;
print <<EOF;
*** Module::Install::Catalyst finished.
EOF
}
#line 76
sub catalyst_files {
my $self = shift;
chdir $FindBin::Bin;
my @files;
opendir CATDIR, '.';
CATFILES: for my $name ( readdir CATDIR ) {
for my $ignore (@IGNORE) {
next CATFILES if $name =~ /^$ignore$/;
next CATFILES if $name !~ /\w/;
}
push @files, $name;
}
closedir CATDIR;
my @path = split '-', $self->name;
for my $orig (@files) {
my $path = File::Spec->catdir( 'blib', 'lib', @path, $orig );
File::Copy::Recursive::rcopy( $orig, $path );
}
}
#line 104
sub catalyst_ignore_all {
my ( $self, $ignore ) = @_;
@IGNORE = @$ignore;
}
#line 115
sub catalyst_ignore {
my ( $self, @ignore ) = @_;
push @IGNORE, @ignore;
}
#line 131
1;
inc/Module/Install/External.pm view on Meta::CPAN
#line 1
package Module::Install::External;
# Provides dependency declarations for external non-Perl things
use strict;
use Module::Install::Base ();
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
$VERSION = '1.06';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
sub requires_xs {
my $self = shift;
# First check for the basic C compiler
$self->requires_external_cc;
# We need a C compiler that can build XS files
unless ( $self->can_xs ) {
print "Unresolvable missing external dependency.\n";
print "This package requires perl's header files.\n";
print STDERR "NA: Unable to build distribution on this platform.\n";
exit(0);
}
1;
}
sub requires_external_cc {
my $self = shift;
# We need a C compiler, use the can_cc method for this
unless ( $self->can_cc ) {
print "Unresolvable missing external dependency.\n";
print "This package requires a C compiler.\n";
print STDERR "NA: Unable to build distribution on this platform.\n";
exit(0);
}
# Unlike some of the other modules, while we need to specify a
# C compiler as a dep, it needs to be a build-time dependency.
1;
}
sub requires_external_bin {
my ($self, $bin, $version) = @_;
if ( $version ) {
die "requires_external_bin does not support versions yet";
}
# Load the package containing can_run early,
# to avoid breaking the message below.
$self->load('can_run');
# Locate the bin
print "Locating bin:$bin...";
my $found_bin = $self->can_run( $bin );
if ( $found_bin ) {
print " found at $found_bin.\n";
} else {
print " missing.\n";
print "Unresolvable missing external dependency.\n";
print "Please install '$bin' seperately and try again.\n";
print STDERR "NA: Unable to build distribution on this platform.\n";
exit(0);
}
# Once we have some way to specify external deps, do it here.
# In the mean time, continue as normal.
1;
}
1;
__END__
#line 171
inc/Module/Install/Fetch.pm view on Meta::CPAN
#line 1
package Module::Install::Fetch;
use strict;
use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
sub get_file {
my ($self, %args) = @_;
my ($scheme, $host, $path, $file) =
$args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) {
$args{url} = $args{ftp_url}
or (warn("LWP support unavailable!\n"), return);
($scheme, $host, $path, $file) =
$args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
}
$|++;
print "Fetching '$file' from $host... ";
unless (eval { require Socket; Socket::inet_aton($host) }) {
warn "'$host' resolve failed!\n";
return;
}
return unless $scheme eq 'ftp' or $scheme eq 'http';
require Cwd;
my $dir = Cwd::getcwd();
chdir $args{local_dir} or return if exists $args{local_dir};
if (eval { require LWP::Simple; 1 }) {
LWP::Simple::mirror($args{url}, $file);
}
elsif (eval { require Net::FTP; 1 }) { eval {
# use Net::FTP to get past firewall
my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600);
$ftp->login("anonymous", 'anonymous@example.com');
$ftp->cwd($path);
$ftp->binary;
$ftp->get($file) or (warn("$!\n"), return);
$ftp->quit;
} }
elsif (my $ftp = $self->can_run('ftp')) { eval {
# no Net::FTP, fallback to ftp.exe
require FileHandle;
my $fh = FileHandle->new;
local $SIG{CHLD} = 'IGNORE';
unless ($fh->open("|$ftp -n")) {
warn "Couldn't open ftp: $!\n";
chdir $dir; return;
}
my @dialog = split(/\n/, <<"END_FTP");
open $host
user anonymous anonymous\@example.com
cd $path
binary
get $file $file
quit
END_FTP
foreach (@dialog) { $fh->print("$_\n") }
$fh->close;
} }
else {
warn "No working 'ftp' program available!\n";
chdir $dir; return;
}
unless (-f $file) {
warn "Fetching failed: $@\n";
chdir $dir; return;
}
return if exists $args{size} and -s $file != $args{size};
system($args{run}) if exists $args{run};
unlink($file) if $args{remove};
print(((!exists $args{check_for} or -e $args{check_for})
? "done!" : "failed! ($!)"), "\n");
chdir $dir; return !$?;
}
1;
inc/Module/Install/Include.pm view on Meta::CPAN
#line 1
package Module::Install::Include;
use strict;
use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
sub include {
shift()->admin->include(@_);
}
sub include_deps {
shift()->admin->include_deps(@_);
}
sub auto_include {
shift()->admin->auto_include(@_);
}
sub auto_include_deps {
shift()->admin->auto_include_deps(@_);
}
sub auto_include_dependent_dists {
shift()->admin->auto_include_dependent_dists(@_);
}
1;
inc/Module/Install/Makefile.pm view on Meta::CPAN
#line 1
package Module::Install::Makefile;
use strict 'vars';
use ExtUtils::MakeMaker ();
use Module::Install::Base ();
use Fcntl qw/:flock :seek/;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
sub Makefile { $_[0] }
my %seen = ();
sub prompt {
shift;
# Infinite loop protection
my @c = caller();
if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) {
die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
}
# In automated testing or non-interactive session, always use defaults
if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) {
local $ENV{PERL_MM_USE_DEFAULT} = 1;
goto &ExtUtils::MakeMaker::prompt;
} else {
goto &ExtUtils::MakeMaker::prompt;
}
}
# Store a cleaned up version of the MakeMaker version,
# since we need to behave differently in a variety of
# ways based on the MM version.
my $makemaker = eval $ExtUtils::MakeMaker::VERSION;
# If we are passed a param, do a "newer than" comparison.
# Otherwise, just return the MakeMaker version.
sub makemaker {
( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0
}
# Ripped from ExtUtils::MakeMaker 6.56, and slightly modified
# as we only need to know here whether the attribute is an array
# or a hash or something else (which may or may not be appendable).
my %makemaker_argtype = (
C => 'ARRAY',
CONFIG => 'ARRAY',
# CONFIGURE => 'CODE', # ignore
DIR => 'ARRAY',
DL_FUNCS => 'HASH',
DL_VARS => 'ARRAY',
EXCLUDE_EXT => 'ARRAY',
EXE_FILES => 'ARRAY',
FUNCLIST => 'ARRAY',
H => 'ARRAY',
IMPORTS => 'HASH',
INCLUDE_EXT => 'ARRAY',
LIBS => 'ARRAY', # ignore ''
MAN1PODS => 'HASH',
MAN3PODS => 'HASH',
META_ADD => 'HASH',
META_MERGE => 'HASH',
PL_FILES => 'HASH',
PM => 'HASH',
PMLIBDIRS => 'ARRAY',
PMLIBPARENTDIRS => 'ARRAY',
PREREQ_PM => 'HASH',
CONFIGURE_REQUIRES => 'HASH',
SKIP => 'ARRAY',
TYPEMAPS => 'ARRAY',
XS => 'HASH',
# VERSION => ['version',''], # ignore
# _KEEP_AFTER_FLUSH => '',
clean => 'HASH',
depend => 'HASH',
dist => 'HASH',
dynamic_lib=> 'HASH',
linkext => 'HASH',
macro => 'HASH',
postamble => 'HASH',
realclean => 'HASH',
test => 'HASH',
tool_autosplit => 'HASH',
# special cases where you can use makemaker_append
CCFLAGS => 'APPENDABLE',
DEFINE => 'APPENDABLE',
INC => 'APPENDABLE',
LDDLFLAGS => 'APPENDABLE',
LDFROM => 'APPENDABLE',
);
sub makemaker_args {
my ($self, %new_args) = @_;
my $args = ( $self->{makemaker_args} ||= {} );
foreach my $key (keys %new_args) {
if ($makemaker_argtype{$key}) {
if ($makemaker_argtype{$key} eq 'ARRAY') {
$args->{$key} = [] unless defined $args->{$key};
unless (ref $args->{$key} eq 'ARRAY') {
$args->{$key} = [$args->{$key}]
}
push @{$args->{$key}},
ref $new_args{$key} eq 'ARRAY'
? @{$new_args{$key}}
: $new_args{$key};
}
elsif ($makemaker_argtype{$key} eq 'HASH') {
$args->{$key} = {} unless defined $args->{$key};
foreach my $skey (keys %{ $new_args{$key} }) {
$args->{$key}{$skey} = $new_args{$key}{$skey};
}
}
elsif ($makemaker_argtype{$key} eq 'APPENDABLE') {
$self->makemaker_append($key => $new_args{$key});
}
}
else {
if (defined $args->{$key}) {
warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n};
}
$args->{$key} = $new_args{$key};
}
}
return $args;
}
# For mm args that take multiple space-seperated args,
# append an argument to the current list.
sub makemaker_append {
my $self = shift;
my $name = shift;
my $args = $self->makemaker_args;
$args->{$name} = defined $args->{$name}
? join( ' ', $args->{$name}, @_ )
: join( ' ', @_ );
}
sub build_subdirs {
my $self = shift;
my $subdirs = $self->makemaker_args->{DIR} ||= [];
for my $subdir (@_) {
push @$subdirs, $subdir;
}
}
sub clean_files {
my $self = shift;
my $clean = $self->makemaker_args->{clean} ||= {};
%$clean = (
%$clean,
FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_),
);
}
sub realclean_files {
my $self = shift;
my $realclean = $self->makemaker_args->{realclean} ||= {};
%$realclean = (
%$realclean,
FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_),
);
}
sub libs {
my $self = shift;
my $libs = ref $_[0] ? shift : [ shift ];
$self->makemaker_args( LIBS => $libs );
}
sub inc {
my $self = shift;
$self->makemaker_args( INC => shift );
}
sub _wanted_t {
}
sub tests_recursive {
my $self = shift;
my $dir = shift || 't';
unless ( -d $dir ) {
die "tests_recursive dir '$dir' does not exist";
}
my %tests = map { $_ => 1 } split / /, ($self->tests || '');
require File::Find;
File::Find::find(
sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 },
$dir
);
$self->tests( join ' ', sort keys %tests );
}
sub write {
my $self = shift;
die "&Makefile->write() takes no arguments\n" if @_;
# Check the current Perl version
my $perl_version = $self->perl_version;
if ( $perl_version ) {
eval "use $perl_version; 1"
or die "ERROR: perl: Version $] is installed, "
. "but we need version >= $perl_version";
}
# Make sure we have a new enough MakeMaker
require ExtUtils::MakeMaker;
if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) {
# This previous attempted to inherit the version of
# ExtUtils::MakeMaker in use by the module author, but this
# was found to be untenable as some authors build releases
# using future dev versions of EU:MM that nobody else has.
# Instead, #toolchain suggests we use 6.59 which is the most
# stable version on CPAN at time of writing and is, to quote
# ribasushi, "not terminally fucked, > and tested enough".
# TODO: We will now need to maintain this over time to push
# the version up as new versions are released.
$self->build_requires( 'ExtUtils::MakeMaker' => 6.59 );
$self->configure_requires( 'ExtUtils::MakeMaker' => 6.59 );
} else {
# Allow legacy-compatibility with 5.005 by depending on the
# most recent EU:MM that supported 5.005.
$self->build_requires( 'ExtUtils::MakeMaker' => 6.36 );
$self->configure_requires( 'ExtUtils::MakeMaker' => 6.36 );
}
# Generate the MakeMaker params
my $args = $self->makemaker_args;
$args->{DISTNAME} = $self->name;
$args->{NAME} = $self->module_name || $self->name;
$args->{NAME} =~ s/-/::/g;
$args->{VERSION} = $self->version or die <<'EOT';
ERROR: Can't determine distribution version. Please specify it
explicitly via 'version' in Makefile.PL, or set a valid $VERSION
in a module, and provide its file path via 'version_from' (or
'all_from' if you prefer) in Makefile.PL.
EOT
if ( $self->tests ) {
my @tests = split ' ', $self->tests;
my %seen;
$args->{test} = {
TESTS => (join ' ', grep {!$seen{$_}++} @tests),
};
} elsif ( $Module::Install::ExtraTests::use_extratests ) {
# Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness.
# So, just ignore our xt tests here.
} elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) {
$args->{test} = {
TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ),
};
}
if ( $] >= 5.005 ) {
$args->{ABSTRACT} = $self->abstract;
$args->{AUTHOR} = join ', ', @{$self->author || []};
}
if ( $self->makemaker(6.10) ) {
$args->{NO_META} = 1;
#$args->{NO_MYMETA} = 1;
}
if ( $self->makemaker(6.17) and $self->sign ) {
$args->{SIGN} = 1;
}
unless ( $self->is_admin ) {
delete $args->{SIGN};
}
if ( $self->makemaker(6.31) and $self->license ) {
$args->{LICENSE} = $self->license;
}
my $prereq = ($args->{PREREQ_PM} ||= {});
%$prereq = ( %$prereq,
map { @$_ } # flatten [module => version]
map { @$_ }
grep $_,
($self->requires)
);
# Remove any reference to perl, PREREQ_PM doesn't support it
delete $args->{PREREQ_PM}->{perl};
# Merge both kinds of requires into BUILD_REQUIRES
my $build_prereq = ($args->{BUILD_REQUIRES} ||= {});
%$build_prereq = ( %$build_prereq,
map { @$_ } # flatten [module => version]
map { @$_ }
grep $_,
($self->configure_requires, $self->build_requires)
);
# Remove any reference to perl, BUILD_REQUIRES doesn't support it
delete $args->{BUILD_REQUIRES}->{perl};
# Delete bundled dists from prereq_pm, add it to Makefile DIR
my $subdirs = ($args->{DIR} || []);
if ($self->bundles) {
my %processed;
foreach my $bundle (@{ $self->bundles }) {
my ($mod_name, $dist_dir) = @$bundle;
delete $prereq->{$mod_name};
$dist_dir = File::Basename::basename($dist_dir); # dir for building this module
if (not exists $processed{$dist_dir}) {
if (-d $dist_dir) {
# List as sub-directory to be processed by make
push @$subdirs, $dist_dir;
}
# Else do nothing: the module is already present on the system
$processed{$dist_dir} = undef;
}
}
}
unless ( $self->makemaker('6.55_03') ) {
%$prereq = (%$prereq,%$build_prereq);
delete $args->{BUILD_REQUIRES};
}
if ( my $perl_version = $self->perl_version ) {
eval "use $perl_version; 1"
or die "ERROR: perl: Version $] is installed, "
. "but we need version >= $perl_version";
if ( $self->makemaker(6.48) ) {
$args->{MIN_PERL_VERSION} = $perl_version;
}
}
if ($self->installdirs) {
warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS};
$args->{INSTALLDIRS} = $self->installdirs;
}
my %args = map {
( $_ => $args->{$_} ) } grep {defined($args->{$_} )
} keys %$args;
my $user_preop = delete $args{dist}->{PREOP};
if ( my $preop = $self->admin->preop($user_preop) ) {
foreach my $key ( keys %$preop ) {
$args{dist}->{$key} = $preop->{$key};
}
}
my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
$self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile');
}
sub fix_up_makefile {
my $self = shift;
my $makefile_name = shift;
my $top_class = ref($self->_top) || '';
my $top_version = $self->_top->VERSION || '';
my $preamble = $self->preamble
? "# Preamble by $top_class $top_version\n"
. $self->preamble
: '';
my $postamble = "# Postamble by $top_class $top_version\n"
. ($self->postamble || '');
local *MAKEFILE;
open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
eval { flock MAKEFILE, LOCK_EX };
my $makefile = do { local $/; <MAKEFILE> };
$makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
$makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
$makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g;
$makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m;
$makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m;
# Module::Install will never be used to build the Core Perl
# Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks
# PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist
$makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m;
#$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m;
# Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well.
$makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g;
# XXX - This is currently unused; not sure if it breaks other MM-users
# $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
seek MAKEFILE, 0, SEEK_SET;
truncate MAKEFILE, 0;
print MAKEFILE "$preamble$makefile$postamble" or die $!;
close MAKEFILE or die $!;
1;
}
sub preamble {
my ($self, $text) = @_;
$self->{preamble} = $text . $self->{preamble} if defined $text;
$self->{preamble};
}
sub postamble {
my ($self, $text) = @_;
$self->{postamble} ||= $self->admin->postamble;
$self->{postamble} .= $text if defined $text;
$self->{postamble}
}
1;
__END__
#line 544
inc/Module/Install/Metadata.pm view on Meta::CPAN
#line 1
package Module::Install::Metadata;
use strict 'vars';
use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
my @boolean_keys = qw{
sign
};
my @scalar_keys = qw{
name
module_name
abstract
version
distribution_type
tests
installdirs
};
my @tuple_keys = qw{
configure_requires
build_requires
requires
recommends
bundles
resources
};
my @resource_keys = qw{
homepage
bugtracker
repository
};
my @array_keys = qw{
keywords
author
};
*authors = \&author;
sub Meta { shift }
sub Meta_BooleanKeys { @boolean_keys }
sub Meta_ScalarKeys { @scalar_keys }
sub Meta_TupleKeys { @tuple_keys }
sub Meta_ResourceKeys { @resource_keys }
sub Meta_ArrayKeys { @array_keys }
foreach my $key ( @boolean_keys ) {
*$key = sub {
my $self = shift;
if ( defined wantarray and not @_ ) {
return $self->{values}->{$key};
}
$self->{values}->{$key} = ( @_ ? $_[0] : 1 );
return $self;
};
}
foreach my $key ( @scalar_keys ) {
*$key = sub {
my $self = shift;
return $self->{values}->{$key} if defined wantarray and !@_;
$self->{values}->{$key} = shift;
return $self;
};
}
foreach my $key ( @array_keys ) {
*$key = sub {
my $self = shift;
return $self->{values}->{$key} if defined wantarray and !@_;
$self->{values}->{$key} ||= [];
push @{$self->{values}->{$key}}, @_;
return $self;
};
}
foreach my $key ( @resource_keys ) {
*$key = sub {
my $self = shift;
unless ( @_ ) {
return () unless $self->{values}->{resources};
return map { $_->[1] }
grep { $_->[0] eq $key }
@{ $self->{values}->{resources} };
}
return $self->{values}->{resources}->{$key} unless @_;
my $uri = shift or die(
"Did not provide a value to $key()"
);
$self->resources( $key => $uri );
return 1;
};
}
foreach my $key ( grep { $_ ne "resources" } @tuple_keys) {
*$key = sub {
my $self = shift;
return $self->{values}->{$key} unless @_;
my @added;
while ( @_ ) {
my $module = shift or last;
my $version = shift || 0;
push @added, [ $module, $version ];
}
push @{ $self->{values}->{$key} }, @added;
return map {@$_} @added;
};
}
# Resource handling
my %lc_resource = map { $_ => 1 } qw{
homepage
license
bugtracker
repository
};
sub resources {
my $self = shift;
while ( @_ ) {
my $name = shift or last;
my $value = shift or next;
if ( $name eq lc $name and ! $lc_resource{$name} ) {
die("Unsupported reserved lowercase resource '$name'");
}
$self->{values}->{resources} ||= [];
push @{ $self->{values}->{resources} }, [ $name, $value ];
}
$self->{values}->{resources};
}
# Aliases for build_requires that will have alternative
# meanings in some future version of META.yml.
sub test_requires { shift->build_requires(@_) }
sub install_requires { shift->build_requires(@_) }
# Aliases for installdirs options
sub install_as_core { $_[0]->installdirs('perl') }
sub install_as_cpan { $_[0]->installdirs('site') }
sub install_as_site { $_[0]->installdirs('site') }
sub install_as_vendor { $_[0]->installdirs('vendor') }
sub dynamic_config {
my $self = shift;
my $value = @_ ? shift : 1;
if ( $self->{values}->{dynamic_config} ) {
# Once dynamic we never change to static, for safety
return 0;
}
$self->{values}->{dynamic_config} = $value ? 1 : 0;
return 1;
}
# Convenience command
sub static_config {
shift->dynamic_config(0);
}
sub perl_version {
my $self = shift;
return $self->{values}->{perl_version} unless @_;
my $version = shift or die(
"Did not provide a value to perl_version()"
);
# Normalize the version
$version = $self->_perl_version($version);
# We don't support the really old versions
unless ( $version >= 5.005 ) {
die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n";
}
$self->{values}->{perl_version} = $version;
}
sub all_from {
my ( $self, $file ) = @_;
unless ( defined($file) ) {
my $name = $self->name or die(
"all_from called with no args without setting name() first"
);
$file = join('/', 'lib', split(/-/, $name)) . '.pm';
$file =~ s{.*/}{} unless -e $file;
unless ( -e $file ) {
die("all_from cannot find $file from $name");
}
}
unless ( -f $file ) {
die("The path '$file' does not exist, or is not a file");
}
$self->{values}{all_from} = $file;
# Some methods pull from POD instead of code.
# If there is a matching .pod, use that instead
my $pod = $file;
$pod =~ s/\.pm$/.pod/i;
$pod = $file unless -e $pod;
# Pull the different values
$self->name_from($file) unless $self->name;
$self->version_from($file) unless $self->version;
$self->perl_version_from($file) unless $self->perl_version;
$self->author_from($pod) unless @{$self->author || []};
$self->license_from($pod) unless $self->license;
$self->abstract_from($pod) unless $self->abstract;
return 1;
}
sub provides {
my $self = shift;
my $provides = ( $self->{values}->{provides} ||= {} );
%$provides = (%$provides, @_) if @_;
return $provides;
}
sub auto_provides {
my $self = shift;
return $self unless $self->is_admin;
unless (-e 'MANIFEST') {
warn "Cannot deduce auto_provides without a MANIFEST, skipping\n";
return $self;
}
# Avoid spurious warnings as we are not checking manifest here.
local $SIG{__WARN__} = sub {1};
require ExtUtils::Manifest;
local *ExtUtils::Manifest::manicheck = sub { return };
require Module::Build;
my $build = Module::Build->new(
dist_name => $self->name,
dist_version => $self->version,
license => $self->license,
);
$self->provides( %{ $build->find_dist_packages || {} } );
}
sub feature {
my $self = shift;
my $name = shift;
my $features = ( $self->{values}->{features} ||= [] );
my $mods;
if ( @_ == 1 and ref( $_[0] ) ) {
# The user used ->feature like ->features by passing in the second
# argument as a reference. Accomodate for that.
$mods = $_[0];
} else {
$mods = \@_;
}
my $count = 0;
push @$features, (
$name => [
map {
ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_
} @$mods
]
);
return @$features;
}
sub features {
my $self = shift;
while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
$self->feature( $name, @$mods );
}
return $self->{values}->{features}
? @{ $self->{values}->{features} }
: ();
}
sub no_index {
my $self = shift;
my $type = shift;
push @{ $self->{values}->{no_index}->{$type} }, @_ if $type;
return $self->{values}->{no_index};
}
sub read {
my $self = shift;
$self->include_deps( 'YAML::Tiny', 0 );
require YAML::Tiny;
my $data = YAML::Tiny::LoadFile('META.yml');
# Call methods explicitly in case user has already set some values.
while ( my ( $key, $value ) = each %$data ) {
next unless $self->can($key);
if ( ref $value eq 'HASH' ) {
while ( my ( $module, $version ) = each %$value ) {
$self->can($key)->($self, $module => $version );
}
} else {
$self->can($key)->($self, $value);
}
}
return $self;
}
sub write {
my $self = shift;
return $self unless $self->is_admin;
$self->admin->write_meta;
return $self;
}
sub version_from {
require ExtUtils::MM_Unix;
my ( $self, $file ) = @_;
$self->version( ExtUtils::MM_Unix->parse_version($file) );
# for version integrity check
$self->makemaker_args( VERSION_FROM => $file );
}
sub abstract_from {
require ExtUtils::MM_Unix;
my ( $self, $file ) = @_;
$self->abstract(
bless(
{ DISTNAME => $self->name },
'ExtUtils::MM_Unix'
)->parse_abstract($file)
);
}
# Add both distribution and module name
sub name_from {
my ($self, $file) = @_;
if (
Module::Install::_read($file) =~ m/
^ \s*
package \s*
([\w:]+)
\s* ;
/ixms
) {
my ($name, $module_name) = ($1, $1);
$name =~ s{::}{-}g;
$self->name($name);
unless ( $self->module_name ) {
$self->module_name($module_name);
}
} else {
die("Cannot determine name from $file\n");
}
}
sub _extract_perl_version {
if (
$_[0] =~ m/
^\s*
(?:use|require) \s*
v?
([\d_\.]+)
\s* ;
/ixms
) {
my $perl_version = $1;
$perl_version =~ s{_}{}g;
return $perl_version;
} else {
return;
}
}
sub perl_version_from {
my $self = shift;
my $perl_version=_extract_perl_version(Module::Install::_read($_[0]));
if ($perl_version) {
$self->perl_version($perl_version);
} else {
warn "Cannot determine perl version info from $_[0]\n";
return;
}
}
sub author_from {
my $self = shift;
my $content = Module::Install::_read($_[0]);
if ($content =~ m/
=head \d \s+ (?:authors?)\b \s*
([^\n]*)
|
=head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
.*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
([^\n]*)
/ixms) {
my $author = $1 || $2;
# XXX: ugly but should work anyway...
if (eval "require Pod::Escapes; 1") {
# Pod::Escapes has a mapping table.
# It's in core of perl >= 5.9.3, and should be installed
# as one of the Pod::Simple's prereqs, which is a prereq
# of Pod::Text 3.x (see also below).
$author =~ s{ E<( (\d+) | ([A-Za-z]+) )> }
{
defined $2
? chr($2)
: defined $Pod::Escapes::Name2character_number{$1}
? chr($Pod::Escapes::Name2character_number{$1})
: do {
warn "Unknown escape: E<$1>";
"E<$1>";
};
}gex;
}
elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) {
# Pod::Text < 3.0 has yet another mapping table,
# though the table name of 2.x and 1.x are different.
# (1.x is in core of Perl < 5.6, 2.x is in core of
# Perl < 5.9.3)
my $mapping = ($Pod::Text::VERSION < 2)
? \%Pod::Text::HTML_Escapes
: \%Pod::Text::ESCAPES;
$author =~ s{ E<( (\d+) | ([A-Za-z]+) )> }
{
defined $2
? chr($2)
: defined $mapping->{$1}
? $mapping->{$1}
: do {
warn "Unknown escape: E<$1>";
"E<$1>";
};
}gex;
}
else {
$author =~ s{E<lt>}{<}g;
$author =~ s{E<gt>}{>}g;
}
$self->author($author);
} else {
warn "Cannot determine author info from $_[0]\n";
}
}
#Stolen from M::B
my %license_urls = (
perl => 'http://dev.perl.org/licenses/',
apache => 'http://apache.org/licenses/LICENSE-2.0',
apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1',
artistic => 'http://opensource.org/licenses/artistic-license.php',
artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php',
lgpl => 'http://opensource.org/licenses/lgpl-license.php',
lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php',
lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html',
bsd => 'http://opensource.org/licenses/bsd-license.php',
gpl => 'http://opensource.org/licenses/gpl-license.php',
gpl2 => 'http://opensource.org/licenses/gpl-2.0.php',
gpl3 => 'http://opensource.org/licenses/gpl-3.0.html',
mit => 'http://opensource.org/licenses/mit-license.php',
mozilla => 'http://opensource.org/licenses/mozilla1.1.php',
open_source => undef,
unrestricted => undef,
restrictive => undef,
unknown => undef,
);
sub license {
my $self = shift;
return $self->{values}->{license} unless @_;
my $license = shift or die(
'Did not provide a value to license()'
);
$license = __extract_license($license) || lc $license;
$self->{values}->{license} = $license;
# Automatically fill in license URLs
if ( $license_urls{$license} ) {
$self->resources( license => $license_urls{$license} );
}
return 1;
}
sub _extract_license {
my $pod = shift;
my $matched;
return __extract_license(
($matched) = $pod =~ m/
(=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?)
(=head \d.*|=cut.*|)\z
/xms
) || __extract_license(
($matched) = $pod =~ m/
(=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?)
(=head \d.*|=cut.*|)\z
/xms
);
}
sub __extract_license {
my $license_text = shift or return;
my @phrases = (
'(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1,
'(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1,
'Artistic and GPL' => 'perl', 1,
'GNU general public license' => 'gpl', 1,
'GNU public license' => 'gpl', 1,
'GNU lesser general public license' => 'lgpl', 1,
'GNU lesser public license' => 'lgpl', 1,
'GNU library general public license' => 'lgpl', 1,
'GNU library public license' => 'lgpl', 1,
'GNU Free Documentation license' => 'unrestricted', 1,
'GNU Affero General Public License' => 'open_source', 1,
'(?:Free)?BSD license' => 'bsd', 1,
'Artistic license 2\.0' => 'artistic_2', 1,
'Artistic license' => 'artistic', 1,
'Apache (?:Software )?license' => 'apache', 1,
'GPL' => 'gpl', 1,
'LGPL' => 'lgpl', 1,
'BSD' => 'bsd', 1,
'Artistic' => 'artistic', 1,
'MIT' => 'mit', 1,
'Mozilla Public License' => 'mozilla', 1,
'Q Public License' => 'open_source', 1,
'OpenSSL License' => 'unrestricted', 1,
'SSLeay License' => 'unrestricted', 1,
'zlib License' => 'open_source', 1,
'proprietary' => 'proprietary', 0,
);
while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
$pattern =~ s#\s+#\\s+#gs;
if ( $license_text =~ /\b$pattern\b/i ) {
return $license;
}
}
return '';
}
sub license_from {
my $self = shift;
if (my $license=_extract_license(Module::Install::_read($_[0]))) {
$self->license($license);
} else {
warn "Cannot determine license info from $_[0]\n";
return 'unknown';
}
}
sub _extract_bugtracker {
my @links = $_[0] =~ m#L<(
https?\Q://rt.cpan.org/\E[^>]+|
https?\Q://github.com/\E[\w_]+/[\w_]+/issues|
https?\Q://code.google.com/p/\E[\w_\-]+/issues/list
)>#gx;
my %links;
@links{@links}=();
@links=keys %links;
return @links;
}
sub bugtracker_from {
my $self = shift;
my $content = Module::Install::_read($_[0]);
my @links = _extract_bugtracker($content);
unless ( @links ) {
warn "Cannot determine bugtracker info from $_[0]\n";
return 0;
}
if ( @links > 1 ) {
warn "Found more than one bugtracker link in $_[0]\n";
return 0;
}
# Set the bugtracker
bugtracker( $links[0] );
return 1;
}
sub requires_from {
my $self = shift;
my $content = Module::Install::_readperl($_[0]);
my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+(v?[\d\.]+)/mg;
while ( @requires ) {
my $module = shift @requires;
my $version = shift @requires;
$self->requires( $module => $version );
}
}
sub test_requires_from {
my $self = shift;
my $content = Module::Install::_readperl($_[0]);
my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg;
while ( @requires ) {
my $module = shift @requires;
my $version = shift @requires;
$self->test_requires( $module => $version );
}
}
# Convert triple-part versions (eg, 5.6.1 or 5.8.9) to
# numbers (eg, 5.006001 or 5.008009).
# Also, convert double-part versions (eg, 5.8)
sub _perl_version {
my $v = $_[-1];
$v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e;
$v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e;
$v =~ s/(\.\d\d\d)000$/$1/;
$v =~ s/_.+$//;
if ( ref($v) ) {
# Numify
$v = $v + 0;
}
return $v;
}
sub add_metadata {
my $self = shift;
my %hash = @_;
for my $key (keys %hash) {
warn "add_metadata: $key is not prefixed with 'x_'.\n" .
"Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/;
$self->{values}->{$key} = $hash{$key};
}
}
######################################################################
# MYMETA Support
sub WriteMyMeta {
die "WriteMyMeta has been deprecated";
}
sub write_mymeta_yaml {
my $self = shift;
# We need YAML::Tiny to write the MYMETA.yml file
unless ( eval { require YAML::Tiny; 1; } ) {
return 1;
}
# Generate the data
my $meta = $self->_write_mymeta_data or return 1;
# Save as the MYMETA.yml file
print "Writing MYMETA.yml\n";
YAML::Tiny::DumpFile('MYMETA.yml', $meta);
}
sub write_mymeta_json {
my $self = shift;
# We need JSON to write the MYMETA.json file
unless ( eval { require JSON; 1; } ) {
return 1;
}
# Generate the data
my $meta = $self->_write_mymeta_data or return 1;
# Save as the MYMETA.yml file
print "Writing MYMETA.json\n";
Module::Install::_write(
'MYMETA.json',
JSON->new->pretty(1)->canonical->encode($meta),
);
}
sub _write_mymeta_data {
my $self = shift;
# If there's no existing META.yml there is nothing we can do
return undef unless -f 'META.yml';
# We need Parse::CPAN::Meta to load the file
unless ( eval { require Parse::CPAN::Meta; 1; } ) {
return undef;
}
# Merge the perl version into the dependencies
my $val = $self->Meta->{values};
my $perl = delete $val->{perl_version};
if ( $perl ) {
$val->{requires} ||= [];
my $requires = $val->{requires};
# Canonize to three-dot version after Perl 5.6
if ( $perl >= 5.006 ) {
$perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e
}
unshift @$requires, [ perl => $perl ];
}
# Load the advisory META.yml file
my @yaml = Parse::CPAN::Meta::LoadFile('META.yml');
my $meta = $yaml[0];
# Overwrite the non-configure dependency hashs
delete $meta->{requires};
delete $meta->{build_requires};
delete $meta->{recommends};
if ( exists $val->{requires} ) {
$meta->{requires} = { map { @$_ } @{ $val->{requires} } };
}
if ( exists $val->{build_requires} ) {
$meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } };
}
return $meta;
}
1;
inc/Module/Install/Scripts.pm view on Meta::CPAN
#line 1
package Module::Install::Scripts;
use strict 'vars';
use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
sub install_script {
my $self = shift;
my $args = $self->makemaker_args;
my $exe = $args->{EXE_FILES} ||= [];
foreach ( @_ ) {
if ( -f $_ ) {
push @$exe, $_;
} elsif ( -d 'script' and -f "script/$_" ) {
push @$exe, "script/$_";
} else {
die("Cannot find script '$_'");
}
}
}
1;
inc/Module/Install/Win32.pm view on Meta::CPAN
#line 1
package Module::Install::Win32;
use strict;
use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
# determine if the user needs nmake, and download it if needed
sub check_nmake {
my $self = shift;
$self->load('can_run');
$self->load('get_file');
require Config;
return unless (
$^O eq 'MSWin32' and
$Config::Config{make} and
$Config::Config{make} =~ /^nmake\b/i and
! $self->can_run('nmake')
);
print "The required 'nmake' executable not found, fetching it...\n";
require File::Basename;
my $rv = $self->get_file(
url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe',
ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe',
local_dir => File::Basename::dirname($^X),
size => 51928,
run => 'Nmake15.exe /o > nul',
check_for => 'Nmake.exe',
remove => 1,
);
die <<'END_MESSAGE' unless $rv;
-------------------------------------------------------------------------------
Since you are using Microsoft Windows, you will need the 'nmake' utility
before installation. It's available at:
http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe
or
ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe
Please download the file manually, save it to a directory in %PATH% (e.g.
C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to
that directory, and run "Nmake15.exe" from there; that will create the
'nmake.exe' file needed by this module.
You may then resume the installation process described in README.
-------------------------------------------------------------------------------
END_MESSAGE
}
1;
inc/Module/Install/WriteAll.pm view on Meta::CPAN
#line 1
package Module::Install::WriteAll;
use strict;
use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
$VERSION = '1.06';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
sub WriteAll {
my $self = shift;
my %args = (
meta => 1,
sign => 0,
inline => 0,
check_nmake => 1,
@_,
);
$self->sign(1) if $args{sign};
$self->admin->WriteAll(%args) if $self->is_admin;
$self->check_nmake if $args{check_nmake};
unless ( $self->makemaker_args->{PL_FILES} ) {
# XXX: This still may be a bit over-defensive...
unless ($self->makemaker(6.25)) {
$self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL';
}
}
# Until ExtUtils::MakeMaker support MYMETA.yml, make sure
# we clean it up properly ourself.
$self->realclean_files('MYMETA.yml');
if ( $args{inline} ) {
$self->Inline->write;
} else {
$self->Makefile->write;
}
# The Makefile write process adds a couple of dependencies,
# so write the META.yml files after the Makefile.
if ( $args{meta} ) {
$self->Meta->write;
}
# Experimental support for MYMETA
if ( $ENV{X_MYMETA} ) {
if ( $ENV{X_MYMETA} eq 'JSON' ) {
$self->Meta->write_mymeta_json;
} else {
$self->Meta->write_mymeta_yaml;
}
}
return 1;
}
1;
lib/Gitalist.pm view on Meta::CPAN
package Gitalist;
BEGIN { require 5.008006; }
use Moose;
extends 'Catalyst';
use Git::Gitalist::Util;
use Catalyst::Runtime 5.90006;
use Catalyst qw/
ConfigLoader
Unicode::Encoding
Static::Simple
StackTrace
SubRequest
/;
use namespace::autoclean;
our $VERSION = '0.005001';
$VERSION = eval $VERSION;
__PACKAGE__->config(
name => 'Gitalist',
default_view => 'Default',
default_model => 'CollectionOfRepos',
use_request_uri_for_path => 1,
disable_component_resolution_regex_fallback => 1,
);
__PACKAGE__->setup();
after prepare_path => sub {
my ($ctx) = @_;
my $path = $ctx->req->uri->path;
if ($ctx->req->param('a')) {
$ctx->req->uri->path("/legacy$path");
}
if($path =~ s/[.]json$// && $ctx->req->content_type eq 'application/json') {
$ctx->req->uri->path($path);
}
};
around uri_for => sub {
my ($orig, $c) = (shift, shift);
my $uri = $c->$orig(@_);
$$uri =~ tr[&][;] if defined $uri;
return $uri;
};
sub uri_with {
my ($self, @args) = @_;
my $uri = $self->request->uri_with(@args);
# Wow this awful.
$uri =~ s[/fragment\b][];
return $uri;
}
after setup_finalize => sub {
# At app startup, ensure we can find a git binary, rather than
# lazily breaking later at request time.
Git::Gitalist::Util::git_executable_path()
or die <<ERR;
No git executable found in PATH.
Please specify which git executable to use in gitalist.conf or ensure that
a git executable is reachable in the PATH environment variable.
ERR
};
1;
__END__
=encoding UTF-8
=head1 NAME
Gitalist - A modern git web viewer
=head1 SYNOPSIS
perl script/gitalist_server.pl --repo_dir /home/me/code/git
=head1 INSTALL
As Gitalist follows the usual Perl module format the usual approach
for installation should work, e.g.:
perl Makefile.PL
make
make test
make install
or
cpan -i Gitalist
You can also L<check Gitalist out from its git repository|/"GETTING GITALIST">
and run it, in this case you'll additionally need the author modules,
but no configuration will be needed as it will default to looking
for repositories the directory above the checkout.
=head1 DESCRIPTION
Gitalist is a web frontend for git repositories based on
L<gitweb.cgi|https://git.wiki.kernel.org/index.php/Gitweb> and backed by
L<Catalyst>.
=head2 History
This project started off as an attempt to port I<gitweb.cgi> to a
Catalyst app in a piecemeal fashion. As it turns out, thanks largely
to Florian Ragwitz's earlier effort, it was easier to use I<gitweb.cgi>
as a template for building a new Catalyst application.
=head1 GETTING GITALIST
You can install Gitalist from CPAN in the usual way:
cpan -i Gitalist
Alternatively, you can get Gitalist using git.
The canonical repository for the master branch is:
git://git.shadowcat.co.uk/catagits/Gitalist.git
Gitalist is also mirrored to GitHub at L<https://github.com/broquaint/Gitalist>,
and a number of people have active forks
with branches and/or new features in the master branch.
=head1 BOOTSTRAPPING
As of C<0.002001> Gitalist can now be bootstrapped to run out of its
own directory by installing its prerequisites locally with the help of
L<local::lib>. So instead of installing the prerequisites to the
system path with CPAN they are installed under the Gitalist directory.
To do this clone Gitalist from the L<Shadowcat repository mentioned
above|/"GETTING GITALIST"> or grab a snapshot from broquaint's GitHub repository:
https://github.com/broquaint/Gitalist/downloads
With the source acquired and unpacked run the following from within the
Gitalist directory:
perl script/bootstrap.pl
This will install the necessary modules for the build process which in
turn installs the prerequisites locally.
B<NB:> The relevant bootstrap scripts aren't available in the CPAN dist
as the bootstrap scripts should not be installed.
=head1 INITIAL CONFIGURATION
Gitalist is configured using L<Catalyst::Plugin::Configloader>. The supplied sample
configuration is in L<Config::General> format, however it is possible to configure
Gitalist using other config file formats (such as YAML) if you prefer.
=head2 WHEN CHECKING GITALIST OUT OF GIT
Gitalist from git includes a minimal C<gitalist_local.conf>, which sets the repository
directory to one directory higher than the Gitalist repository.
This means that if you check Gitalist out next to your other git checkouts, then starting
the demo server needs no parameters at all:
Gitalist [master]$ perl script/gitalist_server.pl
You can connect to your server at http://localhost:3000
=head2 FOR CPAN INSTALLS
Gitalist can be supplied with a config file by setting the C<< GITALIST_CONFIG >>
environment variable to point to a configuration file.
If you install Gitalist from CPAN, a default configuration is installed along with gitalist,
which is complete except for a repository directory. You can get a copy of this configuration
by running:
cp `perl -Ilib -MGitalist -e'print Gitalist->path_to("gitalist.conf")'` gitalist.conf
You can then edit this configuration, adding a C<repo_dir> path and customising
other settings as desired.
You can then start the Gitalist demo server by setting C<< GITALIST_CONFIG >>. For example:
GITALIST_CONFIG=/usr/local/etc/gitalist.conf gitalist_server.pl
Alternatively, if you only want to set a repository directory and are otherwise happy with
the default configuration, then you can set the C<< GITALIST_REPO_DIR >> environment
variable, or pass the C<< --repo_dir >> flag to any of the scripts.
GITALIST_REPO_DIR=/home/myuser/code/git gitalist_server.pl
gitalist_server.pl --repo_dir home/myuser/code/git
The C<< GITALIST_REPO_DIR >> environment variable will override the repository directory set
in configuration, and will itself be overridden by he C<< --repo_dir >> flag.
=head1 RUNNING
Once you have followed the instructions above to install and configure Gitalist, you may want
to run it in a more production facing environment than using the single threaded developement
server.
The recommended deployment method for Gitalist is FastCGI, although Gitalist can also be run
under L<mod_perl|https://perl.apache.org/> or as pure Perl with L<Catalyst::Engine::PreFork>.
Assuming that you have installed Gitalist's dependencies into a L<local::lib>, and you
are running from a git checkout, adding a trivial FCGI script as C<script/gitalist.fcgi>
(this file is specifically in C<.gitignore> so you can have your own copy):
#!/bin/sh
exec /home/t0m/public_html/Gitalist/script/gitalist_fastcgi.pl
This example can be seen live here:
http://example.gitalist.com
=head2 Plack
If you would like to run Gitalist under L<Plack> then one need only
make use of L<plackup|search.cpan.org/perldoc?plackup> and the
C<.psgi> found under C<scripts/>:
plackup script/gitalist_app.psgi
=head1 CONFIGURATION
The Gitalist config is loaded with L<Catalyst::Plugin::ConfigLoader>
and the available config options are:
=over
=item no_gravatars
If true don't display gravatars. May be desirable if you are worried about
leaking repo names via the browser referer headers.
=back
=head2 Model::CollectionOfRepos
=over
=item repo_dir
A directory containing the directories to show.
=item repos
A list of directories containing repositories to show.
=item search_recursively
A boolean indicating whether to always search recursively for
repositories within C<repo_dir>.
=item whitelist
Path a file containing a list of repositories that can be shown. Each
line in the file will represent the name of a repo to show e.g
Gitalist
some-bare-repo.git
This is compatible with C<gitweb>'s C<projects.list>.
=item export_ok
If provided every must contain a file of the same name to be
visible. This is similar to C<gitweb>'s functionality.
=item class
If you want a different way of surfacing repositories you can use your
own model (i.e something that composes
L<Gitalist::Git::CollectionOfRepositories>) and specify the class name with
this config option.
=item args
Any additional arguments to be passed into the Model constructor, only
of use when used in conjunction with C<class> (see above).
=back
=head2 paging
=over
=item log
The number of commits to show in the summary, shortlog and longlog views.
=back
=head2 FASTCGI
Running Gitalist in FastCGI mode requires a webserver with FastCGI
support (such as apache with L<mod_fcgi|http://www.fastcgi.com/drupal/node/3>
or L<mod_fcgid|https://httpd.apache.org/mod_fcgid/>). Below is a sample
configuration using Apache2 with mod_fcgid in a dynamic configuration
(as opposed to static or standalone mode). More information on these modes and
their configuration can be found at L<Catalyst::Engine::FastCGI/"Standalone server mode">.
In Apache's F<mime.conf>, add C<AddHandler fcgid-script .fcgi>
(or C<AddHandler fastcgi-script .fcgi> for mod_fcgi).
And a quick VirtualHost configuration:
<VirtualHost *:80>
ServerName gitalist.yourdomain.com
DocumentRoot /path/to/gitalist.fcgi
<Directory "/path/to/gitalist.fcgi">
AllowOverride all
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
# Tell Apache this is a FastCGI application
<Files gitalist.fcgi>
#change the below to fastcgi-script if using mod_fcgi
SetHandler fcgid-script
</Files>
</VirtualHost>
Now to access your Gitalist instance, you'll go to
C<gitalist.yourdomain.com/gitalist.fcgi/> (B<do not forget that trailing> C</>).
If you'd like a different URL, of course, you'll likely want to use
L<mod_rewrite|https://httpd.apache.org/docs/mod/mod_rewrite.html> or equivalent.
If you find the need to do some troubleshooting, you can call
C<http://url_to_gitalist.fcgi?dump_info=1> and/or add export C<GITALIST_DEBUG=1>
to the top of your F<gitalist.fcgi> file (just below the shebang line).
=head2 Apache config
Apache will refuse C<%2F> in Gitalist URLs unless configured otherwise. Make
sure C<AllowEncodedSlashes On> is in your F<httpd.conf> file in order for
this to run smoothly.
To have the static content served statically by Apache, instead of
Gitalist, then add something like following line to your F<httpd.conf>:
Alias /static /usr/local/share/perl/5.10.1/Gitalist/root/static
=head1 CONTRIBUTING
Patches are welcome, please feel free to fork on github and send pull requests, send patches
from git format-patch to the bug tracker, or host your own copy of gitalist somewhere and
ask us to pull from it.
=head1 SUPPORT
Gitalist has an active irc community in C<#gitalist> on irc.perl.org, please feel free to stop
by and ask questions, report bugs or installation issues or generally for a chat about where
we plan to go with the project.
=head1 SEE ALSO
L<Gitalist::Controller::Root>
L<Git::Gitalist::Repository>
L<Catalyst>
=head1 AUTHORS AND COPYRIGHT
Catalyst application:
© 2009 Venda Ltd and Dan Brook <broq@cpan.org>
© 2009, Tom Doran <bobtfish@bobtfish.net>
© 2009, Zac Stevens <zts@cryptocracy.com>
Original gitweb.cgi from which this was derived:
© 2005-2006, Kay Sievers <kay.sievers@vrfy.org>
© 2005, Christian Gierke
Model based on http://github.com/rafl/gitweb
© 2008, Florian Ragwitz
=head1 LICENSE
Licensed under GNU GPL v2
lib/Gitalist/ActionRole/FilenameArgs.pm view on Meta::CPAN
package Gitalist::ActionRole::FilenameArgs;
use Moose::Role;
use namespace::autoclean;
requires 'execute';
before 'execute' => sub {
my ($self, $controller, $c, @args) = @_;
$c->stash->{filename} = join('/', @args) || ''
unless $c->stash->{filename};
};
1;
lib/Gitalist/ContentMangler/Resolver.pm view on Meta::CPAN
package Gitalist::ContentMangler::Resolver;
use Moose::Role;
requires 'resolve';
1;
lib/Gitalist/ContentMangler/Resolver/Default.pm view on Meta::CPAN
use MooseX::Declare;
use Syntax::Highlight::Engine::Kate ();
our @interpreters = (
'awk',
'bash',
'ksh',
'make',
'node',
'perl',
'prolog',
'python',
'ruby',
'sh',
'tcl',
);
our %interpretersx = (
'awk' => 'AWK',
'ksh' => 'Bash',
'make' => 'Makefile',
'node' => 'Javascript',
'sh' => 'Bash',
);
class Gitalist::ContentMangler::Resolver::Default with Gitalist::ContentMangler::Resolver {
method resolve ($data) {
if($data->{action} eq 'diff_fancy') {
return 'Gitalist::ContentMangler::Transformer::SyntaxHighlight' => {language => 'Diff', css => 'Diff'};
}
my $kate = Syntax::Highlight::Engine::Kate->new();
# Detect .t files as perl code
$kate->extensions->{'*.t'} = ['Perl'];
my $language = $kate->languagePropose($data->{filename}) || $kate->languagePropose(lc $data->{filename});
if(!$language && exists($data->{blob})) {
my $interp = substr(${$data->{blob}}, 0, 256);
if($interp =~ /^#!(?:\S*\/)?([^\s\/]+)/) {
my $interp = $1;
for my $interpreter (@interpreters) {
if($interp =~ /$interpreter/) {
$language = $interpretersx{$interpreter} || ucfirst $interpreter;
last;
}
}
}
}
return unless $language;
return 'Gitalist::ContentMangler::Transformer::SyntaxHighlight' => {language => $language, css => 'Code'};
}
}
lib/Gitalist/ContentMangler/Transformer/SyntaxHighlight.pm view on Meta::CPAN
use MooseX::Declare;
class Gitalist::ContentMangler::Transformer::SyntaxHighlight {
method transform($c, $config) {
$c->stash(
syntax_css => $c->uri_for("/static/css/syntax/$config->{css}.css"),
mangled => 1,
);
for (grep $_, $c->stash->{blobs} ? @{$c->stash->{blobs}} : $c->stash->{blob}) {
$_ = $c->view('SyntaxHighlight')->render($c, $_, $config);
}
}
}
view all matches for this distributionview release on metacpan - search on metacpan