{"action":"created","issue":{"url":"https://api.github.com/repos/cakephp/migrations/issues/97","labels_url":"https://api.github.com/repos/cakephp/migrations/issues/97/labels{/name}","comments_url":"https://api.github.com/repos/cakephp/migrations/issues/97/comments","events_url":"https://api.github.com/repos/cakephp/migrations/issues/97/events","html_url":"https://github.com/cakephp/migrations/pull/97","id":94468729,"number":97,"title":"Implements a way to run Migrations in a non-shell environment","user":{"login":"HavokInspiration","id":5243386,"avatar_url":"https://avatars.githubusercontent.com/u/5243386?v=3","gravatar_id":"","url":"https://api.github.com/users/HavokInspiration","html_url":"https://github.com/HavokInspiration","followers_url":"https://api.github.com/users/HavokInspiration/followers","following_url":"https://api.github.com/users/HavokInspiration/following{/other_user}","gists_url":"https://api.github.com/users/HavokInspiration/gists{/gist_id}","starred_url":"https://api.github.com/users/HavokInspiration/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HavokInspiration/subscriptions","organizations_url":"https://api.github.com/users/HavokInspiration/orgs","repos_url":"https://api.github.com/users/HavokInspiration/repos","events_url":"https://api.github.com/users/HavokInspiration/events{/privacy}","received_events_url":"https://api.github.com/users/HavokInspiration/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/cakephp/migrations/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/cakephp/migrations/milestones/7","html_url":"https://github.com/cakephp/migrations/milestones/1.2","labels_url":"https://api.github.com/repos/cakephp/migrations/milestones/7/labels","id":1203354,"number":7,"title":"1.2","description":null,"creator":{"login":"HavokInspiration","id":5243386,"avatar_url":"https://avatars.githubusercontent.com/u/5243386?v=3","gravatar_id":"","url":"https://api.github.com/users/HavokInspiration","html_url":"https://github.com/HavokInspiration","followers_url":"https://api.github.com/users/HavokInspiration/followers","following_url":"https://api.github.com/users/HavokInspiration/following{/other_user}","gists_url":"https://api.github.com/users/HavokInspiration/gists{/gist_id}","starred_url":"https://api.github.com/users/HavokInspiration/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HavokInspiration/subscriptions","organizations_url":"https://api.github.com/users/HavokInspiration/orgs","repos_url":"https://api.github.com/users/HavokInspiration/repos","events_url":"https://api.github.com/users/HavokInspiration/events{/privacy}","received_events_url":"https://api.github.com/users/HavokInspiration/received_events","type":"User","site_admin":false},"open_issues":1,"closed_issues":1,"state":"open","created_at":"2015-07-11T12:28:17Z","updated_at":"2015-07-30T20:12:27Z","due_on":null,"closed_at":null},"comments":7,"created_at":"2015-07-11T12:23:02Z","updated_at":"2015-07-30T20:14:38Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/cakephp/migrations/pulls/97","html_url":"https://github.com/cakephp/migrations/pull/97","diff_url":"https://github.com/cakephp/migrations/pull/97.diff","patch_url":"https://github.com/cakephp/migrations/pull/97.patch"},"body":"This PR aims to give the ability to run Migrations in a non-shell environment.\r\nIt implements a new ``Migrations`` class that exposes three main methods : ``status``, ``migrate`` and ``rollback``.\r\n\r\nThe constructor accepts an array that will allow users to define default options to run with the methods. The expected and allowed values are the one that are common between each command : \r\n```\r\n     * - `connection` The datasource connection to use\r\n     * - `source` The folder where migrations are in\r\n     * - `plugin` The plugin containing the migrations\r\n```\r\n\r\nSo this can be done :\r\n\r\n```php\r\n        $migrations = new Migrations([\r\n            'connection' => 'customConnection',\r\n            'source' => 'MyCustomDir'\r\n        ]);\r\n        \r\n        // Returns an array with all migrations and their status\r\n        $status = $migrations->status();\r\n\r\n        // Returns a bool\r\n        $migrate = $migrations->migrate();\r\n        \r\n        // If migrate is false, use the getLastError() method to get the exception message\r\n        // that was raised\r\n        $error = $migrations->getLastError();\r\n```\r\n\r\nAs you can see, I don't have to pass the options array for each method. They can be overridden as well by using the $options parameter for each method :\r\n\r\n```php\r\n// Returns an array with all migrations and their status\r\n$status = $migrations->status(['connection' => 'default']);\r\n```\r\n\r\nIn order to implement this, I had to create a ``CakeManager`` class that overrides phinx's ``Manager`` class. This was needed to separate logic and output for the ``status`` command.\r\nI also fixed a wrong behavior of the ``status`` command : if you run it with the ``format`` option set to ``json``, it will now only returns a JSON response.\r\n\r\n**Possible issues :**\r\n- if there is no migrations to run, the ``migrate()`` method will return ``true`` anyway. Same applies to ``rollback()``. Generally speaking, ``migrate()`` and ``rollback()`` will return ``false`` only if an exception is thrown while running the command.\r\n- I did not implement the ``MarkMigrated`` and ``Create`` commands. I could see some value for ``MarkMigrated`` but none with ``Create``. I'm waiting for feedback on this one.\r\n- tests might be failing, I was only able to partly run them with MySQL on my dev setup\r\n\r\n**Possible improvements :**\r\n- have the ``migrate()`` and ``rollback()`` method to return what migrations were migrated and rollbacked. This might need some tuning with the ``CakeManager`` to have something similar ``status()`` (split logic and output). I did not try it but I think this might be doable.\r\n\r\nDocs will come up when everything will be settled and the implementation confirmed.\r\n\r\nRefs #37 "},"comment":{"url":"https://api.github.com/repos/cakephp/migrations/issues/comments/126468356","html_url":"https://github.com/cakephp/migrations/pull/97#issuecomment-126468356","issue_url":"https://api.github.com/repos/cakephp/migrations/issues/97","id":126468356,"user":{"login":"lorenzo","id":37621,"avatar_url":"https://avatars.githubusercontent.com/u/37621?v=3","gravatar_id":"","url":"https://api.github.com/users/lorenzo","html_url":"https://github.com/lorenzo","followers_url":"https://api.github.com/users/lorenzo/followers","following_url":"https://api.github.com/users/lorenzo/following{/other_user}","gists_url":"https://api.github.com/users/lorenzo/gists{/gist_id}","starred_url":"https://api.github.com/users/lorenzo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lorenzo/subscriptions","organizations_url":"https://api.github.com/users/lorenzo/orgs","repos_url":"https://api.github.com/users/lorenzo/repos","events_url":"https://api.github.com/users/lorenzo/events{/privacy}","received_events_url":"https://api.github.com/users/lorenzo/received_events","type":"User","site_admin":false},"created_at":"2015-07-30T20:14:38Z","updated_at":"2015-07-30T20:14:38Z","body":"@HavokInspiration out of curiosity, what was the difference between the 2 exceptions?"}}