Skip to content
This repository was archived by the owner on Jan 31, 2024. It is now read-only.

Commit 2f18839

Browse files
authored
Merge pull request #18 from ajmichels/some-improvements
some refactoring and added unit tests
2 parents 720365f + 05b7467 commit 2f18839

15 files changed

+695
-88
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ language: php
22
php:
33
- '5.6'
44
- '7.0'
5-
- nightly
5+
- '7.1'
66
install: composer install
77
script:
88
- composer lint

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "ajmichels/note-script",
33
"description": "A utility for note taking.",
44
"keywords": ["utility", "notes", "productivity", "markdown"],
5-
"version": "0.0.1",
5+
"version": "0.1.0",
66
"license": "GPL-2.0",
77
"type": "project",
88
"authors": [

composer.lock

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

logs/.gitkeep

Whitespace-only changes.

src/main/Config.php

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2016, AJ Michels
5+
*
6+
* This file is part of Note-Script.
7+
*
8+
* This program is free software; you can redistribute it and/or modify it under the terms of the
9+
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
13+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License along with this program; if
17+
* not, write to the Free Software Foundation, Inc.,
18+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
21+
namespace NoteScript;
22+
23+
use ArrayAccess;
24+
25+
/**
26+
* Initializes and stores application configuration data.
27+
*/
28+
class Config implements ArrayAccess
29+
{
30+
31+
const NOTE_DIR = 'noteDir';
32+
const LOG_DIR = 'logDir';
33+
const ENV_VAR_HOME = 'HOME';
34+
const ENV_VAR_NOTE_HOME = 'NOTE_HOME';
35+
const DEFAULT_NOTE_DIR = '/notes';
36+
37+
/**
38+
* Collection of configuration key/value pairs
39+
* @var array
40+
*/
41+
private $values = [];
42+
43+
/**
44+
* Constructor method
45+
*/
46+
public function __construct(array $values)
47+
{
48+
$this->values = $values;
49+
}
50+
51+
/**
52+
* Factory method for creating new instances of Config.
53+
* @return NoteScript\Config A newly created instance of Config
54+
*/
55+
public static function create()
56+
{
57+
$configValues = [];
58+
$configValues[self::NOTE_DIR] = self::getNoteDirectory();
59+
$configValues[self::LOG_DIR] = dirname(dirname(__DIR__)) . '/logs';
60+
return new Config($configValues);
61+
}
62+
63+
/**
64+
* Determine if a specific config value exists
65+
* @param mixed $offset The key for the config value.
66+
* @return boolean True if config value exists.
67+
*/
68+
public function offsetExists($offset)
69+
{
70+
return isset($this->values[$offset]);
71+
}
72+
73+
/**
74+
* Retrieve a configuration value by key.
75+
* @param mixed $offset The key for the value being fetched.
76+
* @return mixed|null The value or null
77+
*/
78+
public function offsetGet($offset)
79+
{
80+
return $this->offsetExists($offset) ? $this->values[$offset] : null;
81+
}
82+
83+
/**
84+
* Required by the ArrayAccess interface, but in this case will throw an exception as config
85+
* values are read only.
86+
* @param mixed $offset They key for the value
87+
* @param mixed $value The value being set
88+
* @throws NoteScript\ConfigException
89+
* @return null
90+
*/
91+
public function offsetSet($offset, $value)
92+
{
93+
throw new ConfigException(ConfigException::MSG_READ_ONLY);
94+
}
95+
96+
/**
97+
* Required by the ArrayAccess interface, but in this case will throw an exception as config
98+
* values are read only and cannot be removed once set.
99+
* @param mixed $offset The key of the value to be removed
100+
* @throws NoteScript\ConfigException
101+
* @return null
102+
*/
103+
public function offsetUnset($offset)
104+
{
105+
throw new ConfigException(ConfigException::MSG_NOT_REMOVABLE);
106+
}
107+
108+
/**
109+
* Retrieves the directory for storing notes by reading certain environment variables.
110+
* @throws NoteScript\ConfigException
111+
* @return string Path to directory
112+
*/
113+
private static function getNoteDirectory()
114+
{
115+
$noteDir = getenv(self::ENV_VAR_NOTE_HOME);
116+
117+
if ($noteDir === false || trim($noteDir) === '') {
118+
$homeDir = getenv(self::ENV_VAR_HOME);
119+
120+
if ($homeDir === false || trim($homeDir) === '') {
121+
$msg = sprintf(ConfigException::MSG_MISSING_ENV_VAR, self::ENV_VAR_HOME);
122+
throw new ConfigException($msg);
123+
}
124+
125+
$noteDir = $homeDir . self::DEFAULT_NOTE_DIR;
126+
}
127+
128+
return $noteDir;
129+
}
130+
131+
}

src/main/ConfigException.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2016, AJ Michels
5+
*
6+
* This file is part of Note-Script.
7+
*
8+
* This program is free software; you can redistribute it and/or modify it under the terms of the
9+
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
13+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License along with this program; if
17+
* not, write to the Free Software Foundation, Inc.,
18+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
21+
namespace NoteScript;
22+
23+
use RuntimeException;
24+
25+
/**
26+
* Exceptions that are thrown when there are problems with the application configuration.
27+
*/
28+
class ConfigException extends RuntimeException
29+
{
30+
const MSG_READ_ONLY = 'Config values are read only.';
31+
const MSG_NOT_REMOVABLE = 'Config values cannot be removed.';
32+
const MSG_MISSING_ENV_VAR = 'There is no $%s environment variable defined.';
33+
}

src/main/ErrorHandler.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020

2121
namespace NoteScript;
2222

23+
use ErrorException;
24+
use Exception;
25+
26+
/**
27+
* Used to capture, interpret, and output errors and exceptions.
28+
*/
2329
class ErrorHandler
2430
{
2531

@@ -44,4 +50,16 @@ public static function handle($severity, $message, $filename, $lineNum)
4450
}
4551
}
4652

53+
/**
54+
* Takes an exception object and prints it as a string to STDERR
55+
* @param Exception $e The exception to print
56+
* @return null
57+
*/
58+
public static function printException(Exception $e)
59+
{
60+
$stderr = fopen('php://stderr', 'w');
61+
fwrite($stderr, (string) $e);
62+
fclose($stderr);
63+
}
64+
4765
}

src/main/FileUtil.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2016, AJ Michels
5+
*
6+
* This file is part of Note-Script.
7+
*
8+
* This program is free software; you can redistribute it and/or modify it under the terms of the
9+
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
13+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License along with this program; if
17+
* not, write to the Free Software Foundation, Inc.,
18+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
21+
namespace NoteScript;
22+
23+
use Exception;
24+
use Psr\Log\LoggerInterface;
25+
26+
/**
27+
* Provides methods for manipulating files.
28+
*/
29+
class FileUtil
30+
{
31+
32+
const DEFAULT_DIR_MODE = 0700;
33+
const DEFAULT_FILE_MODE = 0600;
34+
const MSG_FILE_EXISTS = 'File already exists (%s)';
35+
const MSG_FILE_CREATED = 'File Created (%s)';
36+
37+
/**
38+
* @var Psr\Log\LoggerInterface
39+
*/
40+
private $logger;
41+
42+
/**
43+
* Constructor
44+
* @param Psr\Log\LoggerInterface $logger
45+
*/
46+
public function __construct(LoggerInterface $logger)
47+
{
48+
$this->logger = $logger;
49+
}
50+
51+
/**
52+
* Will write contents to provided file path. If the directory for the file doesn't exist it
53+
* will be created. If the file already exists an exception will be thrown.
54+
* @param string $path The file path to write to.
55+
* @param string $content The content to write to the file.
56+
* @throws Exception
57+
* @return null
58+
*/
59+
public function writeFile($path, $content)
60+
{
61+
$directory = dirname($path);
62+
63+
// Create the directory if it doesn't exist
64+
if (!is_dir($directory)) {
65+
mkdir($directory, self::DEFAULT_DIR_MODE, true);
66+
}
67+
68+
if (file_exists($path)) {
69+
$msg = sprintf(self::MSG_FILE_EXISTS, $path);
70+
$this->logger->warning($msg);
71+
throw new Exception($msg);
72+
}
73+
74+
$file = fopen($path, 'x');
75+
fwrite($file, $content);
76+
fclose($file);
77+
chmod($path, self::DEFAULT_FILE_MODE);
78+
$this->logger->info(sprintf(self::MSG_FILE_CREATED, $path));
79+
}
80+
81+
}

src/main/Logger.php

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,52 @@
2121
namespace NoteScript;
2222

2323
use Monolog\Logger as Monolog;
24+
use Monolog\Formatter\LineFormatter;
2425
use Monolog\Handler\SyslogHandler;
25-
use Monolog\Handler\RotatingFileHandler;
26+
use Monolog\Handler\StreamHandler;
2627

28+
/**
29+
* Writes and manages application logs.
30+
*/
2731
class Logger extends Monolog
2832
{
2933

30-
public function __construct($logDir)
34+
/**
35+
* Constructor
36+
* Since this class extends Monolog all this constructor is ding is encapsulating the
37+
* initialization of a logger instance that is specific to this application.
38+
*/
39+
public function __construct()
3140
{
3241
parent::__construct('note-script');
3342

43+
// Always log errors to the system log
3444
$this->pushHandler(new SyslogHandler($this->getName(), 'user', Monolog::ERROR));
35-
$this->pushHandler(new RotatingFileHandler($logDir . '/note-script.log', 10, Monolog::DEBUG));
45+
46+
// Log to STDOUT based on the verbosity flags
47+
$stdOutStreamHandler = new StreamHandler('php://stdout', self::getVerbosityFromArgs());
48+
$stdOutStreamHandler->setFormatter(new LineFormatter("%level_name%: %message% %context% %extra%\n"));
49+
$this->pushHandler($stdOutStreamHandler);
50+
}
51+
52+
/**
53+
* Determines what the verbosity of the current execution is based on command line arguments.
54+
* @return int
55+
*/
56+
public static function getVerbosityFromArgs()
57+
{
58+
$args = array_slice($_SERVER['argv'], 1);
59+
$verbosity = Monolog::WARNING;
60+
61+
if (false !== array_search('-vvv', $args)) {
62+
$verbosity = Monolog::DEBUG;
63+
} elseif (false !== array_search('-vv', $args)) {
64+
$verbosity = Monolog::INFO;
65+
} elseif (false !== array_search('-v', $args)) {
66+
$verbosity = Monolog::NOTICE;
67+
}
68+
69+
return $verbosity;
3670
}
3771

3872
}

0 commit comments

Comments
 (0)