/[drupal]/contributions/modules/cvs_deploy/cvs_deploy.module
ViewVC logotype

Contents of /contributions/modules/cvs_deploy/cvs_deploy.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.27 - (show annotations) (download) (as text)
Sat Sep 26 07:00:19 2009 UTC (2 months ago) by dww
Branch: MAIN
CVS Tags: HEAD
Changes since 1.26: +6 -2 lines
File MIME type: text/x-php
#375931 by dww: Fixed some potential PHP notices that might have been
causing trouble for running simpletest with cvs_deploy (although Dave
Reid has found the root of the trouble in core itself, this won't hurt).
1 <?php
2 // $Id: cvs_deploy.module,v 1.26 2009/09/26 06:57:34 dww Exp $
3
4 /**
5 * @file
6 *
7 * This module improves the administrative UI for sites that are deployed
8 * directly via a CVS workspace (as opposed to sites built from packaged
9 * releases that are downloaded from drupal.org).
10 *
11 * See the README.txt file for more information.
12 *
13 * @author Derek Wright ("dww") http://drupal.org/user/46549
14 */
15
16 /**
17 * Returns the human-readable version string from a given CVS tag.
18 */
19 function cvs_deploy_version_from_tag($tag) {
20 // If there's nothing, it must be a HEAD checkout, and therefore,
21 // we have no idea what the version is.
22 $version = '';
23 $match = array();
24 if (empty($tag) || $tag == 'HEAD') {
25 $version = 'HEAD';
26 }
27 // See if it's a full, official release from a tag:
28 elseif (preg_match('@^DRUPAL-(\d+)--(\d+)-(\d+)(-.+)?@', $tag, $match)) {
29 $version = $match[1] .'.x-'. $match[2] .'.'. $match[3];
30 if (isset($match[4])) {
31 // This version's tag has 'extra', so clean that up.
32 $version .= '-'. preg_replace('/[_-]/', '', strtolower($match[4]));
33 }
34 }
35 // If not, see if it's from a branch (like a development snapshot).
36 elseif (preg_match('@^DRUPAL-(\d+)(--(\d+))?@', $tag, $match)) {
37 $version = $match[1] .'.x-'. (isset($match[3]) ? $match[3] : '1') .'.x-dev';
38 }
39 return $version;
40 }
41
42 /**
43 * Implementation of hook_system_info_alter().
44 */
45 function cvs_deploy_system_info_alter(&$info, $file) {
46 // First, if we don't know the 'project' attribute, fill it in based on the
47 // CVS/Repository file.
48 if (empty($info['project'])) {
49 $info['project'] = cvs_deploy_get_project_name($file);
50 }
51
52 // Now, alter the version string based on the CVS sticky tag.
53 if (empty($info['version'])) {
54 $info['version'] = '';
55 }
56 _cvs_deploy_version_alter($info['version'], $file);
57
58 // Find the timestamp for the most recently modified CVS/Entries file.
59 $mtime = _cvs_deploy_find_latest_update(dirname($file->uri), 0);
60
61 // Only fill this in if the .info file does not define a 'datestamp'.
62 if (empty($info['datestamp'])) {
63 $info['datestamp'] = $mtime;
64 }
65
66 // However, the '_info_file_ctime' should always get the latest value.
67 if (empty($info['_info_file_ctime'])) {
68 $info['_info_file_ctime'] = $mtime;
69 }
70 else {
71 $info['_info_file_ctime'] = max($info['_info_file_ctime'], $mtime);
72 }
73 }
74
75 /**
76 * Private helper to alter the version of a module based on what we can figure
77 * out about the CVS tag in use.
78 */
79 function _cvs_deploy_version_alter(&$version, $file) {
80 static $available = array();
81 $match = array();
82 if (empty($version)) {
83 // The .info file contains no version data. Find the version based
84 // on the sticky tag in the local workspace (the CVS/Tag file).
85 $cvs_dir = dirname($file->uri) .'/CVS';
86 if (is_dir($cvs_dir)) {
87 $tag = ''; // If there's no Tag file, there's no tag, a.k.a. HEAD.
88 if (file_exists($cvs_dir .'/Tag')) {
89 $tag_file = trim(file_get_contents($cvs_dir .'/Tag'));
90 if ($tag_file) {
91 // Get the sticky tag for this workspace: strip off the leading 'T'.
92 $tag = preg_replace('@^(T|N)@', '', $tag_file);
93 }
94 }
95 $version = cvs_deploy_version_from_tag($tag);
96 }
97 }
98 // The weird concatenation prevents CVS from 'expanding' this $Name.
99 elseif (preg_match('/\$'.'Name: (.*?)\$/', $version, $match)) {
100 $version = cvs_deploy_version_from_tag(trim($match[1]));
101 }
102
103 if (module_exists('update') && $version == 'HEAD') {
104 module_load_include('inc', 'update', 'update.compare');
105 // If there's available update_status data, we can use the version string
106 // the release node pointing to HEAD really has. However, we can only
107 // safely grab this data directly from the cache, since if we call
108 // update_get_available() here, we'd enter infinite recursion when that
109 // function invokes update_status_get_projects(), which in turn needs to
110 // process the .info files, which invokes the hook that leads here.
111 if (empty($available)) {
112 $cache = _update_cache_get('update_available_releases');
113 if (!empty($cache)) {
114 $available = $cache->data;
115 }
116 }
117 $project = update_get_project_name($file);
118 if (isset($available[$project]['releases'])) {
119 foreach ($available[$project]['releases'] as $release) {
120 if (isset($release['tag']) && $release['tag'] == 'HEAD') {
121 $version = $release['version'];
122 break;
123 }
124 }
125 }
126 }
127 }
128
129 /**
130 * Private helper to alter the 'project' of a module based on what directory
131 * in the CVS repository the module has been checked out from.
132 */
133 function cvs_deploy_get_project_name($file) {
134 static $projects = array();
135 $name = $file->name;
136 if (empty($projects[$name])) {
137 // TODO: cache this in {cache}, too?
138 $cvs_dir = dirname($file->uri) .'/CVS';
139 if (is_dir($cvs_dir)) {
140 $repository = '';
141 if (file_exists($cvs_dir .'/Repository')) {
142 $repo_file = trim(file_get_contents($cvs_dir .'/Repository'));
143 if ($repo_file) {
144 $parts = explode('/', $repo_file);
145 if ($parts[0] == 'drupal') {
146 $projects[$name] = $parts[0];
147 }
148 else {
149 $projects[$name] = $parts[2];
150 }
151 }
152 }
153 }
154 }
155 return (isset($projects[$name]) ? $projects[$name] : '');
156 }
157
158 /**
159 * Recursive helper function to find the latest modification time on every
160 * CVS/Entires file in the current directory tree.
161 *
162 * @param $dir
163 * The directory to search.
164 * @param $timestamp
165 * The current latest modification timestamp on any CVS/Entries file.
166 * @return
167 * The latest mtime based on what we learned in the current directory.
168 */
169 function _cvs_deploy_find_latest_update($dir, $timestamp) {
170 if (is_dir($dir)) {
171 $fp = opendir($dir);
172 while (FALSE !== ($file = readdir($fp))) {
173 if ($file == '.' || $file == '..') {
174 continue;
175 }
176 if ($file == 'CVS' && is_dir("$dir/CVS")) {
177 $entries_file = $dir .'/CVS/Entries';
178 if (file_exists($entries_file)) {
179 $mtime = filemtime($entries_file);
180 $timestamp = ($mtime > $timestamp) ? $mtime : $timestamp;
181 }
182 }
183 elseif (is_dir("$dir/$file")) {
184 $timestamp = _cvs_deploy_find_latest_update("$dir/$file", $timestamp);
185 }
186 }
187 closedir($fp);
188 }
189 return $timestamp;
190 }

  ViewVC Help
Powered by ViewVC 1.1.2