Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
- keep copyright notice and only update the authors list
- check if all changes to a file happened after the fork, this allows the authors to check if the file can be relicensed to AGPLv3 or later
  • Loading branch information
schiessle authored and nickvergessen committed Jul 22, 2016
commit 4e52b845ea4c99e6abca1747b2793856202a8551
99 changes: 81 additions & 18 deletions build/license.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ class Licenses
{
protected $paths = [];
protected $mailMap = [];
protected $checkFiles = [];
public $authors = [];

public function __construct() {
$this->licenseText = <<<EOD
/**
@COPYRIGHT@
*
@AUTHORS@
*
* @license GNU AGPL version 3 or any later version
Expand All @@ -48,9 +51,10 @@ public function __construct() {
EOD;
$this->licenseTextLegacy = <<<EOD
/**
@COPYRIGHT@
*
@AUTHORS@
*
* @copyright Copyright (c) @YEAR@, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -89,6 +93,7 @@ function exec($folder, $gitRoot = false) {

if (is_file($folder)) {
$this->handleFile($folder, $gitRoot);
$this->printFilesToCheck();
return;
}

Expand All @@ -113,6 +118,8 @@ function exec($folder, $gitRoot = false) {
/** @var SplFileInfo $file */
$this->handleFile($file, $gitRoot);
}

$this->printFilesToCheck();
}

function writeAuthorsFile() {
Expand All @@ -139,13 +146,15 @@ function handleFile($path, $gitRoot) {
echo "MIT licensed file: $path" . PHP_EOL;
return;
}
$copyrightNotices = $this->getCopyrightNotices($path, $source);
$authors = $this->getAuthors($path, $gitRoot);
if ($this->isOwnCloudLicensed($source)) {
$authors = $this->getAuthors($path, $gitRoot, true);
$license = str_replace('@AUTHORS@', $authors, $this->licenseTextLegacy);
$this->checkCopyrightState($path, $gitRoot);
} else {
$authors = $this->getAuthors($path, $gitRoot);
$license = str_replace('@AUTHORS@', $authors, $this->licenseText);
}
$license = str_replace('@COPYRIGHT@', $copyrightNotices, $license);

$source = $this->eatOldLicense($source);
$source = "<?php" . PHP_EOL . $license . PHP_EOL . $source;
Expand All @@ -155,6 +164,7 @@ function handleFile($path, $gitRoot) {

/**
* @param string $source
* @return bool
*/
private function isMITLicensed($source) {
$lines = explode(PHP_EOL, $source);
Expand All @@ -181,7 +191,7 @@ private function isOwnCloudLicensed($source) {

return false;
}

/**
* @param string $source
* @return string
Expand Down Expand Up @@ -216,7 +226,68 @@ private function eatOldLicense($source) {
return implode(PHP_EOL, $lines);
}

private function getAuthors($file, $gitRoot, $legacyFiles = false) {
private function getCopyrightNotices($path, $file) {
$licenseHeaderEndsAtLine = (int)trim(shell_exec("grep -n '*/' $path | head -n 1 | cut -d ':' -f 1"));
$lineByLine = explode(PHP_EOL, $file, $licenseHeaderEndsAtLine);
$copyrightNotice = [];
foreach ($lineByLine as $line) {
if (strpos($line, '@copyright') !== false) {
$copyrightNotice[] = $line;
}
}

return implode(PHP_EOL, $copyrightNotice);
}

/**
* check if all lines where changed after the Nextcloud fork.
* That's not a guarantee that we can switch to AGPLv3 or later,
* but a good indicator that we should have a look at the file
*
* @param $path
* @param $gitRoot
*/
private function checkCopyrightState($path, $gitRoot) {
// This was the date the Nextcloud fork was created
$deadline = new DateTime('06/06/2016');
$deadlineTimestamp = $deadline->getTimestamp();

$buildDir = getcwd();
if ($gitRoot) {
chdir($gitRoot);
$path = substr($path, strlen($gitRoot));
}
$out = shell_exec("git --no-pager blame --line-porcelain $path | sed -n 's/^author-time //p'");
if ($gitRoot) {
chdir($buildDir);
}
$timestampChanges = explode(PHP_EOL, $out);
$timestampChanges = array_slice($timestampChanges, 0, count($timestampChanges)-1);
foreach ($timestampChanges as $timestamp) {
if ((int)$timestamp < $deadlineTimestamp) {
return;
}
}

//all changes after the deadline
$this->checkFiles[] = $path;

}

private function printFilesToCheck() {
if (!empty($this->checkFiles)) {
print "\n";
print "For following files all lines changes since the Nextcloud fork." . PHP_EOL;
print "Please check if these files can be moved over to AGPLv3 or later" . PHP_EOL;
print "\n";
foreach ($this->checkFiles as $file) {
print $file . PHP_EOL;
}
print "\n";
}
}

private function getAuthors($file, $gitRoot) {
// 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"));
$buildDir = getcwd();
Expand Down Expand Up @@ -244,19 +315,11 @@ private function getAuthors($file, $gitRoot, $legacyFiles = false) {
$authors = array_unique($authors);
}

if ($legacyFiles) {
$authors = array_map(function($author){
$this->authors[$author] = $author;
return " * @author $author";
}, $authors);
} else {
$authors = array_map(function($author){
$this->authors[$author] = $author;
return " * @copyright Copyright (c) " . date("Y") . ", $author";
}, $authors);
}


$authors = array_map(function($author){
$this->authors[$author] = $author;
return " * @author $author";
}, $authors);

return implode(PHP_EOL, $authors);
}

Expand Down