Dependency management in Magento with Composer



Dependency management in Magento with Composer

0 0


mage-day-2014-speech


On Github mmenozzi / mage-day-2014-speech

Dependency management in Magento with Composer

Manuele Menozzi Senior PHP Developer @ Webgriffe® Zend Certified PHP Engineer Proud GrUSP & PUG MoRe member Email: mmenozzi@webgriffe.com / Twitter: @mmenozzi

About Composer

Composer is a tool for dependency management in PHP. It allows you to declare the dependent libraries your project needs and it will install them in your project for you.

Composer è uno strumento a linea di comando per la gestione delle dipendenze in progetti PHP. È open-source, sviluppato in PHP ed è diventato, ormai da tempo, lo standard de-facto in questo ambito e, tra l’altro, è stato costruito prendendo spunto da strumenti simili sviluppati per altre tecnologie come Ruby, Java o Python.

What Composer does…

/composer.json

{
    "require": {
        "psr/log": "~1.0",
        "acme/foo": "*",
        "monolog/monolog": "dev-master#2eb0c09"
    },
    "require-dev": {
        "phpunit/phpunit": "~3.7.0"
    },
    "repositories": [
        {
            "type": "vcs",
            "url": "git@github.com:AcmeCompany/FooLibrary.git"
        },
    ]
}

$ composer install

Composer permette di definire in un file json (il composer.json) l'elenco dei pacchetti (librerie, moduli, eccetera…) da cui il nostro progetto dipende; per ogni pacchetto può essere specificato un vincolo di versione o di stabilità del pacchetto stesso. Lanciando poi un singolo comando, Composer utilizza questi metadati per scaricare ed installare per noi queste dipendenze all'interno del nostro progetto. L'aspetto interessante è proprio in queste ultime parole "nel nostro progetto", infatti Composer, sebbene abbia la modalità di funzionamento globale, agisce per progetto. Quindi su un secondo progetto avremo un altro composer.json file con diverse dipendenze che saranno specifiche per quel progetto. Altra cosa importante da tenere presente è che Composer, ci permette di installare non solo librerie pubbliche ma anche dipendenze non open-source che si trovano ad esempio su repository privati.

… and how

composer install

Available packages indexing Dependency tree and packages list calculation Packages list locking (composer.lock file) Packages download (in vendor folder) Custom installers Autoload dump Quando lanciamo l'installazione delle dipendenze, Composer indicizza, da uno speciale repository chiamato Packagist, più eventuali repository aggiuntivi definiti nell'apposita sezione del composer.json, i pacchetti disponibili, le loro versioni e le loro dipendenze. Dopodiché risolve l'albero delle dipendenze in maniera automatica definendo così un elenco di pacchetti da installare ognuno ad una specifica versione. Poi, questo elenco viene "lockato" nel file composer.lock per fare in modo che in futuro, per quel progetto, vengano sempre installate quelle dipendenze a quelle esatte versioni. I pacchetti vengono poi scaricati e i relativi file vengono salvati in una speciale cartella chiamata "vendor". Vengono poi cercati ed eseguiti eventuali custom installer che possono svolgere operazioni aggiuntive. Infine, Composer, genera per noi, in automatico, un unico autoloader che, se utilizzato, ci fa l'autoload di tutte le classi presenti nei pacchetti appena scaricati. Tutto questo in pochi secondi!

Benefits

  • Time save
  • Code reuse
  • Code sharing
  • Easy upgrades
  • Same code usage
I vantaggi portati dall’utilizzo di uno strumento di questo tipo sono svariati e vorrei citarne alcuni: Risparmio di tempo: innanzi tutto se dovessimo fare il lavoro appena descritto manualmente tutte le volte che ne abbiamo bisogno capiamo bene che il tempo che impiegheremmo sarebbe molto maggiore Ri-usabilità del codice: immagino che vi sarà capitato di dover utilizzare in un progetto Magento un modulo che avete già sviluppato e utilizzato per un altro progetto. In questo caso quello che possiamo fare, e quello che ci suggeriscono di fare decenni di storia di sviluppo software, è di isolare il suddetto modulo (banalmente, ad esempio, su un repository dedicato) e poi utilizzare Composer per installarlo facilmente in tutti i progetti che ne hanno bisogno. Oppure se nel nostro progetto ci serve un sistema di logging affidabile è inutile che ci scriviamo da zero l’ennesimo motore di logging! Ce ne sono già diversi e fatti molto bene quindi usiamoli. Con Composer è molto facile perché basta scegliere la libreria di logging che vogliamo utilizzare e aggiungerla alle dipendenze del nostro progetto. Condivisione del codice: se sviluppiamo una libreria o un modulo particolarmente utile e ri-usabile, rendendolo installabile con Composer possiamo facilmente fare in modo che altri lo utilizzino e lo migliorino ottenendo così tutti i vantaggio del software open-source. Aggiornamenti facili: se una delle librerie da cui il nostro progetto dipende ha rilasciato una nuova versione che ci farebbe dannatamente comodo nel nostro progetto possiamo con un singolo comando (composer update) aggiornare la libreria. Il team utilizza lo stesso codice: seguendo la buona pratica di mettere sotto controllo di versione i file composer.json e composer.lock ci assicuriamo che tutto il team di sviluppo abbia esattamente le stesse dipendenze alla stesse versioni e quindi un ambiente allineato.

Composer & Magento

The problem…

Composer

./
├── htdocs/
└── vendor/
    ├── vendor-name-1/
    │   ├── package-1/
    │   ├── package-2/
    │   └── package-n/
    ├── vendor-name-2/
    └── vendor-name-n/

Magento

./
├── app/
│   ├── code/
│   │   ├── community/
│   │   └── local/
│   ├── design/
│   └── etc/
│       └── modules/
└── skin/
Ok. Diciamo che siamo convinti e che vogliamo utilizzare Composer per installare moduli e librerie sui nostri progetti Magento. Così a prima vista sembra esserci un problema... Come detto prima Composer mette ogni dipendenza in una singola cartella dedicata, all'interno della cartella speciale “vendor"; mentre noi sappiamo che i moduli Magento hanno una struttura più complessa su file system. Ad esempio il file di config del modulo va in app/etc/modules, il codice va in app/code/local o app/code/community, i template in app/design, gli asset come css e immagini vanno in skin, eccetera. Come possiamo risolvere questo problema e utilizzare Composer per gestire le dipendenze (quindi i moduli) sui nostri progetti Magento?

Composer & Magento

The solution

Available packages indexing Dependency tree and packages list calculation Packages list locking (composer.lock file) Packages download (in vendor folder) Custom installers Autoload dump Se Riguardiamo un momento cosa fa Composer quando installa le dipendenze potremo notare che subito dopo il download dei file vengono eseguiti i Custom Installer. Come abbiamo detto prima i Custom Installer servono per eseguire operazioni aggiuntive dopo il download delle dipendenze e sembrano proprio fare al caso nostro. Infatti, è proprio grazie ad un particolare custom installer sviluppato dalla community che possiamo facilmente risolvere il problema e usare Composer sui nostri progetti Magento.

Magento Composer Installer

by Magento Hackathon

github.com/magento-hackathon/magento-composer-installer

Il particolare Custom Installer di cui stiamo parlando si chiama “Magento Composer Installer” ed è un progetto nato dalla community durante uno dei Magento Worldwide Hackathon. Il progetto è stato poi ampliato e sviluppato e oggi viene ampiamente utilizzato. Questo installer consente l’installazione di moduli Magento attraverso Composer andando a creare dei link simbolici o delle copie dei file all’interno dell’alberatura di cartelle di Magento.

Magento Composer Installer

Install a module in your project

./composer.json

{
    "require": {
        "foo/bar-module": "*",
        "magento-hackathon/magento-composer-installer": "*"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "http://packages.firegento.com"
        }
    ],
    "extra":{
        "magento-root-dir": "htdocs/"
    }
}

$ composer install

Dunque se vogliamo installare un modulo, con Composer, all’interno del nostro progetto Magento basterà creare (se non esiste già) un file composer.json come quello mostrato. Sostanzialmente dobbiamo indicare tra le dipendenze Magento Composer Installer (magento-hackathon/magento-composer-installer) e il modulo che vogliamo installare (foo/bar-module). Poi dobbiamo indicare tra i repository quello ufficiale di Magento Composer Installer (che è packages.firegento.com) e tra i parametri extra la directory in cui si trova la root di Magento (magento-root-dir). Dando poi il comando composer install, Composer eseguirà il processo di installazione che abbiamo visto prima e, quando arriverà ad eseguire i custom installer, eseguirà il Magento Composer Installer che, a sua volta, andrà a creare i link simbolici dei file e delle cartelle del modulo Foo Bar all’interno delle cartelle di Magento.

Magento Composer Installer

Files mapping

There are several ways how the mapping from files in the package into the Magento source is accomplished:

A mapping in the composer.json The MagentoConnect package.xml file The modman file (see github.com/colinmollenhour/modman) Le informazioni di mapping su dove i file del modulo devono essere “symlinkati” all’interno di Magento vengono lette dal pacchetto stesso (in questo caso Foo Bar). Ci sono diversi modi in cui i moduli installabili con Composer possono definire questo mapping. Il primo è inserirle nei parametri extra di Composer all’interno del composer.json. Il secondo è quello di usare il file package.xml dei pacchetti di MagentoConnect. Il terzo è quello di utilizzare il file di mapping di un tool chiamato modman. Se Magento Composer Installer trova i dati di uno qualsiasi di questi metodi di mapping li utilizza per creare i relativi symlink all’interno di Magento.

Magento Composer Installer

Install a MagentoConnect module

http://packages.firegento.com/

{
    "require": {
        "connect20/locale_mage_community_it_it": "*"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "http://packages.firegento.com"
        }
    ]
}
Magento Composer Installer risulta molto utile anche per installare i moduli di MagentoConnect. Infatti su packages.firegento.com sono presenti, tra gli altri, tutti i moduli gratuiti che troviamo su MagentoConnect. Basta cercarli per avere la chiave che va inserita nel composer.json. Dopodiché basterà lanciare il composer install e avremo il modulo installato. Ad esempio per installare la localizzazione italiana basterà aggiungere la relativa chiave nei require e Composer installerà il modulo per noi.

Magento Composer Installer

Install the Magento-Core and initialize your project

Package magento/core on packages.firegento.com ./composer.json
{
    "require": {
        "magento/core": "1.9.0.1"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "http://packages.firegento.com"
        }
    ],
    "extra":{
        "magento-root-dir": "htdocs/"
    }
}

Only 1.9.0.1 avaliable... :(

Se vogliamo creare il nostro progetto da zero ed installare con Composer il core di Magento stesso trattandolo come dipendenza esterna, con Magento Composer Installer possiamo farlo. Infatti, creando un composer.json file come quello mostrato in cui mettiamo tra le dipendenze il pacchetto "magento/core" otterremo proprio questo risultato. Anche in questo caso è importante inserire tra i repository packages.firegento.com perché il pacchetto "magento/core" si trova li. Dando poi il solito comando "composer install" il core di Magento alla versione 1.9.0.1 verrà installato nella cartella specificata dall'opzione magento-root-dir. Unico aspetto negativo è che il pacchetto magento/core, al momento, prevede solo la versione 1.9.0.1 di Magento e non le precedenti.

Magento Composer Installer

Make a module installable with Composer

./composer.json (important: "type": "magento-module")
{
    "name": "acme-company/module-name",
    "type": "magento-module",
    "license":"OSL-3.0",
    "description":"A short one line description of your module",
    "repositories": [
        {
            "type": "vcs",
            "url": "your/github/or/git/or/svn/etc/repository/uri"
        }
    ],
}
Se sviluppate moduli su repository separati vi interesserà sicuramente sapere come renderli installabili con Composer per utilizzarli facilmente come dipendenze nei vari progetti. È molto semplice, basta aggiungere un file composer.json, analogo a quello mostrato, nella root del repository. La parte importante è la chiave “type” che va valorizzata con “magento-module” perché Magento Composer Installer si aggancia solo ai pacchetti di tipo “magento-module” appunto.

Magento Composer Installer

Make a module installable with Composer

Files mapping (modman example)

./modman
src                            app/code/local/AcmeCompany/ModuleName
etc/AcmeCompany_ModuleName.xml app/etc/modules/
locale/it_IT/*                 app/locale/it_IT/

See github.com/colinmollenhour/modman for further info.

Basterà poi aggiungere al nostro modulo le informazioni di mapping dei file. Ad esempio possiamo farlo con il file “modman” che va messo anch'esso nella root del progetto. Come detto prima sono disponibili anche altri 2 metodi di mapping. Sostanzialmente, nel file “modman”, bisogna inserire a sinistra il percorso dei file/cartelle del repository del modulo e a destra la relativa destinazione nell’alberatura di Magento. Questo sarà il mapping che Magento Composer Installer utilizzerà nel creare i symlink.

Magento Composer Installer

Useful extras…

  • Deploy strategy (magento-deploystrategy)
  • Auto append to gitignore (auto-append-gitignore)
  • Mapping overwrite (magento-map-overwrite)

Joind.in

joind.in/talk/view/12698

Any Question?

Webgriffe

Tailored Digital Works webgriffe.com | @webgriffe

  • 5+ Years of Experience with Magento
  • 5 Certified Developers (Zend & Magento)
  • 350+ Customers
  • 20+ Magento Extensions
  • 450+ Extensions Sold

Thank you!