Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F11725946
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
26 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/app/Analyzers/GitHub/GitHubPayloadAnalyzer.php b/app/Analyzers/GitHub/GitHubPayloadAnalyzer.php
index 95d53f8..d74527a 100644
--- a/app/Analyzers/GitHub/GitHubPayloadAnalyzer.php
+++ b/app/Analyzers/GitHub/GitHubPayloadAnalyzer.php
@@ -1,191 +1,191 @@
<?php
namespace Nasqueron\Notifications\Analyzers\GitHub;
use Nasqueron\Notifications\Analyzers\GitHub\Events\Event;
use Nasqueron\Notifications\Analyzers\GitHub\Events\UnknownEvent;
use Config;
use Storage;
class GitHubPayloadAnalyzer {
///
/// Private members
///
/**
* The project name, used to load specific configuration and offer defaults
* @var string
*/
private $project;
/**
* The GitHub event triggering this request
* @var string
*/
private $event;
/**
* The request content, as a structured data
* @var stdClass
*/
private $payload;
/**
* The configuration for the payload analyzer
* @var Nasqueron\Notifications\Analyzers\GitHub\GitHubPayloadAnalyzerConfiguration;
*/
private $configuration;
/**
* The payload analyzer event
*
* @var Nasqueron\Notifications\Analyzers\GitHub\Events\Event;
*/
private $analyzerEvent;
///
/// Constructor
///
/**
* Creates a new GitHubPayloadAnalyzer instance.
*
* @param string $project
* @param string $event
* @param stdClass $payload
*/
public function __construct($project, $event, $payload) {
if (!is_object($payload)) {
throw new \InvalidArgumentException("Payload must be an object.");
}
$this->project = $project;
$this->event = $event;
$this->payload = $payload;
$this->loadConfiguration($project);
try {
$this->analyzerEvent = Event::forPayload($event, $payload);
} catch (\InvalidArgumentException $ex) {
$this->analyzerEvent = new UnknownEvent($event);
}
}
///
/// Configuration
///
/**
* The default name of the configuration file
*/
const CONFIG_DEFAULT_FILE = 'default.json';
/**
* Gets the full path to the configuration file.
*
* @return string
*/
public function getConfigurationFileName () {
$dir = Config::get('services.github.analyzer.configDir');
$filename = $dir . '/' . $this->project . '.json';
if (!Storage::has($filename)) {
return $dir . '/' . static::CONFIG_DEFAULT_FILE;
}
return $filename;
}
public function loadConfiguration () {
$fileName = $this->getConfigurationFileName();
$mapper = new \JsonMapper();
$this->configuration = $mapper->map(
json_decode(Storage::get($fileName)),
new GitHubPayloadAnalyzerConfiguration($this->project)
);
}
///
/// Properties
///
/**
* Gets the name of the repository.
*
* @var string
*/
public function getRepository () {
if ($this->isAdministrativeEvent()) {
return '';
}
return $this->payload->repository->name;
}
///
/// Qualification of the payload
///
/**
* @return bool
*/
public function isAdministrativeEvent () {
$administrativeEvents = [
'membership', // Member added to team
'ping', // Special ping pong event, fired on new hook
'repository', // Repository created
];
return in_array($this->event, $administrativeEvents);
}
/**
* Gets the group for a specific payload.
*
* @return string The group, central part of the routing key
*/
public function getGroup () {
// Some events are organization-level only and can't be mapped to an
// existing repository.
if ($this->isAdministrativeEvent()) {
return $this->configuration->administrativeGroup;
}
// If the payload is about some repository matching a table of
// symbols, we need to sort it to the right group.
$repository = $this->getRepository();
foreach ($this->configuration->repositoryMapping as $mapping) {
- if ($mapping->doesRepositoryBelong($repository)) {
+ if ($mapping->doesItemBelong($repository)) {
return $mapping->group;
}
}
return $this->configuration->getDefaultGroup();
}
///
/// Description of the payload
///
/**
* Gets a short textual description of the event.
*
* @return string
*/
public function getDescription () {
return $this->analyzerEvent->getDescription();
}
/**
* Gets a link to view the event on GitHub.
*
* @return string The most relevant URL
*/
public function getLink () {
return $this->analyzerEvent->getLink();
}
}
diff --git a/app/Analyzers/GitHub/GitHubPayloadAnalyzerConfiguration.php b/app/Analyzers/GitHub/GitHubPayloadAnalyzerConfiguration.php
index 64eeb49..fa36bf2 100644
--- a/app/Analyzers/GitHub/GitHubPayloadAnalyzerConfiguration.php
+++ b/app/Analyzers/GitHub/GitHubPayloadAnalyzerConfiguration.php
@@ -1,73 +1,73 @@
<?php
namespace Nasqueron\Notifications\Analyzers\GitHub;
class GitHubPayloadAnalyzerConfiguration {
///
/// Private members
///
/**
* The project this configuration is for
*
* @var string
*/
private $project;
///
/// Public properties
///
/**
* The group for organization only events
*
* @var string
*/
public $administrativeGroup;
/**
* The default group to fallback for any event not mapped in another group
*
* @var string
*/
public $defaultGroup;
/**
* An array of RepositoryGroupMapping objects to match repositories & groups
*
- * @var RepositoryGroupMapping[]
+ * @var \Nasqueron\Notifications\Analyzers\ItemGroupMapping[]
*/
public $repositoryMapping;
///
/// Constructor
///
/**
* Initializes a new instance of the GitHubPayloadAnalyzerConfiguration class
*
* @param string $project The project name this configuration is related to
*/
public function __construct ($project) {
$this->project = $project;
}
///
/// Helper methods
///
/**
* Gets the default group
*
* @return string the default group, as set in the configuration,
* or if omitted, the project name as fallback.
*/
public function getDefaultGroup () {
if (empty($this->defaultGroup)) {
return strtolower($this->project);
}
return $this->defaultGroup;
}
}
diff --git a/app/Analyzers/GitHub/RepositoryGroupMapping.php b/app/Analyzers/GitHub/RepositoryGroupMapping.php
deleted file mode 100644
index 6204abf..0000000
--- a/app/Analyzers/GitHub/RepositoryGroupMapping.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-namespace Nasqueron\Notifications\Analyzers\GitHub;
-
-class RepositoryGroupMapping {
- ///
- /// Properties
- ///
-
- /**
- * The group the mapped repositories belong to
- *
- * @var string
- */
- public $group;
-
- /**
- * An array of the repositories, each item a string with the name of the
- * repository. The wildcard '*' is allowed to specify several repositories.
- *
- * @var array
- */
- public $repositories;
-
- ///
- /// Helper methods
- ///
-
- /**
- * Determines if the specified repository matches a pattern
- *
- * @param string $pattern The pattern, with * allowed as wildcard character
- * @param string $repository The repository name to compare with the pattern
- * @return bool
- */
- public static function doesRepositoryMatch ($pattern, $repository) {
- return str_is($pattern, $repository);
- }
-
- /**
- * Determines if the specified repository belong to this mapping
- *
- * @return bool
- */
- public function doesRepositoryBelong ($actualRepository) {
- foreach ($this->repositories as $candidateRepository) {
- if (static::doesRepositoryMatch($candidateRepository, $actualRepository)) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/app/Analyzers/ItemGroupMapping.php b/app/Analyzers/ItemGroupMapping.php
new file mode 100644
index 0000000..051e113
--- /dev/null
+++ b/app/Analyzers/ItemGroupMapping.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Nasqueron\Notifications\Analyzers;
+
+/**
+ * Map items (repositories, projects, items, etc.) names to groups
+ */
+class ItemGroupMapping {
+
+ ///
+ /// Properties
+ ///
+
+ /**
+ * The group the mapped items belong to
+ *
+ * @var string
+ */
+ public $group;
+
+ /**
+ * An array of the items to map, each item a string with the name of the
+ * repository, project or item used for mapping.
+ * The wildcard '*' is allowed to specify several items.
+ *
+ * @var array
+ */
+ public $items;
+
+ ///
+ /// Helper methods
+ ///
+
+ /**
+ * Determines if the specified item matches a pattern.
+ *
+ * @param string $pattern The pattern, with * allowed as wildcard character
+ * @param string $item The item name to compare with the pattern
+ * @return bool
+ */
+ public static function doesItemMatch ($pattern, $item) {
+ return str_is($pattern, $item);
+ }
+
+ /**
+ * Determines if the specified item belong to this mapping
+ *
+ * @return bool
+ */
+ public function doesItemBelong ($actualItem) {
+ foreach ($this->items as $candidateItem) {
+ if (static::doesItemMatch($candidateItem, $actualItem)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}
diff --git a/app/Analyzers/Phabricator/PhabricatorGroupMapping.php b/app/Analyzers/Phabricator/PhabricatorGroupMapping.php
index ae88013..697b2c0 100644
--- a/app/Analyzers/Phabricator/PhabricatorGroupMapping.php
+++ b/app/Analyzers/Phabricator/PhabricatorGroupMapping.php
@@ -1,76 +1,39 @@
<?php
namespace Nasqueron\Notifications\Analyzers\Phabricator;
+use Nasqueron\Notifications\Analyzers\ItemGroupMapping;
use Nasqueron\Notifications\Phabricator\PhabricatorStory;
-class PhabricatorGroupMapping {
+class PhabricatorGroupMapping extends ItemGroupMapping {
+
///
- /// Properties
+ /// Extra properties
///
- /**
- * The group the mapped projects belong to
- *
- * @var string
- */
- public $group;
-
- /**
- * An array of the projects, each item a string with the name of the
- * project. The wildcard '*' is allowed to specify several projects.
- *
- * @var array
- */
- public $projects;
-
/**
* An array of words, each item a string with a word to find in the story.
*
* @var array
*/
public $words = [];
///
- /// Helper methods
+ /// Helper methods to process words
///
- /**
- * Determines if the specified project matches a pattern
- *
- * @param string $pattern The pattern, with * allowed as wildcard character
- * @param string $project The project name to compare with the pattern
- * @return bool
- */
- public static function doesProjectMatch ($pattern, $project) {
- return str_is($pattern, $project);
- }
-
- /**
- * Determines if the specified project belong to this mapping
- *
- * @return bool
- */
- public function doesProjectBelong ($actualProject) {
- foreach ($this->projects as $candidateProject) {
- if (static::doesProjectMatch($candidateProject, $actualProject)) {
- return true;
- }
- }
- return false;
- }
-
/**
* Determines if the specified story belong to this mapping
*
* @return bool
*/
public function doesStoryBelong (PhabricatorStory $story) {
foreach ($this->words as $word) {
if (stripos($story->text, $word) !== false) {
return true;
}
}
return false;
}
+
}
diff --git a/app/Analyzers/Phabricator/PhabricatorPayloadAnalyzer.php b/app/Analyzers/Phabricator/PhabricatorPayloadAnalyzer.php
index 2a31b76..f949040 100644
--- a/app/Analyzers/Phabricator/PhabricatorPayloadAnalyzer.php
+++ b/app/Analyzers/Phabricator/PhabricatorPayloadAnalyzer.php
@@ -1,138 +1,138 @@
<?php
namespace Nasqueron\Notifications\Analyzers\Phabricator;
use Nasqueron\Notifications\Phabricator\PhabricatorStory;
use Config;
use Storage;
class PhabricatorPayloadAnalyzer {
-
+
///
/// Private members
///
/**
* The project name, used to load specific configuration and offer defaults
* @var string
*/
private $project;
/**
* The story
* @var PhabricatorStory
*/
private $story;
/**
* The configuration for the payload analyzer
* @var PhabricatorPayloadAnalyzerConfiguration;
*/
private $configuration;
///
/// Constructor
///
/**
* Creates a new PhabricatorPayloadAnalyzer instance.
*
* @param string $project
* @param PhabricatorStory $story
*/
public function __construct($project, PhabricatorStory $story) {
$this->project = $project;
$this->story = $story;
$this->loadConfiguration($project);
}
///
/// Configuration
///
/**
* The default name of the configuration file
*/
const CONFIG_DEFAULT_FILE = 'default.json';
/**
* Gets the full path to the configuration file.
*
* @return string
*/
public function getConfigurationFileName () {
$dir = Config::get('services.phabricator.analyzer.configDir');
$filename = $dir . '/' . $this->project . '.json';
if (!Storage::has($filename)) {
return $dir . '/' . static::CONFIG_DEFAULT_FILE;
}
return $filename;
}
/**
* Gets the full path to the configuration file.
*
* @return string
*/
public function loadConfiguration () {
$fileName = $this->getConfigurationFileName();
$mapper = new \JsonMapper();
$this->configuration = $mapper->map(
json_decode(Storage::get($fileName)),
new PhabricatorPayloadAnalyzerConfiguration()
);
}
///
/// Qualification of the story
///
/**
* @return bool
*/
public function isAdministrativeEvent () {
return false;
}
/**
* Gets the group for a specific story.
*
* @return string the group, central part of the routing key
*/
public function getGroup () {
// Some events are organization-level only and can't be mapped
// to projects.
if ($this->isAdministrativeEvent()) {
return $this->configuration->administrativeGroup;
}
// If the payload is about some repository matching a table of
// symbols, we need to sort it to the right group.
foreach ($this->configuration->groupsMapping as $mapping) {
foreach ($this->story->getProjects() as $project) {
- if ($mapping->doesProjectBelong($project)) {
+ if ($mapping->doesItemBelong($project)) {
return $mapping->group;
}
}
}
// Words
foreach ($this->configuration->groupsMapping as $mapping) {
if ($mapping->doesStoryBelong($this->story)) {
return $mapping->group;
}
}
// By default, fallback group is the project name or a specified value.
if (empty($this->configuration->defaultGroup)) {
return strtolower($this->project);
}
return $this->configuration->defaultGroup;
}
}
diff --git a/tests/Analyzers/GitHub/GitHubPayloadAnalyzerConfigurationTest.php b/tests/Analyzers/GitHub/GitHubPayloadAnalyzerConfigurationTest.php
index 8f2d4dd..056e534 100644
--- a/tests/Analyzers/GitHub/GitHubPayloadAnalyzerConfigurationTest.php
+++ b/tests/Analyzers/GitHub/GitHubPayloadAnalyzerConfigurationTest.php
@@ -1,65 +1,63 @@
<?php
namespace Nasqueron\Notifications\Tests\Analyzers;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Nasqueron\Notifications\Analyzers\GitHub\GitHubPayloadAnalyzerConfiguration;
+use Nasqueron\Notifications\Analyzers\ItemGroupMapping;
use Nasqueron\Notifications\Tests\TestCase;
class GitHubPayloadAnalyzerConfigurationTest extends TestCase {
/**
* Configuration
*
* @var Nasqueron\Notifications\Analyzers\GitHub\GitHubPayloadAnalyzerConfiguration
*/
protected $configuration;
/**
* Prepares the test
*/
public function setUp () {
$filename = __DIR__ . '/../../data/GitHubPayloadAnalyzer/Nasqueron.json';
$mapper = new \JsonMapper();
$this->configuration = $mapper->map(
json_decode(file_get_contents($filename)),
new GitHubPayloadAnalyzerConfiguration('Nasqueron')
);
parent::setUp();
}
/**
* Determines the JSON object is well parsed
*/
public function testProperties () {
$this->assertSame("orgz", $this->configuration->administrativeGroup);
$this->assertSame("nasqueron", $this->configuration->defaultGroup);
foreach ($this->configuration->repositoryMapping as $item) {
- $this->assertInstanceOf(
- 'Nasqueron\Notifications\Analyzers\GitHub\RepositoryGroupMapping',
- $item
- );
+ $this->assertInstanceOf(ItemGroupMapping::class, $item);
}
}
///
/// Tests for getDefaultGroup
///
public function testGetDefaultGroup () {
$this->configuration->defaultGroup = "quux";
$this->assertSame("quux", $this->configuration->getDefaultGroup());
}
public function testGetDefaultGroupWhenNotInConfig () {
$this->configuration->defaultGroup = "";
$this->assertSame("nasqueron", $this->configuration->getDefaultGroup());
$this->configuration->defaultGroup = null;
$this->assertSame("nasqueron", $this->configuration->getDefaultGroup());
}
}
diff --git a/tests/Analyzers/GitHub/RepositoryGroupMappingTest.php b/tests/Analyzers/ItemGroupMappingTest.php
similarity index 59%
rename from tests/Analyzers/GitHub/RepositoryGroupMappingTest.php
rename to tests/Analyzers/ItemGroupMappingTest.php
index 965e36a..53b6a50 100644
--- a/tests/Analyzers/GitHub/RepositoryGroupMappingTest.php
+++ b/tests/Analyzers/ItemGroupMappingTest.php
@@ -1,48 +1,48 @@
<?php
namespace Nasqueron\Notifications\Tests\Analyzers;
use Illuminate\Foundation\Testing\WithoutMiddleware;
-use Nasqueron\Notifications\Analyzers\GitHub\RepositoryGroupMapping;
+use Nasqueron\Notifications\Analyzers\ItemGroupMapping;
use Nasqueron\Notifications\Tests\TestCase;
-class RepositoryGroupMappingTest extends TestCase {
+class ItemGroupMappingTest extends TestCase {
- public function testDoesRepositoryMatch () {
+ public function testDoesItemMatch () {
$this->assertTrue(
- RepositoryGroupMapping::doesRepositoryMatch(
+ ItemGroupMapping::doesItemMatch(
'quux*',
'quuxians'
)
);
$this->assertTrue(
- RepositoryGroupMapping::doesRepositoryMatch(
+ ItemGroupMapping::doesItemMatch(
'quux*',
'quux'
)
);
$this->assertFalse(
- RepositoryGroupMapping::doesRepositoryMatch(
+ ItemGroupMapping::doesItemMatch(
'foobar',
'quux'
)
);
$this->assertFalse(
- RepositoryGroupMapping::doesRepositoryMatch(
+ ItemGroupMapping::doesItemMatch(
'',
'quuxians'
)
);
$this->assertFalse(
- RepositoryGroupMapping::doesRepositoryMatch(
+ ItemGroupMapping::doesItemMatch(
'quux*',
''
)
);
}
}
diff --git a/tests/Analyzers/Phabricator/PhabricatorGroupMappingTest.php b/tests/Analyzers/Phabricator/PhabricatorGroupMappingTest.php
index 12add1a..b6376ef 100644
--- a/tests/Analyzers/Phabricator/PhabricatorGroupMappingTest.php
+++ b/tests/Analyzers/Phabricator/PhabricatorGroupMappingTest.php
@@ -1,127 +1,90 @@
<?php
namespace Nasqueron\Notifications\Tests\Analyzers\Phabricator;
use Nasqueron\Notifications\Analyzers\Phabricator\PhabricatorGroupMapping;
use Nasqueron\Notifications\Tests\TestCase;
class PhabricatorGroupMappingTest extends TestCase {
use WithConfiguration;
/**
* @var PhabricatorGroupMapping|]
*/
private $mappings;
/**
* @var PhabricatorStory
*/
private $story;
public function setUp () {
parent::setUp();
$config = $this->getPhabricatorPayloadAnalyzerConfiguration();
$keys = [
'projects',
'words',
'strongWords',
];
$this->mappings = array_combine($keys, $config->groupsMapping);
$this->story = $this->getStory();
}
///
/// Tests
///
- public function testDoesProjectMatch () {
- $this->assertTrue(
- PhabricatorGroupMapping::doesProjectMatch(
- 'quux*',
- 'quuxians'
- )
- );
-
- $this->assertTrue(
- PhabricatorGroupMapping::doesProjectMatch(
- 'quux*',
- 'quux'
- )
- );
-
- $this->assertFalse(
- PhabricatorGroupMapping::doesProjectMatch(
- 'foobar',
- 'quux'
- )
- );
-
- $this->assertFalse(
- PhabricatorGroupMapping::doesProjectMatch(
- '',
- 'quuxians'
- )
- );
-
- $this->assertFalse(
- PhabricatorGroupMapping::doesProjectMatch(
- 'quux*',
- ''
- )
- );
- }
-
public function testDoesProjectBelong () {
$mapping = $this->mappings['projects'];
$this->assertFalse(
- $mapping->doesProjectBelong("")
+ $mapping->doesItemBelong("")
);
$this->assertFalse(
- $mapping->doesProjectBelong("Tasacora")
+ $mapping->doesItemBelong("Tasacora")
);
$this->assertTrue(
- $mapping->doesProjectBelong("Docker images")
+ $mapping->doesItemBelong("Docker images")
);
$this->assertFalse(
- $mapping->doesProjectBelong("Docker")
+ $mapping->doesItemBelong("Docker")
);
$this->assertFalse(
- $mapping->doesProjectBelong("Docker images quux")
+ $mapping->doesItemBelong("Docker images quux")
);
}
public function testDoesStoryBelong () {
$mapping = $this->mappings['words'];
$this->assertFalse(
$mapping->doesStoryBelong($this->story)
);
$this->story->text = "Review the cartography elements.";
$this->assertTrue(
$mapping->doesStoryBelong($this->story)
);
}
/**
* Test to fix T773
*/
public function testDoesStoryBelongWhenWordIsInAnotherCase () {
$mapping = $this->mappings['words'];
$this->story->text = "Review the Cartography elements.";
$this->assertTrue(
$mapping->doesStoryBelong($this->story)
);
}
}
diff --git a/tests/data/GitHubPayloadAnalyzer/Nasqueron.json b/tests/data/GitHubPayloadAnalyzer/Nasqueron.json
index 74c1100..21bab6e 100644
--- a/tests/data/GitHubPayloadAnalyzer/Nasqueron.json
+++ b/tests/data/GitHubPayloadAnalyzer/Nasqueron.json
@@ -1,30 +1,30 @@
{
"administrativeGroup": "orgz",
"defaultGroup": "nasqueron",
"repositoryMapping": [
{
"group": "docker",
- "repositories": [
+ "items": [
"docker-*"
]
},
{
"group": "tasacora",
- "repositories": [
+ "items": [
"tasacora-*"
]
},
{
"group": "ops",
- "repositories": [
+ "items": [
"decommission",
"discourse-config",
"ftp",
"notifications",
"operations",
"servers-*",
"zemke-rhyne"
]
}
]
}
diff --git a/tests/data/PhabricatorPayloadAnalyzer/Nasqueron.json b/tests/data/PhabricatorPayloadAnalyzer/Nasqueron.json
index 96bfbf2..bbb4b37 100644
--- a/tests/data/PhabricatorPayloadAnalyzer/Nasqueron.json
+++ b/tests/data/PhabricatorPayloadAnalyzer/Nasqueron.json
@@ -1,42 +1,42 @@
{
"administrativeGroup": "orgz",
"defaultGroup": "nasqueron",
"groupsMapping": [
{
"group": "docker",
- "projects": [
+ "items": [
"Docker images",
"Nasqueron Docker deployment squad"
]
},
{
"group": "tasacora",
- "projects":[
+ "items":[
"Tasacora"
],
"words": [
"Tasacora",
"cartography"
]
},
{
"group": "ops",
- "projects": [
+ "items": [
"Continous integration and delivery",
"IPv6",
"Mail",
"Message queues",
"Murasil",
"Nasqueron security operations squad",
"Servers",
"Ops-sprint-*"
],
"words": [
"Ysul",
"Dwellers",
"pkg audit"
],
"wordsAreStrong": true
}
]
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Sep 18, 22:38 (2 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2991885
Default Alt Text
(26 KB)
Attached To
Mode
rNOTIF Notifications center
Attached
Detach File
Event Timeline
Log In to Comment