Skip to content

Commit

Permalink
Add a command to refresh the project autoloads
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenremot committed Apr 1, 2017
1 parent 414971d commit 3f13302
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 13 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Next

Features:

- Add the command `ede-php-autoload-reload-autoloads` to refresh the
composer autoloads when the composer configuration changed

Fixes:

- Always load the root project when visiting a third-party source
- Improve ecukes tests
- Improve ecukes tests reliability
6 changes: 6 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@
(add-hook 'php-mode-hook #'ede-php-autoload-mode)
#+END_SRC

* Commands

| Name | Description |
|-----------------------------------------+----------------------------------------------------------------|
| ~M-x ede-php-autoload-reload-autoloads~ | Similar to the reindexation in IDEs. Use it when your composer configuration changed to reload the autoloads. |

* License

This project is released under the GPL v3 license. See =GPL= for details.
45 changes: 33 additions & 12 deletions ede-php-autoload.el
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ intended to be a subproject, so this argument is ignored."
:safe-p t)
'unique))

(defun ede-php-autoload-reload-autoloads ()
"Reload the autoloads for the current projects.
This has the same goal than a reindexation in IDEs. Use this
method when your composer.json file changed, or your vendor
directory has been updated in order to take the new autoloads
into account."
(interactive)
(ede-php-autoload-reload-autoloads-for-project (ede-current-project)))

;;;;
;;;; Class loaders
;;;;
Expand Down Expand Up @@ -147,8 +157,7 @@ to the associated directories."
;;;###autoload
(defclass ede-php-autoload-project (ede-project eieio-instance-tracker)
((tracking-symbol :initform 'ede-php-autoload-project-list)
(class-loader :initarg :class-loader
:type ede-php-autoload-class-loader
(class-loader :type ede-php-autoload-class-loader
:documentation "The project's class loader.")
(include-path :initarg :include-path
:type list
Expand All @@ -157,21 +166,21 @@ to the associated directories."
(system-include-path :initarg :system-include-path
:type list
:initform ()
:documentation "The list of PHP include paths defined for the system.")))
:documentation "The list of PHP include paths defined for the system.")
(explicit-class-autoloads :initarg :explicit-class-autoloads
:type list
:documentation "The class autoloads explicitly defined at initialization")))

(defmethod initialize-instance ((this ede-php-autoload-project) &rest fields)
"Make sure the :file is fully expanded."
(let ((class-autoloads (plist-get (car fields) :class-autoloads)))
(call-next-method this (list
:file (plist-get (car fields) :file)
:explicit-class-autoloads (plist-get (car fields) :class-autoloads)
:include-path (plist-get (car fields) :include-path)
:system-include-path (plist-get (car fields) :system-include-path)))

(setq class-autoloads (ede-php-autoload--append-composer-autoload-data
(file-name-directory (plist-get (car fields) :file))
class-autoloads))
(ede-php-autoload-reload-autoloads-for-project this)

(call-next-method this (list
:file (plist-get (car fields) :file)
:class-loader (ede-php-autoload-create-class-loader class-autoloads)
:include-path (plist-get (car fields) :include-path)
:system-include-path (plist-get (car fields) :system-include-path))))
(let ((f (expand-file-name (oref this file))))
;; Remove any previous entries from the main list.
(let ((old (eieio-instance-tracker-find (file-name-directory f)
Expand All @@ -191,6 +200,18 @@ to the associated directories."
(unless (slot-boundp this 'targets)
(oset this :targets nil))))

(defmethod ede-php-autoload-reload-autoloads-for-project ((this ede-php-autoload-project))
"Regenerate the class loaders.
This can be used when some composer dependencies changed, to take
the new autoloads into account."
(oset this class-loader
(ede-php-autoload-create-class-loader
(ede-php-autoload--append-composer-autoload-data
(file-name-directory (ede-project-root-directory this))
(oref this explicit-class-autoloads))
)))

(defmethod ede-find-subproject-for-directory ((proj ede-php-autoload-project) dir)
"Return PROJ, for handling all subdirs below DIR."
proj)
Expand Down
7 changes: 7 additions & 0 deletions features/ede-php-autoload-composer.feature
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,10 @@ Feature: Composer EDE project creation
Scenario: Visit a vendor file
Given I visit "vendor/third-party/third-party/src/ThirdClass.php" in project "with-composer"
Then the class "Psr0Ns_TheClass" should be detected in "src/Psr0Ns/TheClass.php"

Scenario: Update the autoloads
Given I visit "src/main.php" in project "with-composer"
Then the class "NewNs\MyClass" should not be detected
Given I update the composer file
And I refresh the project autoloads
Then the class "NewNs\MyClass" should be detected in "src/NewNs/MyClass.php"
8 changes: 8 additions & 0 deletions features/step-definitions/ede-php-autoload-steps.el
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
(find-file (ede-php-autoload-test-get-project-file-path file-path project-name))
))

(Given "^I update the composer file"
(lambda ()
(ede-php-autoload-test-set-composer "new")))

(Given "^I refresh the project autoloads"
(lambda ()
(call-interactively #'ede-php-autoload-reload-autoloads)))

(Then "^ede-php-autoload-project should exist$"
(lambda ()
(should (ede-php-autoload-project-p (ede-current-project)))))
Expand Down
16 changes: 16 additions & 0 deletions features/support/env.el
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@
(or (buffer-file-name) default-directory)
ede-php-autoload-test-projects-root-path))))

(defun ede-php-autoload-test-set-composer (composer-file-name)
"Set the composer file of the project with-composer.
COMPOSER-FILE-NAME is either default or new."
(let* ((project-root (f-join ede-php-autoload-test-projects-root-path "with-composer"))
(destination (f-join project-root "composer.json")))

(when (f-exists? destination)
(f-delete destination))

(f-copy (f-join project-root (format "%s-composer.json" composer-file-name))
destination)))

(add-to-list 'load-path ede-php-autoload-root-path)

(package-generate-autoloads "ede-php-autoload" ede-php-autoload-root-path)
Expand All @@ -38,6 +51,9 @@

(Before
(setq ede-projects nil)

(ede-php-autoload-test-set-composer "default")

;; Define projects
;; The composer projet is auto-detected
(ede-php-autoload-project "Without composer"
Expand Down
25 changes: 25 additions & 0 deletions test/projects/with-composer/default-composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"autoload": {
"psr-0": {
"Psr0Ns": "src/",
"": "src/Fallback/Psr0"
},
"psr-4": {
"Psr4Ns": "src/Psr4Ns",
"MultiDirNs": ["src/MultiDirNs1", "src/MultiDirNs2"],
"": "src/Fallback/Psr4"
}
},
"autoload-dev": {
"psr-4": {
"AutoloadDev": "src/AutoloadDev"
}
},
"require": {
"third-party/third-party": "*",
"target-dir/target-dir": "*"
},
"require-dev": {
"third-party/dev-dependency": "*"
}
}
7 changes: 7 additions & 0 deletions test/projects/with-composer/new-composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"autoload": {
"psr-4": {
"NewNs": "src/NewNs"
}
}
}
7 changes: 7 additions & 0 deletions test/projects/with-composer/src/NewNs/MyClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace NewNs;

class MyClass {

}

0 comments on commit 3f13302

Please sign in to comment.