Gitalist

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

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

MANIFEST  view on Meta::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

META.yml  view on Meta::CPAN

---
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"
}

MYMETA.yml  view on Meta::CPAN

---
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;

README  view on Meta::CPAN

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 distribution
 view release on metacpan -  search on metacpan

( run in 0.921 second using v1.00-cache-2.02-grep-82fe00e-cpan-503542c4f10 )