Giter Club home page Giter Club logo

central's People

Contributors

bhoat avatar burex avatar circlecode avatar flip111 avatar gitter-badger avatar grummfy avatar guiled avatar hywan avatar jubianchi avatar k-phoen avatar lalop avatar luxifer avatar mathroc avatar metalaka avatar mgratch avatar mikesimonson avatar nicolas-grekas avatar osaris avatar pierozi avatar rogeriopradoj avatar samundra avatar serafimarts avatar shouze avatar shulard avatar smoench avatar stephpy avatar tomzx avatar tyx avatar vonglasow avatar zackkatz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

central's Issues

Why Hoa?

Explain what are the pros and the cons of Hoa, why do you love it, why to use it instead of another projects, why is it possible to include it in your existing projects?

Go on :-).

Update all composer.json for the `support` entry

The support entry is set to:

    "support": {
        "email" : "[email protected]",
        "irc"   : "irc://irc.freenode.org/hoaproject",
        "source": "http://git.hoa-project.net/"
    },

This is wrong for the email part. We must fix it. Any proposal @hoaproject/hoackers?

See #37 (comment) for the diff and issue templates.

Progression

  • Acl,
  • Bench,
  • Cache,
  • Cli,
  • Compiler,
  • Consistency,
  • Console,
  • Core,
  • Database,
  • Devtools,
  • Dispatcher,
  • Dns,
  • Event,
  • Eventsource,
  • Exception,
  • Fastcgi,
  • File,
  • Graph,
  • Http,
  • Irc,
  • Iterator,
  • Json,
  • Locale,
  • Log,
  • Mail,
  • Math,
  • Memory,
  • Mime,
  • Model,
  • Notification,
  • Praspel,
  • Promise,
  • Protocol,
  • Prototype,
  • Realdom,
  • Regex,
  • Registry,
  • Router,
  • Ruler,
  • Serialize,
  • Session,
  • Socket,
  • Stream,
  • String,
  • Stringbuffer,
  • Test,
  • Translate,
  • Tree,
  • Ustring,
  • View,
  • Visitor,
  • Websocket,
  • Worker,
  • Xml,
  • Xmlrpc,
  • Xyl,
  • Zformat,
  • Zombie,
  • .

Missing README.md

That's really nice hoa has such a rich collection of libraries. However some libraries don't describe themselves.
For most of those it's easy to guess what they are, but not why they are made and how they compare to other libraries or even native php functions. Maybe some of them are only intended to be used in another project, and maybe some can be very well used standalone? Which ones are production ready?

https://github.com/hoaproject/Xyl
https://github.com/hoaproject/Http
https://github.com/hoaproject/Stream
https://github.com/hoaproject/XmlRpc
https://github.com/hoaproject/Xml
https://github.com/hoaproject/Visitor
https://github.com/hoaproject/Tree
https://github.com/hoaproject/Translate
https://github.com/hoaproject/Stringbuffer
https://github.com/hoaproject/Socket
https://github.com/hoaproject/Serialize
https://github.com/hoaproject/Regex
https://github.com/hoaproject/Realdom
https://github.com/hoaproject/Prototype
https://github.com/hoaproject/Model
https://github.com/hoaproject/Memory
https://github.com/hoaproject/Math
https://github.com/hoaproject/Mail
https://github.com/hoaproject/Log
https://github.com/hoaproject/Locale
https://github.com/hoaproject/Json
https://github.com/hoaproject/Iterator
https://github.com/hoaproject/Graph
https://github.com/hoaproject/Filter
https://github.com/hoaproject/File
https://github.com/hoaproject/Cache
https://github.com/hoaproject/Acl
https://github.com/hoaproject/Sandbox
https://github.com/hoaproject/Embryo
https://github.com/hoaproject/Observer
https://github.com/hoaproject/Notification

droping of php version

Hello,
it's cool to follow the php version end of life, and I totally agree on the principle BUT for enterprise support it will be hard.

Why?
Because too many enterprise are late related to they PHP versions. Whatever they reason. But because we don't follow semver, it's hard for them to see that this BC break have been made. By the way, with this system, it's impossible to have a support about a bug in a previous version ;)

Define commit type, and enhance the `CHANGELOG` format

Hello fellow @hoaproject/hoackers and users!

Introduction

Actual commit messages in Hoa are really great. They are detailed, meaningful, reviewed, and comprehensive. The commit title is always: scope: title. However, when generating the CHANGELOG.md file, this is hard to see what is a bug fix or a new feature.

Goal

Import the concept of “commit type” from the Angular commit message guideline.

To quote it:

We have very precise rules over how our git commit messages can be formatted. This leads to more
readable messages
that are easy to follow when looking through the project history. But also,
we use the git commit messages to generate the AngularJS change log.

The commit message formatting can be added using a typical git workflow or through the use of a CLI
wizard (Commitizen). To use the wizard, run yarn run commit
in your terminal after staging your changes in git.

Commit Message Format

Each commit message consists of a header, a body and a footer. The header has a special
format that includes a type, a scope and a subject:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

The header is mandatory and the scope of the header is optional.

Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.

Revert

If the commit reverts a previous commit, it should begin with revert: , followed by the header of the reverted commit.
In the body it should say: This reverts commit <hash>., where the hash is the SHA of the commit being reverted.

Type

Must be one of the following:

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing
    semi-colons, etc)
  • refactor: A code change that neither fixes a bug nor adds a feature
  • perf: A code change that improves performance
  • test: Adding missing or correcting existing tests
  • chore: Changes to the build process or auxiliary tools and libraries such as documentation
    generation

Scope

The scope could be anything specifying place of the commit change. For example $location,
$browser, $compile, $rootScope, ngHref, ngClick, ngView, etc...

You can use * when the change affects more than a single scope.

Subject

The subject contains succinct description of the change:

  • use the imperative, present tense: "change" not "changed" nor "changes"
  • don't capitalize first letter
  • no dot (.) at the end

Body

Just as in the subject, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.

Footer

The footer should contain any information about Breaking Changes and is also the place to
[reference GitHub issues that this commit closes][closing-issues].

Breaking Changes should start with the word BREAKING CHANGE: with a space or two newlines.
The rest of the commit message is then used for this.

A detailed explanation can be found in this [document][commit-message-format].

Not everything is useful. We are mostly concerned about the “commit type”.

Differences with the current format

The “commit type” is the only main difference, and this is what I would like to “import” in our format. The goal is to generate a CHANGELOG as suggested by http://keepachangelog.com/en/0.3.0/, so with the “Added”, “Bug fixes”, “Removed“ Sections, and the date of the release (already given by our Rust Release snapshot format, but anyway, we should give it a try).

Commit types

I would like to introduce the following commit types:

  • feat for a new feature,
  • fix for a bug fix,
  • test for a test modification,
  • doc for a documentation modification,
  • chore to replace the “Quality” type,
  • undef for anything else, must not be used, so should we introduce it?

Example

In the Angular commit message guideline, they propose this syntax: type(scope): title. In Hoa, we use scope: title. The colon is a separator. However, the commit type will reduce the size of the title (remember that we have only 50 characters for the whole line!). With the type(scope) we no longer need a separator, so I propose type(scope) title, like

  • feat(permission) Search backward bla bla.,
  • fix(user) `getName` is incorrectly computing its value.,

Will produce:

2.17.16.02

New features

Permission

  • Search backward bla bla (Ivan Enderlin, date, bla).

Bug fixes

User

  • getName is incorrectly computing its value (Ivan Enderlin, date, bla).

Thoughts?

[meta] Add .gitignore file in all repositories to enhance composer user usability

Hello,

We discussed here hoaproject/Devtools#16 about adding .gitignore files to repos. This file will help Composer users which also want to contribute to do not commit unnecessary files (vendor, .lock).

This issue is here to discussed what need to be ignored before create all these files.

For me, the simplest can be :

/vendor/
composer.lock

The composer.lock is ignore here to be coherent with the Rüsh Release process used by Hoa.


Progression:

  • Acl
  • Bench
  • Cache
  • Compiler
  • Console
  • Core
  • Database
  • Devtools
  • Dispatcher
  • Dns
  • Eventsource
  • Fastcgi
  • File
  • Filter
  • Graph
  • Http
  • Iterator
  • Json
  • Locale
  • Log
  • Mail
  • Math
  • Memory
  • Mime
  • Model
  • Notification
  • Praspel
  • Promise
  • Prototype
  • Realdom
  • Regex
  • Registry
  • Router
  • Ruler
  • Serialize
  • Session
  • Socket
  • Stream
  • Stringbuffer
  • Translate
  • Tree
  • Ustring
  • View
  • Visitor
  • Websocket
  • Worker
  • Xml
  • Xmlrpc
  • Xyl
  • Zombie

Dependency errors when installed with prefer-lowest

I am moving the hoaproject/Compiler#83 directly here to Hoa\Central since this apparently seems to be a huge issue across whole Hoa ecosystem where all dependencies are just ~1.0.


While attempting to run the suite locally with lowest dependencies (Composer's --prefer-lowest), it crashes right away:

$ vendor/bin/hoa test:run -a
PHP Deprecated:  The (unset) cast is deprecated in /tmp/Compiler/vendor/hoa/consistency/Prelude.php on line 73

Deprecated: The (unset) cast is deprecated in /tmp/Compiler/vendor/hoa/consistency/Prelude.php on line 73

Error: The (unset) cast is deprecated in /tmp/Compiler/vendor/hoa/test/.bootstrap.atoum.php at line 7
$ php -v | head -n 1
PHP 7.2.3 (cli) (built: Mar 12 2018 20:39:08) ( NTS )

When using Compiler as dependency and installing with --prefer-lowest, it produces lots of errors, regarding the deprecated cast, but also non-existent class Hoa\Iterator\Buffer. See Travis log here: https://travis-ci.org/schmittjoh/serializer/jobs/371673251#L580

Compiler must, as a library, require lowest versions of its dependencies in versions it works with.

Drop PHP 5.x

See #74 for more information.

Progression

Library PR Tests are green Merged
Acl
Bench
Cli
Compiler
Consistency
Console
Database
Devtools
Dispatcher
Dns
Event
Eventsource
Exception
Fastcgi
File
Graph
Heap
Http
Irc
Iterator
Json
Locale
Mail
Math
Mime
Option
Praspel
Promise
Protocol
Realdom
Regex
Registry
Router
Ruler
Session
Socket
Stream
Stringbuffer
Test
Ustring
View
Visitor
Websocket
Worker
Xml
Xyl
Zformat
Zombie

Badges font are broken

Hello,

Check https://camo.githubusercontent.com/694468544412beab895d5d982f31ff711a7ecf12/687474703a2f2f63656e7472616c2e686f612d70726f6a6563742e6e65742f53746174652f54657374 vs. http://central.hoa-project.net/State/Test. Same code but on githubusercontent.com the @font-face is broken on Firefox:

downloadable font: download not allowed (font-family: "Text" style:normal weight:normal stretch:normal src index:1): content blocked source: http://static.hoa-project.net/Font/DroidSansMono.woff

Our nginx configuration is:

add_header Access-Control-Allow-Origin *;
add_header Cache-Control public;

Do you have the same issue @hoaproject/hoackers?

Warning: fwrite() expects parameter 1 to be resource, boolean given in .../Hoa.central/Hoa/Core/Protocol.php on line 844

As I didn't found Embryo.git, I start a Hoa project from scratch. I didn't use the "whereishoa" command.

My first lines are:

<?php

define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__DIR__));

require ROOT.DS.'Hoa.central'.DS.'Hoa'.DS.'Core'.DS.'Core.php';


from('Hoa')
-> import('File.Write')
;

from('Hoathis')
-> import('Hero.Identity~')
-> import('Hero.Unit.Uuid')
;


event('hoa://Event/Exception')->attach(new Hoa\File\Write('hoa://Data/Variable/Exception.log'));

Then I throw an exception:

throw new \Hoa\Core\Exception('undefined "%s"', crc32(__METHOD__), [$name]);

But if I change 'hoa://Data/Variable/Exception.log' to 'Exception.log', it works.
Where I have to map 'how://Data/Variable' to a real path?
Perhaps; you should add a thrown exception if an unregistered stream is used?

Repo for contribution system provisioning

Hello Hoa community,

I've build a little Vagrantfile for Hoa, with php provisioned by Chef and box hosted in Vagrant Atlas built himself with Packer.
That should be great if we can centralise all community contribution like this in new repository can contain Packer, Vagrant, Chef, Docker...

What do you think ?

BTW, this is also useful to Hoa/Comte-Intatto , for run Hoa test with different version and system.

Drop HHVM support

After a long discussion about #36:

  1. atoum has dropped support for HHVM,
  2. No one has asked for HHVM support,
  3. HHVM does not support PHP 7.

Progression

  • Acl,
  • Compiler,
  • Consistency,
  • Console,
  • Database,
  • Dispatcher,
  • Event,
  • Exception,
  • Graph,
  • Iterator,
  • Json,
  • Locale,
  • Mail,
  • Math,
  • Mime,
  • Protocol,
  • Registry,
  • Ruler,
  • Socket,
  • Stream,
  • Ustring,
  • View,
  • Visitor,
  • Websocket,
  • Zombie.

Drop Hoa\Log

Hello @hoaproject/hoackers,

I would like to drop the hoa/log library because:

  • It is not complete,
  • It does not respect any PSR,
  • There is tons of great logs library out there,
  • This library does not bring anything relevant compared to the other ones.

As usual, the library will be marked as deprecated, the repository will be kept.

Thoughts?

Add Travis CI for all libraries

As discussed in the last Hoa Virtual Meeting (hoaproject/ActionBoard#26), we are going to move our CI to Travis.

Progression

  • Acl,
  • Compiler,
  • Consistency,
  • Console,
  • Database,
  • Dispatcher,
  • Event,
  • Exception,
  • Graph,
  • Http,
  • Iterator,
  • Json,
  • Locale,
  • Mail,
  • Math,
  • Mime,
  • Protocol,
  • Registry,
  • Ruler,
  • Socket,
  • Stream,
  • String,
  • Ustring,
  • View,
  • Visitor,
  • Websocket,
  • Zombie.

Blocking

Important but not blocking

Configure mirror on Gitlab

Create a mirror on gitlab

Add description and logo

Progressions

Compile API documentation examples in executable tests

Hello fellow @hoaproject/hoackers and users!

Introduction

This RFC aims at including the documentation of Hoa's libraries into the test quality process by having executable and testable examples. This is a sequel/extend to the RFC #58 which introduces a new API format. In particular, each method will have an API documentation written in markdown, with special sections, like Examples. In this section, we can have code blocks representing PHP code. The goal of this RFC is to define a process that: (i) extract the code from these API documentation, (ii) transform them into a unit or integration test, (iii) execute them.

The same process can be extended to RFC #51, where the Invalid examples and Valid examples Sections define the same kind of code blocks, with the same goal. The difference is that an invalid example is expected to fail, but the process is the same.

Extracting the code blocks

Based on the tools defined in the RFC #53, we will be able to:

  • Open a directory,
  • Iterate over PHP files,
  • Open each file,
  • Iterate over classes, chained with attributes and methods,
  • For each doc comment (/** … */), if the “Examples” Section is present, iterate over code blocks.

Now, a code block will has the following form:

\```[pl]?
c
\```

where c (body of the code block) is PHP code, and pl (programming language type of the code block, also called code block type) is php or none. If none, php will be the default.

Compiling to tests

The body of the code block will not use any test framework API, so no atoum or Hoa\Test API in our case. Why? Because this is documentation. Documentation has nothing to do with an API from our test framework. However, the documentation can contain assert intrinsics (also called Expectations). Example:

$x = 1;
$y = 2;
$z = new Sum();

assert(3 === $z($x, $y));

This example illustrates the usage of Sum, it shows also its result. The assert is here to illustrate the form of the results that Sum can produce. This way to write an example for the documentation provides all these benefits. I think this is adequate for this kind of documentation.

Since PHP 7.0, assert can take a second argument, called $exception, which is an instance of an exception of kind AssertionError. This exception will be thrown if the assertion fails. We can change the code to automatically add an exception as a second argument.

If we take our previous example, the code block will be compiled into:

public function case_methodName_example_1()
{
    $this
        ->when(function () {
            $x = 1;
            $y = 2;
            $z = new Sum();

            assert(3 === $z($x, $y), new AssertionError());
        });
}

Because the when pseudo-asserter has no specific meaning, we can create a new pseudo-asserter in Hoa\Test like: do, as an alias to when. Thus:

public function case_methodName_example_1()
{
    $this
        ->do(function () {
            $x = 1;
            $y = 2;
            $z = new Sum();

            assert(3 === $z($x, $y), new AssertionError());
        });
}

If the test is failing, atoum will catch that an unexpected exception has been thrown, and the test will fail.

This test case will belong to a specific test suite. The structure will be like this:

Xyz/
    Foo.php
    Test/
        Unit/
        Integration/
        Documentation/
            Foo.php

The Test/Documentation/Foo.php file will contain a test suite defined as:

namespace Hoa\Xyz\Test\Documentation;

use Hoa\Test;

class Foo extends Test\Documentation\Suite
{
    public function case_methodName_example_1()
    {
        // …
    }
}

where methodName is the name of the method whom API documentation is being tested.

Because the API documentation examples can be either a unit test or an integration test, a special Documentation namespace is created. It targets all the documentation tests.

Catching expected fail tests

This is possible that an example shows that an exception must be thrown. In this case, the test will fail while the example is valid. To avoid that, the following code block type must be used:

\```php,must_throw
c
\```

In this situation, the test case will compile to:

public function case_methodName_example_1()
{
    $this
        ->exception(function () {
            $x = 1;
            $y = 2;
            $z = new Sum();

            assert(3 === $z($x, $y), new AssertionError());
        })
            ->isInstanceOf(AssertionError::class);
}

Ignoring examples

To ignore an example, use the following code block type:

\```php,ignore
c
\```

Run tests

So far, tests are executed with the hoa test:run command. We also have hoa test:generate and hoa test:clean. These latters target Praspel, but we can re-use them to generate the documentation. We could select what kind of tests we would like to generate with an option, like hoa test:generate --documentation, or hoa test:generate --praspel for instance.

By default, hoa test:run will run hoa test:generate --documentation if no Documentation directory exists. The goal is to not modify the .travis.yml file to include these new tests.

In the contributor guide, we must stipulate that hoa test:generate --documentation must be run before hoa test:run when iterating on the code (edit, test, edit, test, edit, test…). Maybe we could introduce a cache invalidation system to re-generate only the specific documentation test suite. This should not be too much complicated.

Visually, there will be no difference between unit, integration or documentation test execution in the CLI report. Only the test suite namespaces will provide this information, like Hoa\Xyz\Test\Unit\Foo\Bar or Hoa\Xuz\Test\Documentation\Foo\Bar. Room for improvements in the CLI report to add a separator between “test namespaces” (between Unit, Integration etc.)?

Conclusion

I think with this approach we will be able to automatically test the API documentation examples. This will be a good win. With RFC #53 in mind, we will ensure that all examples will always be valid. This will improve the whole quality of the project. The test workflow will not be disturbed since hoa test:run will still control everything. The contributor workflow might change a little bit, but the impact is minimal compared to the guarantees it provides.

Thoughts?

Removing from/import

Hello :-),

As discussed during Apex'14, we are going to drop from/import. This construction is totally optionnal but it seems to be a “brake” for new incomers. Consequently, we are going to drop all of them.

Thoughts?

Provide Supported PHP-Versions in all composer.json files

Currently people wanting to use your libraries are forced to look up a secondary library (hoa/consistency) to figure out the officially supported version.
Adding the required php-version to the other libraries would provide an easier and quicker way to figure out if the given version is useable as intended.

This has pretty much the same reasoning as #33, since quite often the developers do not have complete control over the provided enviroment and this would speed up checking the requirements.

Better errors with codes and `hoa explain`

Hello fellow @hoaproject/hoackers and users!

As a direct or indirect user of Hoa, I want better errors than a simple exception backtrace. I want more context about errors.

Introduction

Rust and Elm errors are exemplaries. For instance in Rust:

error: `y` does not live long enough
  |
4 |     x = &y;
  |          - borrow occurs here
5 | }
  | ^ `y` dropped here while still borrowed
...
8 | }
  | - borrowed value needs to live until here

Or in Elm:

Cannot find variable `List.nap`.

6|    div [] (List.nap viewUser users)

`List` does not expose `nap`. Maybe you want one of the following?

    List.map
    List.any
    List.map2
    List.map3

All Rust errors are all listed online. Another interesting blog post from Elm: Compiler errors for humans.

We must provide a better mechanism to understand errors thrown by Hoa libraries. This RFC takes inspiration from the Rust and Elm languages.

Goals

Majority of the time spent on a new project consists of dealing with errors. This RFC will:

  • Improve the user experience by providing a description for each error, invalid examples, valid examples, and links to more resources,
  • Help us to visualise the amount of errors our libraries produce,
  • Help us to discuss about the meaning of errors (should we remove some of them, keep them, if yes why? Does it make sense?),
  • Being serious regarding errors,
  • Having error-based testing (™ 😉).

Context

So far, Hoa does not trigger any error. Only exceptions are thrown. Each exception is uniquely indexed per class (so 0, 1, 2, 3 for class C, 0, 1, 2, 3, 4, 5, 6 for class D etc). We might revise this indexing to have a similar mechanism to Rust's.

Index is stored in the $code attribute of the Exception class. The code is typed as mixed so we can store an integer, or a string in it.

Error format

By errors, we mean exceptions. An error code is defined by a specific format. In Rust, an error format has the following form: E[0-9]{4}. In our case, sure we will not reach the error number E9999, but we can apply a different format, like [A-Z]{3}[0-9]{3}, where the first letters represents the error prefix, i.e. the library identifier, and followed by the error index. For instance: ACL012 for Hoa\Acl, or RUL007 for Hoa\Ruler, or COM011 for Hoa\Compiler. Picking the first three letter of the library name is not enought to avoid conflicts, like Hoa\Event and Hoa\Eventsource that will collide (EVE in both case). So it can be totally arbitrary, we can take EVT for Hoa\Event and ESR for Hoa\Eventsource. This is a possibility. Or we can stick with E[0-9]{4} but we must set a lock on an error index in one library when creating a new error in another library to avoid having the same index twice (imagine I create 1 new error in Hoa\Acl and 1 new in Hoa\Bench, we need to “reserve” the new error index for one library to ensure the index is unique). Having the [A-Z]{3}[0-9]{3} format is simpler to manage for a library context.

We can use the $code attribute of the Exception class to store the [0-9]{3} part. The [A-Z]{3} might be a meta data attached to the library. Or the $code attribute can store the whole error code.

Explain

Given an error code, we can get more explanations about what leads to it, how to avoid it etc. The new hoa explain <error_code> command will show a comprehensive description about this particular error.

The description would include this:

  1. What the error means, in english, no code,
  2. An example of a bad code generating such an error (aka invalid example),
  3. An example of a good code (valid example),
  4. More links to online documentation (from hoa-project.net or php.net).

The format of the description will be markdown.

Example:

ACL012 Bad usage of the x argument of the f method

This error suggests that the value of x was not expected. f expects x to be an array but with some particular key/value pairs, bla bla.

Invalid example

For example, this following example is not invalid:

$acl = new Hoa\Acl\Acl();
$x   = …; // incorrect
$acl->f($x);

Valid example

This following example is valid:

$acl = new Hoa\Acl\Acl();
$x   = …; // incorrect
$acl->f($x);

Find more online at ….

The “Invalid example” and “Valid example” Sections must be strictly named like this. They act as “anchors” for error-based testing, see bellow. All sections can contain zero or more code blocks.

Error list

It will be easy to collect all errors, and publish them online. This will be a good resource for everyone, and it will publicly show we are serious regarding errors.

Error-based testing

Obviously, these error descriptions must be testable. We can extract the code from the examples, compile them to integration test cases, and then run them. All the example code blocks in the “Invalid example” Section are expected to fail. All the example code blocks in the “Valid example” Section are expected to succeed.

What command to run to test the errors? Maybe hoa test:run but it will need to scan, parse, compile, and execute error examples each time, a cache would be nice, not discussed here. Engineering issue.

Too much errors to manage?

If you think we have too much errors to manage, then this would be because we have too much errors at all. In this case, we must reduce the amount of errors a library can produce. If the number goes too high, it means we might be doing something wrong. This is a good probe.

Location of error descriptions

Just like we have Bin, Test, and Documentation at the root of each library, we can add Error, accessible through hoa://Library/<Name>/Error, but from my point of view, this must be considered as a documentation, so I would store all the error descriptions in Documentation/Error/, just like that:

Acl/
    Documentation/
        Error/
            Prefix.txt // contains `ACL` (the error prefix).
            ACL001.md
            ACL002.md
            ACL003.md
            …

Print exception message

When printing the exception message, instead of printing the exception index as usual, we print:

sprintf(
    '%s%03d',
    file_get_contents('hoa://Library/Acl/Documentation/Error/Prefix.txt'),
    $exception->getCode()
)

or, if we store the whole error code in Exception::$code, simply printing $exception->getCode(), not changes required.

Outro

What do you think? To be frank, majority of the time I spend on a new project is not coding but dealing with stupid errors. This mechanism will help a lot any new comers.

Thoughts?

Enhanced `README.md` files

Related to hoaproject/ActionBoard#17.

Hey :-),

Here the proposal (based on hoaproject/Ruler#58 and more). The README.md files are the homepages of libraries. So far, we have the following sections:

  • Abstract/short description
  • Installation (with a link to Rush),
  • Quick usage,
  • Awecode (if at least one exists),
  • Documentation,
  • License.

The proposals are the following:

  • Better documentation body, with a direct link to the hack book (even if not available/written yet?),
  • Links to “related projects”. Just like the Awecode section, it could be great to have a list of projects that use a specific library. For instance: Hoa\Ruler is used by RulerZ or ownCloud, Hoa\Dns is used by ec2dns. Also, these links should be added in the hack book chapters.

Why do I think “Related projects” is a good idea? Because it will create kind of a “Hoa network”, like the “trusters”. Also it will provide a better visibility, and most importantly: It provides examples of how to integrate this library into real “industrial products”.

Thoughts on these proposal?
Any other proposals?

/cc @hoaproject/hoackers

Progression

  • Acl,
  • Bench,
  • Cache,
  • Cli,
  • Compiler,
  • Consistency,
  • Console,
  • Core,
  • Database,
  • Devtools,
  • Dispatcher,
  • Dns,
  • Event,
  • Eventsource,
  • Exception,
  • Fastcgi,
  • File,
  • Graph,
  • Http,
  • Irc,
  • Iterator,
  • Json,
  • Locale,
  • Log,
  • Mail,
  • Math,
  • Memory,
  • Mime,
  • Model,
  • Notification,
  • Praspel,
  • Promise,
  • Protocol,
  • Prototype,
  • Realdom,
  • Regex,
  • Registry,
  • Router,
  • Ruler,
  • Serialize,
  • Session,
  • Socket,
  • Stream,
  • String,
  • Stringbuffer,
  • Test,
  • Translate,
  • Tree,
  • Ustring,
  • View,
  • Visitor,
  • Websocket,
  • Worker,
  • Xml,
  • Xmlrpc,
  • Xyl,
  • Zformat,
  • Zombie,
  • .

New library: Hoa\Devtools

Hello :-),

I propose a new library: Hoa\Devtools. Here is the POC. You can read the README.md, all the informations are written inside. The goal is to provide a set of development tools, for developers or maintainers, not for users.

Thoughts?

I am asking a review of all @hoaproject/hoackers :-).

New library: Hoa\Option

Hello @hoaproject/hoackers,

I am proposing a new RFC to introduce a new library, called Hoa\Option.

Introduction

The Option sum type is very powerful. In some languages, like Rust or Haskell, it replaces the null value, and thus it increases the safety of the language itself.

The definition of Option is the following:

enum Option<T> {
    Some(T),
    None
}

You must read it like: Either we have some value T, or we have nothing, aka null.

This new library will be very helpful if designed correctly. The PHP type system is yet poor and fragile, but we can still provide more safety with such a type. For instance, in the Hoa\Socket library, we have to deal with a lot of null value, in expected or unexpected locations. Having an Option in PHP 7 (so with declared types) would provide a better safety. How? First by having a real type forcing us to deal with unexpected situation, and second by automatically panicing/throwing a RuntimeException. It can be caught elegantly if it happens, unlike a null value that will just be silent until a bad usage of it.

The pros of an Option in PHP is the API it provides to deal with null value. Not only to replace null and is_null(), but to really chain operations on it without taking care if the value is null or not.

Design of the API

In PHP, we do not have the same expressiveness that we can have in Rust, Haskell, or Caml for instance. Nevertheless, we have powerful mechanisms like autoloaders, import etc., to have our own approach.

Having the value wrapped in a type (Option) and inaccessible from the outside will force us to write the code differently. We will no longer pass values directly, but we will extract them from the option before passing them to another function. So for instance, let's pretend f is a function that can return a nullable value, then this actual code:

$x = f();
$y = g($x);

could be rewritten as:

$x = f();

if ($x->isSome()) {
    $y = g($x->unwrap());
}

What to do if $x->isSome() is false? We should initialize $y to null? It sounds like we are postponing the problem. The Option::expect API is helpful in this particular case: Unwrap the value is some, else “panic” i.e. throw a RuntimeException for instance, thus:

$x = f();
$y = g($x->expect('Damn, x is null!'));

Write code differently

This library will definitively force us to write our code differently. We will use less variables, more edge cases/error cases will be handled correctly and very well identified.

Proposed API

I really like the API from Rust: std::option::Option:

  • isSome(): bool, check if there is some value,
  • isNone(): bool, check if there is none,
  • expect(string $message): mixed, unwrap the value if some, throw a RuntimeException exception with the message $message else,
  • unwrap(): mixed, return the value if some, throw a RuntimeException with a default message else,
  • unwrapOr(mixed $default): mixed, return the value if some, $default else,
  • unwrapOrElse(callable $default): mixed, return the value if some, or return the result from the callable $default else,
  • map(callable $mapper): Option, map the value into another Option with $mapper,
  • mapOr(callable $mapper, mixed $default): Option, map the value into another Option if some with $mapper, build a new Option with the value $default else,
  • mapOrElse(callable $mapper, callable $default): Option, same as before but the default value is returned from the $default function,
  • iterator(): Iterator, return an iterator over the value if some, panick else,
  • and(Option $operand): mixed, return $operand if $this is some, none else,
  • andThen(…), to be defined like flat, must be discussed,
  • or(Option $operand): mixed, return operand if $this or $operand is some, none else,
  • orElse(…), same as andThen(…).

Cloning

Whether Option will be clonable or not must be strictly defined.

Serializing

Whether Option will be serializable or not must strictly defined.

Iterating

It might be possible to iterate over a value. It will introduce a strong dependency to Hoa\Iterator. It would be possible to compute a simple \Iterator object, but we will loose some benefits when writing code (need to instanciate new Hoa\Iterator objects manually for instance, less clear code). Maybe we should do nothing for a first step.

Magic methods

__isset(): bool could be an alias to isSome(): bool.

Mutability

Option will be immutable. No possibility to get a mutable reference with the current API. Could be introduce later with smart mechanisms.

Instanciating

The most powerful API I have in mind yet is the following:

$x = Option::some($value);
$y = Option::none();

We can automatically import some and none as function alias to respectively Option::some and Option::none in the global scope, so:

$x = some($value);
$y = none();

Just writing none instead of none() implies that none is a constant, so all instances will be identical. Since an option is immutable, it can make sense. It will save some memory allocations, which will be good.

Nullable type

PHP has nullable type, like ?Foo, which means either the null value, or a value of kind Foo. This is somewhat similar to Option<Foo>, but with no API, except is_null(mixed $value): bool to see if $value is null or not, which is equivalent to Option::isSome(): bool. However, Option has a much richer API, with unwrap, and, or, except, map etc. This is “null with superpowers”. Unfortunately, ?Foo is a type, while Option<Foo> cannot be expressed in PHP yet, so we could not have such a type.

Concrete implementation

Not completely designed yet. First idea: Having an Option class, with 2 interfaces: None and Some. That would allow to write such code:

if ($x instanceof Some) {
    …
}

will be strictly equivalent to:

if ($x->isSome()) {
    …
}

Note we could not change the implemented interface on-the-fly, except with Reflection, but it comes with a cost. This might not be a good idea.

Second idea, just a single Option class, with the mentionned API. It must have as few attributes as possible to reduce the size of Option. This library will add a runtime cost, it must be as much insignificant as possible.

Conclusion

What do you think? I assume you will have a lot of questions about this RFC. I cannot address all of them ahead of time. I could add a FAQ, but I prefer to get fresh and unoriented feedbacks first. A FAQ can be added in the future.

Thanks!

Remove @author and what about @copyright attribution

Hello :-),

The @author tags are not up-to-date. I propose either to remove them or to replace the list of authors by Hoa community, which will be used in the @copyright. If we go in that direction, we have to clearly define what is the Hoa community from a juridic point of view, because it will also be used in the license. Example:

<?php

/**
 * Hoa
 *
 *
 * @license
 *
 * New BSD License
 *
 * Copyright © 2007-2014, Hoa community. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Hoa nor the names of its contributors may be
 *       used to endorse or promote products derived from this software without
 *       specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

namespace Hoa\…;

/**
 * Class \Hoa\….
 *
 * …
 *
 * @copyright  Copyright © 2007-2014 Hoa community.
 * @license    New BSD License
 */

We can replace Hoa community by Hoa.

In addition, we can provide a command hoa core:authors that will fetch the authors of the whole project, a library, a directory or a file (if Hoa has been installed through Git of course).

Thoughts?

Nucleus release issue

Hello :-),

We have a big issues with the not-finalized libraries. They are tagged as 0.*. We require ~0.0 in this case. This is wrong. Here is why.

Try this:

{
    "require": {
        "hoa/ruler": "~1.0"
    }
}

and then

$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing hoa/core (2.15.11.09)
    Loading from cache

  - Installing hoa/visitor (1.15.08.17)
    Loading from cache

  - Installing hoa/exception (1.16.01.11)
    Loading from cache

  - Installing hoa/consistency (1.16.01.11)
    Loading from cache

  - Installing hoa/event (1.16.01.11)
    Loading from cache

  - Installing hoa/protocol (1.16.01.11)
    Loading from cache

  - Installing hoa/stream (0.16.01.11)
    Loading from cache

  - Installing hoa/iterator (1.15.10.29)
    Loading from cache

  - Installing hoa/file (0.15.11.09)
    Loading from cache

  - Installing hoa/ustring (3.15.11.09)
    Loading from cache

  - Installing hoa/compiler (2.15.10.29)
    Loading from cache

  - Installing hoa/regex (0.15.08.13)
    Loading from cache

  - Installing hoa/math (0.15.10.26)
    Loading from cache

  - Installing hoa/ruler (1.15.11.09)
    Loading from cache

See what's wrong here? Because of hoa/stream in 0.…, it will load 0.16.01.11 and then hoa/consistency etc., and it will create a conflict with hoa/core.

To solve this, this is easy. Track all composer.json files with a ~0.0 dependency, and add this: ~0.0,<=0.15, it will work. However, I don't want to create another branch just for that, so here is my proposal:

  • Track all composer.json with ~0.0 dependencies,
  • Change them to ~0.15.0 or ~0.0,<=0.15,
  • Commit on master,
  • Release a new 0.15.12.31 snapshot,
  • Undo the change in composer.json and re-commit,
  • Maybe release a new snapshot, but it's not necessary.

What do you think @hoaproject/hoackers?

Online API browser

Hello fellow @hoaproject/hoackers and users!

I would like to have a nice online API browser for our libraries. Ready?

Intro

So far, we have tried http://api.hoa-project.net/, which is the result of Doxygen output.

Is it a solution we could maintain? Do we have better alternatives? What do you expect from an API browser?

Solutions for PHP

Personally, I don't like any of them.

Solutions in other languages

Build our own?

I really like the approach of rustdoc, the style, the fact that the code must be extremely documented, and the API is not the first-citizen. Look at Tagua VM, the https://tagua-vm.github.io/parser/ page represents the documentation of the tagua-parser library.

For each class, we have a long description. Then we have modules (namepaces in PHP) with a description.

For each function (for instance parse), we have a description, and an example. The API is even not documented. Well, this discussion is part of the RFC #58.

But the browsing experience is great.

Outro

All API documentation generator I tried in PHP didn't catch me. In other languages, like Rust or Elm, we have very nice ideas. We must get inspired from them.

I am not afraid of building a new tool. I personally thing this is the direction to take.

Thoughts?

Simplify getter naming, introduce data conversion naming

Hello fellow @hoaproject/hoackers and users!

In this RFC, I would like to simplify and standardize the API to get data.

Introduction

So far, we use this formalism: getFoo() to name a method that returns the value foo. This can be a direct attribute, or a computation. To get this data within another form, i.e. to convert this data into another type, we don't have any formalism yet. For instance, if foo is an array, and we would like to get it as a string, we will probably name a method like getFooAsString() but this is not deterministic.

Shorten getter methods

First proposal is to remove the get prefix for all getters. So getFoo() will be renamed like foo(). Real example:

$production->collection()->title();

instead of:

$production->getCollection()->getTitle();

The meaning is strictly the same, but I think the former is easier and shorter to read.

However, the setFoo() formalism for setters will remain. I would like to see set_foo() but it does not respect PSR, so let's not start a war 😉.

Conversions

I would like to introduce 3 method prefixes:

Prefix Cost Consumes convertee
as Free No
to Expensive No
into Variable Probably

Example:

  • Let's $x be a float. asInteger() will be (almost) free.
  • Let's $x be an array. toString() will be expensive because we have to iterate over the array, to allocate a string, and to convert every pairs in the array as a string (like a serializer).
  • Let's $x be an object. intoArray() will not be that expensive, it might reference all attributes into an array, so that's just one allocation.

Conversions prefixed as and into typically decrease abstraction, either exposing a view into the underlying representation (as) or deconstructing data into its underlying representation (into). Conversions prefixed to, on the other hand, typically stay at the same level of abstraction but do some work to change one representation into another.

Outro

This is not something we will use often, but it is important to have a strict naming here. Based on this naming, the user will be able to choose if the resulting data must be cached or not (for instance, all to conversions are likely to be cached because they might be expensive).

Thoughts?

steps for next version - bc break

Hello,
as discussed, we have several task to do for a next version:

  • increase minimal php version to php 7.1 (require #70)
  • introduce hoa\Option #56
  • fix for hoaproject/Protocol#22
  • update hoa/consistency first, then other libraries,
  • something else?

But two question:

  • increase php version for the pleasure is stupid, so only if there is a refactoring of the code, for me nothing should be done? which version php 7.0 or 7.1 ? for me it's not clear.
  • how does we introduce hoa/option in libs? for which purpose? does we create several task explaining for each libs the purpose?

no more gitter?

Hello,
it's seems that gitter/hoa/central is dead.

Is it normal?

It's inside all of our readme, so ?

Configure bors-ng for all projects

First allow the application in the settings

Add bors.toml with right configuration on all libraries listed below:

Pull request created

Pull Request merged

Enhanced Hoa\Iterator API

Hello fellow @hoaproject/hoackers and users!

This RFC aims at enhancing the Hoa\Iterator API.

Introduction

PHP has a lot of iterators, but the API for a daily usage is quite limited from my point of view. Other languages, like Rust, define nice and powerful API (see Trait std::iter::Iterator).

Goals

Let's start by an example:

$hasEven = false;

foreach ($data as $datum) {
    if (0 === $item % 2) {
        $hasEven = true;

        break;
    }
}

can be rewritten:

$hasEven = (new Hoa\Iterator\Map($data))->any(function ($item) { return 0 === $item % 2; })

With the PHP RFC about short function notation, we will have something like:

$hasEven = (new Hoa\Iterator\Map($data))->any($item => 0 === $item % 2);

The former is harder to read and to understand, and it is much more error-prone. Moreover, this is harder to chain with another operations, like a filter or a map just before having the any.

Goals are:

  1. Less error-prone,
  2. Easier to read and to write,
  3. Avoid iterator invalidations as most as possible,
  4. Allow safe iterator mutation if needed,
  5. Uniform and simple API to replace most of the (our) foreach loops,
  6. Better performances than foreach.

Vocabulary

This is important to agree on a vocabulary. An iterator iterates over a collection of items.

In the case of PHP, the items are heterogeneous, i.e. they can have different types. This is defined by the collection type.

Proposed API

Basis:

  • current(): Option<mixed> to get the current item (see #56 for Option),
  • key(): Option<int> to get the current key of the item (see #56 for Option),
  • next(): void to move the internal pointer to the next item,
  • rewind(): void to rewind the iterator,
  • valid(): bool to check if the current internal pointer is valid or not.

In a perfect world, next would be defined as next(): Option<mixed>, and thus valid could be dropped, but let's fit in the current PHP API.

More:

  • count(): int to count the number of items, iterates over all the collection if necessary, i.e. consumes the iterator if necessary,
  • last(): Option<mixed> to get the last item, consumes the iterator if necessary, restore the internal pointer,
  • nth(): Option<mixed>' to get the nth item, can be an alias to offsetGetbut it implies to implement theArrayAccessinterface, and thus to implementoffsetSet, offsetUnsetandoffsetIsset` methods, and we don't want them,
  • chain(Iterator): Iterator to append one iterator to another one, produce a new iterator (this is equivalent to Hoa\Iterator\Append),
  • zip(Iterator): Iterator to zip to iterators, produce a new iterator where items are a pair of item from both iterators (this is equivalent to Hoa\Iterator\Multiple); when either iterator reachs its end, it will stop,
  • map(Callable): Iterator to transform an iterator into another one, i.e. takes a callable and creates an iterator which calls that callable on each element,
  • filter(Callable): Iterator to produce another iterators with items satisfying the callable predicate,
  • peekable(): Iterator to get an iterator with the peek(): Option<mixed> method (this is equivalent to Hoa\Iterator\Lookahead),
  • buffer(int): Iterator to get an iterator with the previous method (this is equivalent to Hoa\Iterator\Buffer),
  • skipWhile(Callable): Iterator to skip all items that satisfy the predicate; once the predicate has returned false at least once, then all others items are yielded normally,
  • takeWhile(Callable): Iterator to yield all items that satisfy the predicate; once the predicate has returned false at least once, then all other items are ignored,
  • skip(int): Iterator to skip the first n items,
  • take(int): Iterator to take the first n items and ignored the others,
  • flatMap(Callable): Iterator not very clear yet (should we restrict it to some types? to flatten only on iterator),
  • inspect(Callable): Iterator works like tee,
  • collect(): Collection transforms an iterator into a collection,
  • partition(Callable): pair of Iterators partition an iterator into two iterators: The former where all items satisfy the callable, the second for the other items,
  • fold(mixed $init, Callable): mixed apply a callable on each item of the iterator and produce a single value, the accumulator is initialised to the value of $init,
  • all(Callable): bool check that all items match the predicate,
  • any(Callable): bool check that at least one item matches the predicate,
  • find(Callable): Option<mixed> search the first item matching the predicate,
  • position(Callable): Option<mixed> search the first item matching the predicate and returns in index,
  • rightPosition(Callable): Option<mixed> same as position but searches from the right (the end) of the iterator,
  • max(): Option<mixed> to get the maximum value of an iterator, will be based on the spaceship operator,
  • min(): Option<mixed> to get the minimum value of an iterator, same mechanism than max,
  • maxBy(Callable): Option<mixed> to get maximum value of an iterator based on the callable to compare two values, return the right most value in the collection in case of equality,
  • minBy(Callable): Option<mixed> same as maxBy but for the minimum value,
  • reverse(): Iterator reverse the iterator,
  • cloned(): Iterator create an iterator from an iterator where each item is cloned from the former,
  • cycle(): Iterator to repeat the same iterator again and again and again (this is equivalent to Hoa\Iterator\Infinite),
  • repeat(int): Iterator to repeat the same iterator n times (this is equivalent to Hoa\Iterator\Repeater),
  • sum(): int to sum all elements in an iterator, this is a shortcut to fold with a special callable, 0 if the collection is empty,
  • product(): int to multiply all elements in an iterator, this is a shortcut to fold with a special callable, 1 if the collection is empty,

Bounded vs. unbounded iterators

What to do if the iterator is unbounded?

Producer-consumer model

Put in other words, all the API is lazy. It means that:

$iterator->map(…)->filter(…)->collect();

Will not be equivalent to:

$mapped = $iterator->map(…);
$filtered = new Iterator\…($mapped)->filter(…);
$out = new Iterator\…($filtered)->collect();

But it will be much more like this:

foreach ($iterator as $item) {
    $mappedItem = $mapCallable($item);

    if (true !== $filterCallable($mappedItem)) {
        continue;
    }

    $out[] = $mappedItem;
}

So, when we describe the map API as map(Callable): Iterator, this is wrong. It would more accurate to describe it as map(Callable): Map, where Map is a special Iterator.

A nice effect is that:

$iterator->map(…)->filter(…);

will execute nothing. Why, Because map and filter are producers, not consumers. However, count, collect, fold etc. are consumers.

Another name for this pattern is the “adapter pattern”.

Outro

Most of the API can re-use the work we did with existing Hoa\Iterator classes. Most of them are extending PHP SPL. However, we can re-implement everything from scratch with generators, thanks to generator delegation. That's my strategy.

Thoughts?

Edits:

Error when installing hoa/ruler with the lowest dependancies

Following this issue of atoum's extension ruler-extension : atoum/ruler-extension#22

Let's install hoa/ruler in the 1.15.11.09 version :

composer require hoa/ruler:1.15.11.09

So we get this composer.json :

{
    "require": {
        "hoa/ruler": "1.15.11.09"
    }
}

If we use this test file :

<?php

include __DIR__ . '/vendor/autoload.php';


$hoa = new \Hoa\Ruler\Ruler();
$hoa->assert("true");

We have no error when executing it php test.php.

But if we install it with the minimum version of the dependancies with this command :

composer update --prefer-lowest

We get this error :

PHP Fatal error:  Uncaught Hoa\File\File::_open(): (1) Failed to open stream hoa://Library/Ruler/Grammar.pp.
in /home/agallou/tests/test-hoa-deps/vendor/hoa/file/Hoa/File/File.php at line 234.
  thrown in /home/agallou/tests/test-hoa-deps/vendor/hoa/file/Hoa/File/File.php on line 234

Here is the dependancies versions, on stable (the removed), and lowest (the installed) :

   composer update --prefer-lowest
   Loading composer repositories with package information
   Updating dependencies (including require-dev)
     - Removing hoa/ustring (3.15.11.09)
     - Removing hoa/core (2.15.11.09)
     - Installing hoa/core (2.14.09.17)
       Loading from cache

     - Removing hoa/visitor (1.15.08.17)
     - Installing hoa/visitor (1.14.11.15)
       Loading from cache

     - Removing hoa/iterator (1.15.10.29)
     - Installing hoa/iterator (1.14.11.07)
       Loading from cache

     - Installing hoa/string (2.14.09.16)
       Loading from cache

     - Removing hoa/regex (0.15.08.13)
     - Installing hoa/regex (0.14.11.25)
       Loading from cache

     - Removing hoa/compiler (2.15.10.29)
     - Installing hoa/compiler (2.14.11.26)
       Loading from cache

     - Removing hoa/math (0.15.10.26)
     - Installing hoa/math (0.14.11.09)
       Loading from cache

     - Removing hoa/stream (0.15.08.28)
     - Installing hoa/stream (0.14.09.17)
       Loading from cache

     - Removing hoa/file (0.15.11.09)
     - Installing hoa/file (0.14.11.09)
       Loading from cache

For the ruler exxtension, that means we have to add minimim versions on the hoa/ruler dependancies in the composer.json : atoum/ruler-extension#22. That should not be needed.

To check if this work, a matrix could be configured in the travis.yml like this : https://github.com/atoum/ruler-extension/pull/25/files.

tag release

Hi,

I'm using some parts of hoaprojects (thank you for your work it's very usefull). And I'm installing them with composer, it would be nice to tag a version of the project to be able to integrate it nicely with project with with minimum-stability=stable.
I saw this commit that fc2535c talks about release candidate, maybe it could be tag with something like 1.0.0-RC1 until a 1.0.0 stable can be added

API documentation v2

Hello fellow @hoaproject/hoackers and users!

Related RFC: #51, #52, and #53.

The API documentation is a mess, and useless. Not specifically in Hoa, but in the majority of PHP projects. Recently, I learned from Rust, Elm, Haskel, Caml… and they have a nice usage of it. I would like to change the way we write API documentation in Hoa.

Intro

What is “API documentation”? Basically everything written in the code. Not only the doc-comment on functions, classes, attributes, or methods, but everything.

I would like to define useful API documentation, which can be browsable nicely (see #53), that can be used to auto-check itself (see #52), and helpful.

Documentation format

First, let's start by defining the documentation format. HTML is awesome and would be the best, but it is hard to read in the code (HTML in comment of PHP, too much syntaxes). Moreover, we do not need particular semantics. So markdown is the format we will use. Of course, there are several versions of Markdown, so maybe we will choose CommonMark, don't know what is the best move here.

Elements of the documentation

<?php

/**
 * License code block
 */

namespace Foo\Bar;

/**
 * Class documentation
 */
class C
{
    /**
     * Attribute documentation
     */
    public $a;

    /**
     * Method documentation
     */
    public function f() { … }
}

/**
 * Function documentation
 */
function f() { … }

Class documentation

Explain what the class does, why it exists, how does it interact with others, examples, links to resources like RFC, online documentations, explain the design, explain the decision, explain the performance impact, design and decisions etc.

Provide at least one example about how to use it.

Attribute documentation

Explain what it holds, how it interacts with other, why it exists, design decision etc. If this is structural type, explain all its possible forms. Provide examples too.

Method and function documentations

Explain what the function does, why it exists, how does it interact with others, when should we call it, why, performance impact, design decisions etc.

Provide examples too, if possible for all of them.

Structure of a documentation element

A document element has different section in it, like:

/**
 * This is a complete description.
 * You have all these arguments. `$x` represents this, `$y` that etc.
 *
 * # My first section
 *
 * Hello, World!
 *
 * # Examples
 *
 * This example shows how this stuff works bla bla:
 *
 * ```
 * $x = 1;
 * $y = 2;
 * assert(3 == $x);
 * ```
 *
 * This is another example showing this and that:
 *
 * ```php
 * # use Vendor\Gordon;
 * use Foo\Bar;
 * 
 * ```
 *
 * # Exceptions
 *
 * In this particular circumstance, this method will throw the `E` exception.
 * Here is why, what does it mean and bla bla.
 *
 * # Contract
 *
 * ```praspel
 * @requires x: u8() and y: /fo+/;
 * @ensures \result: boolean();
 * @throwable …;
 * ```
 */
public function f(int $x, string $y): bool
{
    …
}

Special sections

There are special sections in this format:

  • Examples, provide a list of examples, where code blocks are real examples. The type of code block can be empty (3x), which will default to 3x + php, or any other types. See #52 for more details about this,
  • Exceptions, provide explanations and examples about what exceptions can be throw. Can be related to #51,
  • Contract, contain only one code block, if its type is praspel, then it will be used for Contract-based Testing, see Hoa\Praspel.

These sections are not mandatory!

assert in code blocks are related to #52.

No more PHPDoc?

Yes. Removed. We have types in PHP 7, we have meaningful argument names, PHPDoc is useless. The first part of a method documentation can explain what the argument does. More importantly, if this is not possible to understand what a method/function does just by reading its name and its argument names, then we have an issue.

Outro

I think this is a nice direction to go. It will be hard, but it will be good. This RFC is strongly related to RFC #51 RFC #52, and RFC #53.

Thoughts?

Happy new year!

Progression

  • Acl,
  • Bench,
  • Cache,
  • Cli,
  • Compiler,
  • Consistency,
  • Console,
  • Core,
  • Database,
  • Devtools,
  • Dispatcher,
  • Dns,
  • Event,
  • Eventsource,
  • Exception,
  • Fastcgi,
  • File,
  • Graph,
  • Http,
  • Irc,
  • Iterator,
  • Json,
  • Locale,
  • Log,
  • Mail,
  • Math,
  • Memory,
  • Mime,
  • Model,
  • Notification,
  • Praspel,
  • Promise,
  • Protocol,
  • Prototype,
  • Realdom,
  • Regex,
  • Registry,
  • Router,
  • Ruler,
  • Serialize,
  • Session,
  • Socket,
  • Stream,
  • String,
  • Stringbuffer,
  • Test,
  • Translate,
  • Tree,
  • Ustring,
  • View,
  • Visitor,
  • Websocket,
  • Worker,
  • Xml,
  • Xmlrpc,
  • Xyl,
  • Zformat,
  • Zombie,
  • .

Progression reviewed and merged

  • Acl,
  • Bench,
  • Cache,
  • Cli,
  • Compiler,
  • Consistency,
  • Console,
  • Core,
  • Database,
  • Devtools,
  • Dispatcher,
  • Dns,
  • Event,
  • Eventsource,
  • Exception,
  • Fastcgi,
  • File,
  • Graph,
  • Http,
  • Irc,
  • Iterator,
  • Json,
  • Locale,
  • Log,
  • Mail,
  • Math,
  • Memory,
  • Mime,
  • Model,
  • Notification,
  • Praspel,
  • Promise,
  • Protocol,
  • Prototype,
  • Realdom,
  • Regex,
  • Registry,
  • Router,
  • Ruler,
  • Serialize,
  • Session,
  • Socket,
  • Stream,
  • String,
  • Stringbuffer,
  • Test,
  • Translate,
  • Tree,
  • Ustring,
  • View,
  • Visitor,
  • Websocket,
  • Worker,
  • Xml,
  • Xmlrpc,
  • Xyl,
  • Zformat,
  • Zombie,
  • .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.