Hostfile-Manager-0.09/0000755000175000017500000000000013374151313015534 5ustar amirabellaamirabellaHostfile-Manager-0.09/Makefile.PL0000644000175000017500000000213113374145703017511 0ustar amirabellaamirabellause strict; use warnings; use ExtUtils::MakeMaker; BEGIN { require 5.006; } my %conf = ( NAME => 'Hostfile::Manager', VERSION_FROM => 'lib/Hostfile/Manager.pm', EXE_FILES => ['bin/hostfiles'], PREREQ_PM => { 'File::Basename' => 0, 'File::Find' => 0, 'File::Slurp' => 0, 'Getopt::Long' => 0, 'Moose' => 0, 'Pod::Usage' => 0, 'Term::Clui' => 0, }, BUILD_REQUIRES => { 'Test::Class' => 0, 'Test::Deep' => 0, 'Test::Most' => 0, 'Test::NoWarnings' => 0, }, AUTHOR => 'Anthony J. Mirabella', ABSTRACT => 'Manage a hostfile by composing multiple fragments into a whole.', LICENSE => 'perl', META_MERGE => { resources => { repository => 'git://github.com/Aneurysm9/hostfile_manager.git', homepage => 'https://github.com/Aneurysm9/hostfile_manager', }, }, ); my $eumm_version = do { no warnings 'numeric'; eval $ExtUtils::MakeMaker::VERSION; }; delete $conf{META_MERGE} if $eumm_version < 6.46; $conf{PREREQ_PM} = { %{ $conf{PREREQ_PM} || {} }, %{ delete $conf{BUILD_REQUIRES} }, } if ($conf{BUILD_REQUIRES} and $eumm_version < 6.5503); WriteMakefile(%conf); Hostfile-Manager-0.09/bin/0000755000175000017500000000000013374151312016303 5ustar amirabellaamirabellaHostfile-Manager-0.09/bin/hostfiles0000755000175000017500000000615113374145703020243 0ustar amirabellaamirabella#! /usr/bin/env perl use strict; use warnings; use Getopt::Long; use Pod::Usage; use Hostfile::Manager; use Term::Clui; my @enabled = (); my @disabled = (); my $interactive = 0; my $status = 0; my $help = 0; my $man = 0; GetOptions( "enable=s" => \@enabled, "disable=s" => \@disabled, "interactive" => \$interactive, "status" => \$status, "help|?" => \$help, man => \$man, ) or pod2usage(2); pod2usage(1) if $help; pod2usage( -exitstatus => 0, -verbose => 2 ) if $man; @enabled = split( /,/, join( ',', @enabled ) ); @disabled = split( /,/, join( ',', @disabled ) ); pod2usage(1) unless ( @enabled || @disabled || $status || $interactive ); my $manager = Hostfile::Manager->new; if ($interactive) { my $modified = 0; while ( my $chosen = choose( "Select a hostfile fragment:", map { get_fragment_status_line($_) } $manager->fragment_list ) ) { $chosen =~ s/^..//; $manager->toggle_fragment($chosen); $modified = 1; } $manager->write_hostfile if $modified; } else { map { print "Disabling $_\n"; $manager->disable_fragment($_) } @disabled; map { print "Enabling $_\n"; $manager->enable_fragment($_) } @enabled; $manager->write_hostfile if ( @disabled || @enabled ); map { print get_fragment_status_line($_) . "\n" } $manager->fragment_list if $status; } sub get_fragment_status_line { my $fragment_name = shift; my $flag = $manager->fragment_status_flag($fragment_name); return "$flag $fragment_name"; } __END__ =head1 NAME hostfiles - A simple script to manage multiple sets of hostfiles on *NIX systems =head1 SYNOPSIS hostfiles [options] Options: --enable Enable one or more hostfile fragments --disable Disable one or more hostfile fragments --status Display the status of various hostfile fragments --interactive Present an interactive list of hostfile fragments =head1 OPTIONS =over 8 =item B<--enable> Enable one or more hostfile fragments. This option may be specified multiple times and multiple fragments may be specified in a comma-separated list. =item B<--disable> Disable one or more hostfile fragments. This option may be specified multiple times and multiple fragments may be specified in a comma-separated list. =item B<--status> Display a list of fragments and their status. A '+' indicates the fragment is enabled. A '*' indicates an enabled fragment has been changed in /etc/hosts. =item B<--interactive> Presents an interactive list of hostfile fragment to enable or disable. =back =head1 DESCRIPTION B will read the hostfile fragments specified to be enabled from /etc/hostfiles/ and add them to /etc/hosts. It will remove any fragments from /etc/hosts that are specified to be disabled. =head1 LICENSE Copyright (c) 2010-11 Anthony J. Mirabella. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Anthony J. Mirabella Hostfile-Manager-0.09/META.yml0000664000175000017500000000155413374151313017014 0ustar amirabellaamirabella--- abstract: 'Manage a hostfile by composing multiple fragments into a whole.' author: - 'Anthony J. Mirabella' build_requires: Test::Class: '0' Test::Deep: '0' Test::Most: '0' Test::NoWarnings: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Hostfile-Manager no_index: directory: - t - inc requires: File::Basename: '0' File::Find: '0' File::Slurp: '0' Getopt::Long: '0' Moose: '0' Pod::Usage: '0' Term::Clui: '0' resources: homepage: https://github.com/Aneurysm9/hostfile_manager repository: git://github.com/Aneurysm9/hostfile_manager.git version: '0.09' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Hostfile-Manager-0.09/META.json0000664000175000017500000000267513374151313017171 0ustar amirabellaamirabella{ "abstract" : "Manage a hostfile by composing multiple fragments into a whole.", "author" : [ "Anthony J. Mirabella" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Hostfile-Manager", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "Test::Class" : "0", "Test::Deep" : "0", "Test::Most" : "0", "Test::NoWarnings" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "File::Basename" : "0", "File::Find" : "0", "File::Slurp" : "0", "Getopt::Long" : "0", "Moose" : "0", "Pod::Usage" : "0", "Term::Clui" : "0" } } }, "release_status" : "stable", "resources" : { "homepage" : "https://github.com/Aneurysm9/hostfile_manager", "repository" : { "type" : "git", "url" : "git://github.com/Aneurysm9/hostfile_manager.git" } }, "version" : "0.09", "x_serialization_backend" : "JSON::PP version 2.27400_02" } Hostfile-Manager-0.09/lib/0000755000175000017500000000000013374151312016301 5ustar amirabellaamirabellaHostfile-Manager-0.09/lib/Hostfile/0000755000175000017500000000000013374151312020056 5ustar amirabellaamirabellaHostfile-Manager-0.09/lib/Hostfile/Manager.pm0000644000175000017500000001357713374150201021777 0ustar amirabellaamirabellapackage Hostfile::Manager; use strict; use warnings; use Moose; use File::Find; use File::Slurp; use File::Basename qw/dirname/; our $VERSION = '0.09'; =head1 NAME Hostfile::Manager - Manage a hostfile by composing multiple fragments into a whole. =head1 SYNOPSIS use Hostfile::Manager; $manager = Hostfile::Manager->new; $manager->enable_fragment($fragment_name); $manager->write_hostfile; =head1 ACCESSORS =over 6 =item B<< Str path_prefix( [Str $prefix] ) >> Defines the prefix that will be searched for hostfile fragments. Defaults to '/etc/hostfiles/'. =cut has path_prefix => ( is => 'rw', isa => 'Str', default => '/etc/hostfiles/', ); =item B<< Str hostfile_path( [Str $path] ) >> Defines the path to the hostfile to manage. Defaults to '/etc/hosts'. =cut has hostfile_path => ( is => 'rw', isa => 'Str', default => '/etc/hosts', ); =item B<< Str hostfile >> The contents of the hostfile under management. =cut has hostfile => ( is => 'ro', isa => 'Str', writer => '_set_hostfile', lazy => 1, builder => 'load_hostfile', init_arg => undef, ); has blocks => ( is => 'ro', isa => 'HashRef', default => sub { {} }, init_arg => undef, ); =item B<< HashRef fragments >> The available hostfile fragments. =item B<< Array fragment_list >> A list of the names of available fragments. =cut sub fragment_list { my ($self) = @_; return sort { $a cmp $b } keys %{$self->fragments}; } =item B<< Str get_fragment( Str $fragment_name ) >> The contents of an individual hostfile fragment. =back =cut has fragments => ( is => 'ro', isa => 'HashRef[Str]', traits => ['Hash'], lazy => 1, builder => '_load_fragments', handles => { get_fragment => 'get', }, init_arg => undef, ); =head1 METHODS =over 6 =item B<< Hostfile::Manager->new( [\%options] ) >> Create a new manager instance. Available options are B and B, listed in the L section. =cut sub load_hostfile { my ( $self, $filename ) = @_; $filename = $self->hostfile_path unless defined $filename; unless ( -e $filename ) { Carp::croak("Hostfile must exist. File not found at $filename"); } my $file = read_file($filename); $self->_set_hostfile($file); } =item B<< Bool write_hostfile >> Write the contents of the hostfile to disk. =cut sub write_hostfile { my $self = shift; my $filename = $self->hostfile_path; unless ( ( !-e $filename && -w dirname($filename) ) || -w $filename ) { Carp::croak("Unable to write hostfile to $filename"); } write_file( $filename, $self->hostfile ); } =item B<< Bool fragment_enabled( Str $fragment_name ) >> Test whether a named fragment is enabled in the hostfile under management. =cut sub fragment_enabled { my ( $self, $fragment_name ) = @_; $self->hostfile =~ $self->block($fragment_name); } =item B<< enable_fragment( Str $fragment_name ) >> Enable a named fragment. If the fragment is currently enabled, it will be disabled first, removing any modifications that may have been made out-of-band. =cut sub enable_fragment { my ( $self, $fragment_name ) = @_; my $fragment = $self->get_fragment($fragment_name) or return; $self->disable_fragment($fragment_name) if $self->fragment_enabled($fragment_name); $self->_set_hostfile( $self->hostfile . "# BEGIN: $fragment_name\n$fragment# END: $fragment_name\n" ); } =item B<< disable_fragment( Str $fragment_name ) >> Disable a named fragment. =cut sub disable_fragment { my ( $self, $fragment_name ) = @_; my $hostfile = $self->hostfile; $hostfile =~ s/@{[$self->block($fragment_name)]}//g; $self->_set_hostfile($hostfile); } =item B<< toggle_fragment( Str $fragment_name ) >> Enable a fragment if it is disabled, disable it otherwise. =cut sub toggle_fragment { my ( $self, $fragment_name ) = @_; if ( $self->fragment_enabled($fragment_name) ) { $self->disable_fragment($fragment_name); } else { $self->enable_fragment($fragment_name); } } sub block { my ( $self, $block_name ) = @_; $self->blocks->{$block_name} ||= qr/#+\s*BEGIN: $block_name[\r\n](.*)#+\s*END: $block_name[\r\n]/ms; return $self->blocks->{$block_name}; } sub _load_fragments { my $self = shift; my $fragments = {}; my $prefix = $self->path_prefix; find( { wanted => sub { return if -d $_; $_ =~ s{^$prefix}{}; $fragments->{$_} = $self->_load_fragment($_); }, no_chdir => 1 }, $prefix ); $fragments; } sub _load_fragment { my ( $self, $fragment_name ) = @_; my $filename = $self->path_prefix . $fragment_name; unless ( -e $filename ) { Carp::carp("Fragment not found at $filename"); return; } read_file($filename); } =item B<< Str fragment_status_flag( Str $fragment_name ) >> Returns a string indicating the current status of a named fragment. =over 2 =item B<"+"> The named fragment is enabled. =item B<"*"> The named fragment is enabled and has been modified in the sourced hostfile. =item B<" "> The named fragment is not enabled. =back =back =cut sub fragment_status_flag { my ( $self, $fragment_name ) = @_; my $fragment_contents = $self->get_fragment($fragment_name); my ($found) = $self->hostfile =~ /@{[$self->block($fragment_name)]}/g; return $found ? ( $found eq $fragment_contents ? "+" : "*" ) : " "; } no Moose; __PACKAGE__->meta->make_immutable; __END__ =head1 LICENSE Copyright (c) 2010-11,2018 Anthony J. Mirabella. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Anthony J. Mirabella Hostfile-Manager-0.09/t/0000755000175000017500000000000013374151312015776 5ustar amirabellaamirabellaHostfile-Manager-0.09/t/run.t0000644000175000017500000000025013374145703016773 0ustar amirabellaamirabella#! /usr/bin/perl -T use strict; use warnings; use lib 't/tests'; use Test::Class::Load qw; INIT { Test::Class->runtests( Test::Class->_test_classes, +1 ) } Hostfile-Manager-0.09/t/tests/0000755000175000017500000000000013374151312017140 5ustar amirabellaamirabellaHostfile-Manager-0.09/t/tests/Test/0000755000175000017500000000000013374151312020057 5ustar amirabellaamirabellaHostfile-Manager-0.09/t/tests/Test/Hostfile/0000755000175000017500000000000013374151312021634 5ustar amirabellaamirabellaHostfile-Manager-0.09/t/tests/Test/Hostfile/Manager.pm0000644000175000017500000002546213374147774023576 0ustar amirabellaamirabellapackage Test::Hostfile::Manager; use strict; use warnings; use Test::Most; use Test::NoWarnings qw/had_no_warnings/; use File::Slurp; use base 'Test::Class'; sub class { 'Hostfile::Manager'; } sub startup : Tests(startup => 1) { my $test = shift; use_ok $test->class; } sub constructor : Tests(3) { my $test = shift; my $class = $test->class; can_ok $class, 'new'; ok my $manager = $class->new, '... and the constructor should succeed'; isa_ok $manager, $class, '... and the object it returns'; } sub path_prefix : Tests(3) { my $test = shift; my $manager = $test->class->new; my $default_prefix = '/etc/hostfiles/'; my $new_prefix = '/etc/hostfiles/2/'; can_ok $manager, 'path_prefix'; is $default_prefix, $manager->path_prefix, '... and path_prefix should start out with default value'; $manager->path_prefix($new_prefix); is $manager->path_prefix, $new_prefix, '... and setting its value should succeed'; } sub hostfile_path : Tests(3) { my $test = shift; my $manager = $test->class->new; my $default_hostfile_path = '/etc/hosts'; my $new_hostfile_path = '/etc/hosts2'; can_ok $manager, 'hostfile_path'; is $default_hostfile_path, $manager->hostfile_path, '... and hostfile_path should start out with default value'; $manager->hostfile_path($new_hostfile_path); is $manager->hostfile_path, $new_hostfile_path, '... and setting its value should succeed'; } sub hostfile : Tests(4) { my $test = shift; my $file = 't/fixtures/hosts/1'; my $content = read_file($file); my $manager = $test->class->new( hostfile_path => $file ); can_ok $manager, 'hostfile'; is $content, $manager->hostfile, '... and hostfile should start out with content of file at hostfile_path'; throws_ok { $manager->hostfile('foobar') } qr/^Cannot assign a value/, '... and settings its value should NOT succeed'; is $content, $manager->hostfile, '... and settings its value did not succeed'; } sub hostfile_is_lazy : Tests(2) { my $test = shift; my $file = 't/fixtures/hosts/1'; my $content = read_file($file); my $manager = $test->class->new( hostfile_path => 'non_existent' ); $manager->hostfile_path($file); can_ok $manager, 'hostfile'; is $content, $manager->hostfile, '... and hostfile should start out with content of file at hostfile_path, even when constructed with a different hostfile_path'; } sub hostfile_cannot_be_set_in_constructor : Tests(1) { my $test = shift; my $file = 't/fixtures/hosts/1'; my $content = read_file($file); my $manager = $test->class->new( hostfile_path => $file, hostfile => 'this should be ignored' ); is $content, $manager->hostfile, 'hostfile should start out with content of file at hostfile_path'; } sub load_hostfile : Tests(3) { my $test = shift; my $manager = $test->class->new; my $file = 't/fixtures/hosts/1'; my $content = read_file($file); can_ok $manager, 'load_hostfile'; ok $manager->load_hostfile($file), '... and load_hostfile indicates success'; is $content, $manager->hostfile, '... and load_hostfile actually loaded the file'; } sub load_hostfile_uses_hostfile_path : Tests(3) { my $test = shift; my $manager = $test->class->new; my $file = 't/fixtures/hosts/1'; my $content = read_file($file); $manager->hostfile_path($file); can_ok $manager, 'load_hostfile'; ok $manager->load_hostfile, '... and load_hostfile indicates success'; is $content, $manager->hostfile, '... and load_hostfile actually loaded the file'; } sub load_hostfile_requires_hostfile_existence : Tests(2) { my $test = shift; my $manager = $test->class->new; my $file = 't/fixtures/hosts/non_existent'; can_ok $manager, 'load_hostfile'; throws_ok { $manager->load_hostfile($file) } qr/^Hostfile must exist/, '... and load_hostfile chokes when hostfile missing'; } sub get_fragment : Tests(2) { my $test = shift; my $hostfile = 't/fixtures/hosts/1'; my $prefix = 't/fixtures/fragments/'; my $fragment = 'f1'; my $manager = $test->class->new( path_prefix => $prefix, hostfile_path => $hostfile ); can_ok $manager, 'get_fragment'; is read_file( $prefix . $fragment ), $manager->get_fragment($fragment), '... and get_fragment returns fragment content'; } sub get_fragment_returns_undef_when_fragment_missing : Tests(2) { my $test = shift; my $hostfile = 't/fixtures/hosts/1'; my $prefix = 't/fixtures/fragments/'; my $fragment = 'non_existent'; my $manager = $test->class->new( path_prefix => $prefix, hostfile_path => $hostfile ); can_ok $manager, 'get_fragment'; is undef, $manager->get_fragment($fragment), '... and get_fragment undef when fragment file missing'; } sub block : Tests(2) { my $test = shift; my $manager = $test->class->new; my $fragment_name = 'f1'; my $block_regexp = qr/#+\s*BEGIN: $fragment_name[\r\n](.*)#+\s*END: $fragment_name[\r\n]/ms; can_ok $manager, 'block'; is $manager->block($fragment_name), $block_regexp; } sub write_hostfile : Tests(3) { my $test = shift; my $manager = $test->class->new; my $file = 't/fixtures/hosts/1'; my $content = read_file($file); $manager->load_hostfile($file); can_ok $manager, 'write_hostfile'; my $file2 = 't/fixtures/hosts/write_test'; unlink($file2); $manager->hostfile_path($file2); ok $manager->write_hostfile, '... and write_hostfile returns ok'; is $content, read_file($file2), "... and hostfile written to $file2"; unlink($file2); } sub write_hostfile_requires_writable : Tests(3) { my $test = shift; my $manager = $test->class->new; my $file = 't/fixtures/hosts/1'; my $content = read_file($file); $manager->load_hostfile($file); can_ok $manager, 'write_hostfile'; SKIP: { skip 'Cannot test writable requirements as root', 2 if ($< == 0); my $file2 = 't/fixtures/hosts/write_test'; write_file( $file2, '' ); chmod 0444, $file2; $manager->hostfile_path($file2); throws_ok { $manager->write_hostfile } qr/^Unable to write hostfile/, '... and write_hostfile chokes when trying to write to file without permissions'; is '', read_file($file2), "... and hostfile NOT written to $file2"; unlink($file2); } } sub fragment_enabled : Tests(3) { my $test = shift; my $path = 't/fixtures/hosts/2'; my $prefix = 't/fixtures/fragments/'; my $manager = $test->class->new( hostfile_path => $path, path_prefix => $prefix ); can_ok $manager, 'fragment_enabled'; ok $manager->fragment_enabled('f1'), '... and fragment_enabled returns ok when fragment is indeed enabled'; ok !$manager->fragment_enabled('f2'), '... and fragment_enabled returns not_ok when fragment is not enabled'; } sub enable_fragment : Tests(3) { my $test = shift; my $path = 't/fixtures/hosts/1'; my $prefix = 't/fixtures/fragments/'; my $manager = $test->class->new( hostfile_path => $path, path_prefix => $prefix ); can_ok $manager, 'enable_fragment'; ok $manager->enable_fragment('f1'), '... and enable_fragment returns ok when fragment is newly enabled'; ok $manager->fragment_enabled('f1'), '... and fragment is indeed enabled'; } sub enable_fragment_does_not_leave_multiple_entries : Tests(4) { my $test = shift; my $path = 't/fixtures/hosts/2'; my $content = read_file($path); my $prefix = 't/fixtures/fragments/'; my $manager = $test->class->new( hostfile_path => $path, path_prefix => $prefix ); can_ok $manager, 'enable_fragment'; ok $manager->enable_fragment('f1'), '... and enable_fragment returns ok when fragment is newly enabled'; ok $manager->fragment_enabled('f1'), '... and fragment is indeed enabled'; is $manager->hostfile, $content, '... and fragment only appears once'; } sub enable_fragment_does_not_warn_if_fragment_not_loaded : Tests(1) { my $test = shift; my $path = 't/fixtures/hosts/2'; my $prefix = 't/fixtures/fragments/'; my $manager = $test->class->new( hostfile_path => $path, path_prefix => $prefix ); had_no_warnings $manager->enable_fragment('non_existent'), '... and enable_fragment does not complain excessively when enabling missing fragment'; } sub disable_fragment : Tests(4) { my $test = shift; my $path = 't/fixtures/hosts/2'; my $prefix = 't/fixtures/fragments/'; my $manager = $test->class->new( hostfile_path => $path, path_prefix => $prefix ); can_ok $manager, 'disable_fragment'; ok $manager->fragment_enabled('f1'), '... and fragment_enabled returns ok when fragment is indeed enabled'; ok $manager->disable_fragment('f1'), '... and disable_fragment returns ok when fragment is newly disabled'; ok !$manager->fragment_enabled('f1'), '... and fragment is indeed disabled'; } sub fragment_list : Tests(2) { my $test = shift; my $prefix = 't/fixtures/fragments/'; my @fragments = ('f1', 'f1a'); my $manager = $test->class->new( path_prefix => $prefix ); can_ok $manager, 'fragment_list'; my @fl = $manager->fragment_list; is_deeply \@fl, \@fragments, '... and fragment list matches expectation'; } sub toggle_fragment : Tests(6) { my $test = shift; my $path = 't/fixtures/hosts/2'; my $prefix = 't/fixtures/fragments/'; my $manager = $test->class->new( hostfile_path => $path, path_prefix => $prefix ); can_ok $manager, 'toggle_fragment'; ok $manager->fragment_enabled('f1'), '... and fragment_enabled returns ok when fragment is enabled'; ok $manager->toggle_fragment('f1'), '... and toggle_fragment returns ok when fragment is newly toggled'; ok !$manager->fragment_enabled('f1'), '... and fragment is disabled'; ok $manager->toggle_fragment('f1'), '... and toggle_fragment returns ok when fragment is newly toggled'; ok $manager->fragment_enabled('f1'), '... and fragment is enabled'; } sub fragment_status_flag : Tests(4) { my $test = shift; my $path = 't/fixtures/hosts/3'; my $prefix = 't/fixtures/fragments/'; my $manager = $test->class->new( hostfile_path => $path, path_prefix => $prefix ); can_ok $manager, 'fragment_status_flag'; is $manager->fragment_status_flag('f1'), '+', '... and fragment_status_flag returns \'+\' when fragment is enabled and unmodified'; is $manager->fragment_status_flag('f1a'), '*', '... and fragment_status_flag returns \'*\' when fragment is enabled and modified'; is $manager->fragment_status_flag('f2'), ' ', '... and fragment_status_flag returns \' \' when fragment is disabled'; } 1; Hostfile-Manager-0.09/t/fixtures/0000755000175000017500000000000013374151312017647 5ustar amirabellaamirabellaHostfile-Manager-0.09/t/fixtures/fragments/0000755000175000017500000000000013374151312021635 5ustar amirabellaamirabellaHostfile-Manager-0.09/t/fixtures/fragments/f10000644000175000017500000000002313374145703022070 0ustar amirabellaamirabella192.168.0.1 router Hostfile-Manager-0.09/t/fixtures/fragments/f1a0000644000175000017500000000002313374145703022231 0ustar amirabellaamirabella192.168.1.1 router Hostfile-Manager-0.09/t/fixtures/hosts/0000755000175000017500000000000013374151312021007 5ustar amirabellaamirabellaHostfile-Manager-0.09/t/fixtures/hosts/10000644000175000017500000000003013374145703021072 0ustar amirabellaamirabella127.0.0.1 home.sweet.hm Hostfile-Manager-0.09/t/fixtures/hosts/30000644000175000017500000000015513374145703021104 0ustar amirabellaamirabella127.0.0.1 home.sweet.hm # BEGIN: f1 192.168.0.1 router # END: f1 # BEGIN: f1a 192.168.0.1 router # END: f1a Hostfile-Manager-0.09/t/fixtures/hosts/20000644000175000017500000000010213374145703021073 0ustar amirabellaamirabella127.0.0.1 home.sweet.hm # BEGIN: f1 192.168.0.1 router # END: f1 Hostfile-Manager-0.09/MANIFEST.SKIP0000644000175000017500000000002113374145703017431 0ustar amirabellaamirabella^\.git ^.*\.swp$ Hostfile-Manager-0.09/MANIFEST0000644000175000017500000000061313374151313016665 0ustar amirabellaamirabellaMakefile.PL MANIFEST MANIFEST.SKIP README bin/hostfiles lib/Hostfile/Manager.pm t/fixtures/fragments/f1 t/fixtures/fragments/f1a t/fixtures/hosts/1 t/fixtures/hosts/2 t/fixtures/hosts/3 t/run.t t/tests/Test/Hostfile/Manager.pm META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker)