source: OFFICIAL/FCM_V1.3/lib/Fcm/SrcDirLayer.pm

Last change on this file was 1, checked in by fcm, 15 years ago

creation de larborescence

File size: 7.0 KB
Line 
1#!/usr/bin/perl
2# ------------------------------------------------------------------------------
3# NAME
4#   Fcm::SrcDirLayer
5#
6# DESCRIPTION
7#   This class contains methods to manipulate the extract of a source
8#   directory from a branch of a (Subversion) repository.
9#
10# COPYRIGHT
11#   (C) Crown copyright Met Office. All rights reserved.
12#   For further details please refer to the file COPYRIGHT.txt
13#   which you should have received as part of this distribution.
14# ------------------------------------------------------------------------------
15
16package Fcm::SrcDirLayer;
17@ISA = qw(Fcm::Base);
18
19# Standard pragma
20use warnings;
21use strict;
22
23# Standard modules
24use File::Basename;
25use File::Path;
26use File::Spec::Functions;
27
28# FCM component modules
29use Fcm::Base;
30use Fcm::Timer;
31use Fcm::Util;
32
33# List of property methods for this class
34my @scalar_properties = (
35  'cachedir',  # cache directory for this directory branch
36  'commit',    # revision at which the source directory was changed
37  'extracted', # is this branch already extracted?
38  'files',     # list of source files in this directory branch
39  'location',  # location of the source directory in the branch
40  'name',      # sub-package name of the source directory
41  'package',   # top level package name of which the current repository belongs
42  'reposroot', # repository root URL
43  'revision',  # revision of the repository branch
44  'tag',       # package/revision tag of the current repository branch
45  'type',      # type of the repository branch ("svn" or "user")
46);
47
48# ------------------------------------------------------------------------------
49# SYNOPSIS
50#   $obj = Fcm::SrcDirLayer->new (%args);
51#
52# DESCRIPTION
53#   This method constructs a new instance of the Fcm::SrcDirLayer class. See
54#   above for allowed list of properties. (KEYS should be in uppercase.)
55# ------------------------------------------------------------------------------
56
57sub new {
58  my $this  = shift;
59  my %args  = @_;
60  my $class = ref $this || $this;
61
62  my $self = Fcm::Base->new (%args);
63
64  for (@scalar_properties) {
65    $self->{$_} = exists $args{uc ($_)} ? $args{uc ($_)} : undef;
66  }
67
68  bless $self, $class;
69  return $self;
70}
71
72# ------------------------------------------------------------------------------
73# SYNOPSIS
74#   $value = $obj->X;
75#   $obj->X ($value);
76#
77# DESCRIPTION
78#   Details of these properties are explained in @scalar_properties.
79# ------------------------------------------------------------------------------
80
81for my $name (@scalar_properties) {
82  no strict 'refs';
83
84  *$name = sub {
85    my $self = shift;
86
87    # Argument specified, set property to specified argument
88    if (@_) {
89      $self->{$name} = $_[0];
90    }
91
92    # Default value for property
93    if (not defined $self->{$name}) {
94      if ($name eq 'files') {
95        # Reference to an array
96        $self->{$name} = [];
97      }
98    }
99
100    return $self->{$name};
101  }
102}
103
104# ------------------------------------------------------------------------------
105# SYNOPSIS
106#   $dir = $obj->localdir;
107#
108# DESCRIPTION
109#   This method returns the user or cache directory for the current revision
110#   of the repository branch.
111# ------------------------------------------------------------------------------
112
113sub localdir {
114  my $self = shift;
115
116  return $self->user ? $self->location : $self->cachedir;
117}
118
119# ------------------------------------------------------------------------------
120# SYNOPSIS
121#   $user = $obj->user;
122#
123# DESCRIPTION
124#   This method returns the string "user" if the current source directory
125#   branch is a local directory. Otherwise, it returns "undef".
126# ------------------------------------------------------------------------------
127
128sub user {
129  my $self = shift;
130
131  return $self->type eq 'user' ? 'user' : undef;
132}
133
134# ------------------------------------------------------------------------------
135# SYNOPSIS
136#   $rev = $obj->get_commit;
137#
138# DESCRIPTION
139#   If the current repository type is "svn", this method attempts to obtain
140#   the revision in which the branch is last committed. On a successful
141#   operation, it returns this revision number. Otherwise, it returns
142#   "undef".
143# ------------------------------------------------------------------------------
144
145sub get_commit {
146  my $self = shift;
147
148  if ($self->type eq 'svn') {
149    # Execute the "svn info" command
150    my @lines   = &run_command (
151      [qw/svn info -r/, $self->revision, $self->location . '@' . $self->revision],
152      METHOD => 'qx', TIME => $self->config->verbose > 2,
153    );
154
155    my $rev;
156    for (@lines) {
157      if (/^Last\s+Changed\s+Rev\s*:\s*(\d+)/i) {
158        $rev = $1;
159        last;
160      }
161    }
162
163    # Commit revision of this source directory
164    $self->commit ($rev);
165
166    return $self->commit;
167
168  } elsif ($self->type eq 'user') {
169    return;
170
171  } else {
172    e_report 'Repository type "', $self->type, '" not supported.';
173  }
174}
175
176# ------------------------------------------------------------------------------
177# SYNOPSIS
178#   $rc = $obj->update_cache;
179#
180# DESCRIPTION
181#   If the current repository type is "svn", this method attempts to extract
182#   the current revision source directory from the current branch from the
183#   repository, sending the output to the cache directory. It returns true on
184#   a successful operation, or false if the repository is not of type "svn".
185# ------------------------------------------------------------------------------
186
187sub update_cache {
188  my $self = shift;
189
190  return unless $self->cachedir;
191
192  # Create cache extract destination, if necessary
193  my $dirname = dirname $self->cachedir;
194  mkpath $dirname if not -d $dirname;
195
196  e_report $dirname, ': cannot write to cache, abort.'
197    unless -d $dirname and -w $dirname;
198 
199  if ($self->type eq 'svn') {
200    # Set up the extract command, "svn export --force -q -N"
201    my @command = (
202      qw/svn export --force -q -N/,
203      $self->location . '@' . $self->revision,
204      $self->cachedir,
205    );
206
207    &run_command (\@command, TIME => $self->config->verbose > 2);
208
209  } elsif ($self->type eq 'user') {
210    return;
211
212  } else {
213    e_report 'Repository type "', $self->type, '" not supported.';
214  }
215
216  return 1;
217}
218
219# ------------------------------------------------------------------------------
220# SYNOPSIS
221#   @files = $obj->get_files;
222#
223# DESCRIPTION
224#   This method returns a list of files in the cache or local user directory
225#   of the current revision of the source directory in the current branch.
226# ------------------------------------------------------------------------------
227
228sub get_files {
229  my $self = shift;
230
231  # Get a list of files in the cache (or local user) directory
232  my @files = ();
233
234  opendir (DIR, $self->localdir)
235    or die $self->localdir, ': cannot read directory';
236
237  while (my $file = readdir DIR) {
238    next if $file =~ /^\.\.?/;                   # ignore . and .. and hidden
239    next if $file =~ /~$/;                       # ignore emacs swap files
240    next if -d catfile ($self->localdir, $file); # ignore sub-directories
241    push @files, $file;
242  }
243  closedir DIR;
244
245  # Return the (base name) of the list of files
246  $self->files (\@files);
247  return @files;
248}
249
250# ------------------------------------------------------------------------------
251
2521;
253
254__END__
Note: See TracBrowser for help on using the repository browser.