<?php /** * @author Thomas Müller * * @copyright Copyright (c) 2015, ownCloud, Inc. * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see <http://www.gnu.org/licenses/> * */ class Licenses { protected $paths = array(); public function __construct() { $this->licenseText = <<<EOD /** @AUTHORS@ * * @copyright Copyright (c) @YEAR@, ownCloud, Inc. * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see <http://www.gnu.org/licenses/> * */ EOD; $this->licenseText = str_replace('@YEAR@', date("Y"), $this->licenseText); } function exec($folder) { if (is_array($folder)) { foreach($folder as $f) { $this->exec($f); } return; } if (is_file($folder)) { $this->handleFile($folder); return; } $excludes = array_map(function($item) use ($folder) { return $folder . '/' . $item; }, ['vendor', '3rdparty', '.git', 'l10n', 'templates']); $iterator = new RecursiveDirectoryIterator($folder, RecursiveDirectoryIterator::SKIP_DOTS); $iterator = new RecursiveCallbackFilterIterator($iterator, function($item) use ($folder, $excludes){ /** @var SplFileInfo $item */ foreach($excludes as $exclude) { if (substr($item->getPath(), 0, strlen($exclude)) === $exclude) { return false; } } return true; }); $iterator = new RecursiveIteratorIterator($iterator); $iterator = new RegexIterator($iterator, '/^.+\.php$/i'); foreach ($iterator as $file) { /** @var SplFileInfo $file */ $this->handleFile($file); } } function handleFile($path) { $source = file_get_contents($path); if ($this->isMITLicensed($source)) { echo "MIT licensed file: $path" . PHP_EOL; return; } $source = $this->eatOldLicense($source); $authors = $this->getAuthors($path); $license = str_replace('@AUTHORS@', $authors, $this->licenseText); $source = "<?php" . PHP_EOL . $license . PHP_EOL . $source; file_put_contents($path,$source); echo "License updated: $path" . PHP_EOL; } private function isMITLicensed($source) { $lines = explode(PHP_EOL, $source); while(!empty($lines)) { $line = $lines[0]; array_shift($lines); if (strpos($line, 'The MIT License') !== false) { return true; } } return false; } private function eatOldLicense($source) { $lines = explode(PHP_EOL, $source); while(!empty($lines)) { $line = $lines[0]; if (strpos($line, '<?php') !== false) { array_shift($lines); continue; } if (strpos($line, '/**') !== false) { array_shift($lines); continue; } if (strpos($line, '*/') !== false ) { array_shift($lines); break; } if (strpos($line, '*') !== false) { array_shift($lines); continue; } if (trim($line) === '') { array_shift($lines); continue; } break; } return implode(PHP_EOL, $lines); } private function getAuthors($file) { // only add authors that changed code and not the license header $licenseHeaderEndsAtLine = trim(shell_exec("grep -n '*/' $file | head -n 1 | cut -d ':' -f 1")); $out = shell_exec("git blame --line-porcelain -L $licenseHeaderEndsAtLine, $file | sed -n 's/^author //p;s/^author-mail //p' | sed 'N;s/\\n/ /' | sort -f | uniq"); $authors = explode(PHP_EOL, $out); $authors = array_filter($authors, function($author) { return !in_array($author, [ '', 'Not Committed Yet <not.committed.yet>', 'Jenkins for ownCloud <owncloud-bot@tmit.eu>']); }); $authors = array_map(function($author){ return " * @author $author"; }, $authors); return implode(PHP_EOL, $authors); } } $licenses = new Licenses; if (isset($argv[1])) { $licenses->exec($argv[1]); } else { $licenses->exec([ '../apps/files', '../apps/encryption', '../apps/files_external', '../apps/files_sharing', '../apps/files_trashbin', '../apps/files_versions', '../apps/provisioning_api', '../apps/user_ldap', '../core', '../lib', '../ocs', '../settings', '../console.php', '../cron.php', '../index.php', '../public.php', '../remote.php', '../status.php', '../version.php', ]); }