SyncProjectsAndEnvironments   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 31
lcom 1
cbo 6
dl 0
loc 167
rs 9.8
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
C run() 0 42 8
A removeObsoleteEnvironments() 0 19 4
A removeObsoleteProjects() 0 13 4
C syncEnvironmentPaths() 0 26 7
A syncProjectPaths() 0 10 4
A message() 0 6 2
A echoHeader() 0 7 2
1
<?php
2
3
class SyncProjectsAndEnvironments extends BuildTask {
4
	/**
5
	 * @param SS_HTTPRequest|null $request
6
	 */
7
	public function run($request = null) {
8
		// should syncing remove obsolete records?
9
		$remove = true;
10
		$dryRun = true;
11
12
		if($request && $request->requestVar('remove') !== null) {
13
			$remove = (bool)$request->requestVar('remove');
14
		}
15
16
		if($request && $request->requestVar('dryrun') !== null) {
17
			$dryRun = (bool)$request->requestVar('dryrun');
18
		}
19
20
		if($dryRun) {
21
			echo "Running in dry run mode, no changes commited, ";
22
			echo "the output shows a prediction on what will happen." . PHP_EOL;
23
			echo "To skip dryrun, run the task like this:" . PHP_EOL;
24
			echo "./framework/sake dev/tasks/SyncProjectsAndEnvironments dryrun=0" . PHP_EOL . PHP_EOL;
25
			sleep(3);
26
		}
27
28
		$data = DNData::inst();
29
		$projectPaths = $data->getProjectPaths();
30
31
		// Sync projects
32
		$projects = DNProject::get();
33
		if($remove) {
34
			$this->echoHeader('Removing obsolete projects');
35
			$this->removeObsoleteProjects($projectPaths, $dryRun);
36
		}
37
		$this->echoHeader('Adding new projects');
38
		$this->syncProjectPaths($projectPaths, $dryRun);
39
40
		$this->echoHeader('Syncing environment files');
41
		foreach($projects as $project) {
42
			$this->echoHeader($project->Name);
43
			// Sync environments for each project
44
			$environmentPaths = $data->getEnvironmentPaths($project->Name);
45
			$this->removeObsoleteEnvironments($environmentPaths, $project, $dryRun);
46
			$this->syncEnvironmentPaths($environmentPaths, $project, $dryRun);
47
		}
48
	}
49
50
	/**
51
	 * Remove environment files that can't be found on disk
52
	 *
53
	 * @param array $paths Array of pathnames
54
	 * @param DNProject
55
	 * @param bool $dryRun
56
	 */
57
	protected function removeObsoleteEnvironments($paths, $project, $dryRun = false) {
58
		$list = $project->Environments();
59
60
		$basePaths = array_map(function($path) {
61
			return basename($path);
62
		}, $paths);
63
64
		$removeList = $list->filter('Filename:not', $basePaths);
65
		if($removeList->count() === 0) {
66
			return;
67
		}
68
69
		foreach($removeList as $remove) {
70
			$this->message('Removing "' . basename($remove->Name) . '" from db');
71
			if(!$dryRun) {
72
				$removeList->remove($remove);
73
			}
74
		}
75
	}
76
77
	/**
78
	 * Remove projects that don't exists on disk but in the database
79
	 *
80
	 * @todo add a archive functionality
81
	 *
82
	 * @param array $paths
83
	 */
84
	protected function removeObsoleteProjects($paths, $dryrun = false) {
85
		$removeList = DNProject::get()->filter('Name:not', $paths);
86
		if($removeList->count() == 0) {
87
			return;
88
		}
89
90
		foreach($removeList as $remove) {
91
			$this->message($remove->Name . ' ' . $remove->Path);
92
			if(!$dryrun) {
93
				$removeList->remove($remove);
94
			}
95
		}
96
	}
97
98
	/**
99
	 * Sync the in-db project list with a list of file paths
100
	 *
101
	 * @param array $paths Array of pathnames
102
	 * @param DNProject
103
	 * @param bool $dryRun
104
	 */
105
	protected function syncEnvironmentPaths($paths, $project, $dryRun = false) {
106
		$list = $project->Environments();
107
108
		// Normalise paths in DB
109
		foreach($list as $item) {
110
			$real = realpath($item->Filename);
111
			if($real && $real != $item->Filename) {
112
				$item->Filename = $real;
113
				$item->write();
114
			}
115
		}
116
117
		foreach($paths as $path) {
118
			$path = basename($path);
119
			if($list->filter('Filename', $path)->count()) {
120
				continue;
121
			}
122
123
			$this->message('Adding "' . basename($path) . '" to db');
124
			if(!$dryRun) {
125
				$environment = DNEnvironment::create_from_path($path);
126
				$environment->ProjectID = $project->ID;
127
				$environment->write();
128
			}
129
		}
130
	}
131
132
	/**
133
	 * Sync the in-db project list with a list of file paths
134
	 *
135
	 * @param array $paths Array of pathnames
136
	 * @param boolean $dryRun
137
	 */
138
	public function syncProjectPaths($paths, $dryRun = false) {
139
		foreach($paths as $path) {
140
			if(!DNProject::get()->filter('Name', $path)->count()) {
141
				$this->message($path);
142
				if(!$dryRun) {
143
					DNProject::create_from_path($path)->write();
144
				}
145
			}
146
		}
147
	}
148
149
	/**
150
	 * @param string $text
151
	 */
152
	protected function message($text) {
153
		if(PHP_SAPI !== 'cli') {
154
			$text = '<p>' . $text . '</p>' . PHP_EOL;
155
		}
156
		echo ' - ' . $text . PHP_EOL;
157
	}
158
159
	/**
160
	 * @param string $text
161
	 */
162
	protected function echoHeader($text) {
163
		if(PHP_SAPI !== 'cli') {
164
			echo '<h2>' . $text . '</h2>' . PHP_EOL;
165
		} else {
166
			echo '# ' . $text . PHP_EOL;
167
		}
168
	}
169
}
170