-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Decouple disk based descend order, config and overlays to allow other…
… sources Ticket #38 This is a major change.
- Loading branch information
richard
committed
Mar 30, 2010
1 parent
905afa6
commit f315334
Showing
32 changed files
with
2,578 additions
and
1,285 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
# -*- mode: perl; cperl-continued-brace-offset: -4; indent-tabs-mode: nil; -*- | ||
# vim:shiftwidth=2:tabstop=8:expandtab:textwidth=78:softtabstop=4:ai: | ||
|
||
# $Id$ | ||
|
||
# | ||
# This program is free software; you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation; either version 3 of the License. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
# (C) Copyright Ticketmaster, Inc. 2007 | ||
# | ||
|
||
use strict; | ||
|
||
package Spine::Plugin::Data::Disk; | ||
use base qw(Spine::Plugin); | ||
use Spine::Constants qw(:plugin); | ||
use File::Spec::Functions; | ||
use File::Basename; | ||
use Spine::Util qw(simple_exec do_rsync mkdir_p octal_conv uid_conv gid_conv); | ||
|
||
our ( $VERSION, $DESCRIPTION, $MODULE, $DONTDELETE, $TMPDIR, @ENTRIES ); | ||
|
||
$VERSION = sprintf( "%d", q$Revision$ =~ /(\d+)/ ); | ||
$DESCRIPTION = "Disk based data."; | ||
|
||
$MODULE = { author => 'osscode@ticketmaster.com', | ||
description => $DESCRIPTION, | ||
version => $VERSION, | ||
hooks => { | ||
"PARSE/branch" => [ { name => "load_disk_config", | ||
code => \&parse_branch } ], } }; | ||
|
||
use Spine::Constants qw(:basic :plugin); | ||
|
||
sub parse_branch { | ||
my $c = shift; | ||
my $branch = shift; | ||
|
||
my $fatal = | ||
exists $branch->{fatal_if_missing} | ||
? exists $branch->{fatal_if_missing} | ||
: 0; | ||
|
||
return PLUGIN_SUCCESS unless substr( $branch->{uri}, 0, 5 ) eq "file:"; | ||
|
||
my ( undef, $descend_item ) = ( $branch->{uri} =~ m%file://([^/]*)/(.*)% ); | ||
|
||
($branch) = ( $branch->{uri} =~ m%file://[^/]*/(.*)% ); | ||
|
||
unless ( -d $branch ) { | ||
# is it ok if it's missing? | ||
if ($fatal) { | ||
$c->error( "required branch is missing \"$branch\"", 'crit' ); | ||
return PLUGIN_FATAL; | ||
} | ||
return PLUGIN_SUCCESS; | ||
} | ||
|
||
if ( not _get_values( $c, $branch, $fatal ) ) { | ||
return PLUGIN_ERROR; | ||
} | ||
|
||
#### XXX removed as this is pointless now that the c_hierachy key tracks this | ||
# # Store the paths we actually managed to descend | ||
# # in the exact order that we did so. | ||
# push( @{ $c->{c_descend_order} }, $branch ); | ||
|
||
return PLUGIN_SUCCESS; | ||
} | ||
|
||
sub _get_values { | ||
my $c = shift; | ||
my $directory = shift; | ||
my $fatal = shift; | ||
my $keys_dir = $c->getval_last('config_keys_dir') || 'config'; | ||
|
||
unless ( defined $directory ) { | ||
$c->error( "_get_values(): no path passed to method", 'crit' ); | ||
return SPINE_FAILURE; | ||
} | ||
|
||
$directory = catdir( $directory, $keys_dir ); | ||
|
||
unless ( -d $directory ) { | ||
if ($fatal) { | ||
$c->error( "required config location is missing \"$directory\"", | ||
'crit' ); | ||
return SPINE_FAILURE; | ||
} | ||
return SPINE_SUCCESS; | ||
} | ||
|
||
# Iterate through each file in a hierarchial endpoint and | ||
# read the contents to extract values. | ||
my $dir = new IO::Dir($directory); | ||
|
||
unless ( defined($dir) ) { | ||
$c->error( "_get_values(): failed to open $directory: $!", 'crit' ); | ||
return SPINE_FAILURE; | ||
} | ||
|
||
my @files = $dir->read(); | ||
$dir->close(); | ||
|
||
foreach my $keyfile ( sort(@files) ) { | ||
|
||
# Key names beginning with c_ are reserved for values | ||
# that are automatically populated by the this module. | ||
my $keyname = basename($keyfile); | ||
if ( $keyname eq '.' or $keyname eq '..' ) { | ||
next; | ||
} | ||
|
||
if ( $keyname =~ m/(?:(?:^(?:\.|c_\#).*)|(?:.*(?:~|\#)$))/ ) { | ||
$c->error( | ||
"ignoring $directory/$keyname because of lame" . ' file name', | ||
'err' ); | ||
next; | ||
} | ||
|
||
$keyfile = "file:///" . catfile( $directory, $keyfile ); | ||
|
||
# Read the contents of a file. Filename is stored | ||
# as the key, where value(s) are the contents. | ||
my $value = $c->read_keyuri( uri => $keyfile, | ||
keyname => $keyname, | ||
description => "$keyfile key" ); | ||
|
||
if ( not defined($value) ) { | ||
$c->error( "read_keyuri: \"$keyfile\" parse error", 'crit' ); | ||
|
||
return SPINE_FAILURE; | ||
} | ||
} | ||
|
||
return SPINE_SUCCESS; | ||
} | ||
|
||
1; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# -*- Mode: perl; cperl-continued-brace-offset: -4; indent-tabs-mode: nil; -*- | ||
# vim:shiftwidth=2:tabstop=8:expandtab:textwidth=78:softtabstop=4:ai: | ||
|
||
# $Id$ | ||
|
||
# | ||
# This program is free software; you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation; either version 3 of the License. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
# (C) Copyright Ticketmaster, Inc. 2007 | ||
# | ||
|
||
use strict; | ||
|
||
package Spine::Plugin::Descend::Disk; | ||
use base qw(Spine::Plugin); | ||
use Spine::Constants qw(:plugin :keys); | ||
use Spine::Data; | ||
use Spine::Key::Blank; | ||
use Spine::Plugin::DescendOrder; | ||
use Spine::Plugin::Interpolate; | ||
|
||
our ( $VERSION, $DESCRIPTION, $MODULE, $CURRENT_DEPTH, $MAX_NESTING_DEPTH ); | ||
|
||
$VERSION = sprintf( "%d", q$Revision$ =~ /(\d+)/ ); | ||
$DESCRIPTION = "process disk based includes/branches"; | ||
|
||
$MODULE = { author => 'osscode@ticketmaster.com', | ||
description => $DESCRIPTION, | ||
version => $VERSION, | ||
hooks => { | ||
'DISCOVERY/Descend/resolve' => [ | ||
{ name => 'resolve_disk_descend', | ||
code => \&resolve, | ||
provides => ["disk_descend"] } | ||
], | ||
"DISCOVERY/populate" => [ | ||
{ name => 'reserve_include_key', | ||
code => \&reserve_key, }, ], } | ||
}; | ||
use File::Spec::Functions; | ||
|
||
sub resolve { | ||
my ( $c, $key, $item ) = @_; | ||
|
||
# deal with legacy dirs that do not have proper uris | ||
# TODO: depreciate this once everyone uses uri's, should probably move to | ||
# a separate fixup plugin! | ||
unless ( $item->{uri} =~ m%[^:]+://% ) { | ||
# if the item has succedes we assume that it's | ||
# a config_group since it has a parent branch | ||
if ( exists $item->{dependencies}->{succedes} ) { | ||
$item->{uri} = "file:///" | ||
. catdir( $c->getval_last('include_dir'), $item->{uri} ); | ||
} else { | ||
$item->{uri} = "file:///$item->{uri}"; | ||
} | ||
} | ||
|
||
# we only deal with file URIs | ||
return PLUGIN_SUCCESS unless substr( $item->{uri}, 0, 5 ) eq "file:"; | ||
|
||
my ( undef, $descend_item ) = ( $item->{uri} =~ m%file://([^/]*)/(.*)% ); | ||
my $croot = $c->getval('c_croot'); | ||
|
||
unless ( $descend_item =~ m#^/# ) { | ||
$descend_item = catfile( $croot, $descend_item ); | ||
} | ||
|
||
# TODO: this isn't very nice. Taken from the old code. Should be based on a | ||
# key. Also the first include is better then the second. | ||
foreach my $path (qw(include config/include)) { | ||
my $inc_file = catfile( $descend_item, $path ); | ||
|
||
# An empty set is perfectly acceptable | ||
unless ( -f $inc_file ) { | ||
next; | ||
} | ||
|
||
# add in the item to $key, noteing that it succedes it's parent | ||
# by passing a merge parameter | ||
# XXX: might be worth moving this to a function within the DescendOrder | ||
# plugin to hide the implementation... | ||
$c->read_key( { uri => "file:///$inc_file", | ||
description => "file:///$inc_file descend key", | ||
operators => [ [ 'merge', $item->{name} ] ], }, | ||
$c->getkey(SPINE_HIERARCHY_KEY) ); | ||
} | ||
} | ||
|
||
# Since the include keys get processed from the same location as config keys | ||
# the resulting data seen by the user in printdata makes little sense. Actauly | ||
# the data within include is pointless. So lets make sure it stays blank no | ||
# matter what! | ||
sub reserve_key { | ||
my $c = shift; | ||
$c->set( "include", new Spine::Key::Blank ); | ||
return PLUGIN_SUCCESS; | ||
} | ||
|
||
1; |
Oops, something went wrong.