Packagit is amazing laravel modules management, you could manage huge project with many separate laravel modules.

Overview

Packagit

Packagit is amazing laravel modules management, you could manage huge project with many separate laravel modules.

You could run packagit or a short name p, such as p new Auth, a module named Auth would be created.

You can make artisan command running anywhere, All the packagit commands are same with artisan like following table.

artisan packagit
php artisan tinker p tinker
php artisan make:controller p make:controller
php artisan make:migration p make:migration
php artisan make:job p make:job
php artisan test p test
php artisan ... p ...

for example, you have a project named starter, directories layout:

starter
    └── modules
        ├── Auth
        ├── Components
        └── Wechat

change path to starter/modules/Auth, and run p make:controller:

cd starter/modules/Auth
p make:controller DemoController

DemoController.php would be created for Auth module.

modules/Auth/src/Http/
└── Controllers
   └── DemoController.php

change path to starter/app/Http/Controllers, and p make:controller:

cd starter/app/Http/Controllers
p make:controller DemoController

DemoController.php would be created for starter, because of current path doesn't include any module.

So when you run p make:xxx laravel command, packagit would scan the path, if current is in a module path, it will create for the module, otherwise for the project.

Installation

composer global require packagit/packagit

You MUST install packagit with global, and add composer bin to the $PATH environment.

Following command would help you find the global bin path:

composer global config bin-dir --absolute --global

# such as $HOME/.composer/vendor/bin, add to $PATH
# save to ~/.zshrc or ~/.bashrc
export PATH=$HOME/.composer/vendor/bin:$PATH

Usage

1. Custom package namespace (Optional)

run p custom

config/packagit.php file would be created, you could customize namespace by edit this file, skip here if you don't need custom.

2. Create a new module

run packagit new ModuleName

you also could group many modules as Components or others you want.

packagit new Components/NetUtil
packagit new Components/Updater
packagit new Components/Downloader

A Module Structure:

├── README.md
├── composer.json
├── config
│   └── config.php
├── database
│   ├── factories
│   ├── migrations
│   └── seeders
│       └── DatabaseSeeder.php
├── package.json
├── resources
├── routes
│   ├── api.php
│   └── web.php
├── src
│   ├── Models
│   └── Providers
│       ├── CommandServiceProvider.php
│       ├── RouteServiceProvider.php
│       └── ServiceProvider.php
├── tests
│   ├── Feature
│   └── Unit
└── webpack.mix.js

Load modules in project

1、composer require wikimedia/composer-merge-plugin

edit project/composer.json => extra => merge-plugins:

    "extra": {
        "merge-plugin": {
            "include": [
                "modules/*/composer.json",
                "modules/Components/*/composer.json"
            ],
            "recurse": false,
            "replace": true,
            "ignore-duplicates": false,
            "merge-dev": true,
            "merge-extra": true,
            "merge-extra-deep": true
        },
        "laravel": {
            "dont-discover": []
        }
    },

2、composer dump-autoload

3、edit project/config/app.php

    'providers' => [
        \Packagit\[MoudleName]\Providers\ServiceProvider::class, 
    ],

All done, modules should work well.

License

The Apache License 2. Please see License File for more information.

Comments
  • 服务提供者是否可以自动加载呢?

    服务提供者是否可以自动加载呢?

    开发完成了项目后,一般期望能使用 composer.jsonextra 配置,完成服务提供者的自动加载,并且期望能通过事件、数据的的方式完成插件的各方面管理。不希望改动到文件 app/config.php 与主项目的各项文件内容。

    这里之前的参考资料:

    注册模块的命名空间:https://gitee.com/fresns/plugin-manager/blob/master/src/Providers/PluginServiceProvider.php#L35-38

    注册每一个插件的命名空间、别名:https://gitee.com/fresns/plugin-manager/blob/master/src/Support/Plugin.php#L118-120

    opened by mouyong 4
  • 运行数据填充和模型工厂的时候报错..

    运行数据填充和模型工厂的时候报错..

    image
    p db:seed --class=ArticleSeeder
    Work Module: /modules/ArticleApi
    
       Error 
    
      Class "Database\Factories\App\Models\ArticleFactory" not found
    
      at /Users/chensuilong/Desktop/phpproject/laravel9xx/laravel9/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:770
        766▕     public static function factoryForModel(string $modelName)
        767▕     {
        768▕         $factory = static::resolveFactoryName($modelName);
        769▕ 
      ➜ 770▕         return $factory::new();
        771▕     }
        772▕ 
        773▕     /**
        774▕      * Specify the callback that should be invoked to guess factory names based on dynamic relationship names.
    
          +1 vendor frames 
      2   /Users/chensuilong/Desktop/phpproject/laravel9xx/laravel9/database/seeders/ArticleSeeder.php:28
          App\Models\Article::factory()
    
    

    参考教程 https://learnku.com/docs/laravel/9.x/database-testing/12261#defining-model-factories

    正常目录下摆放是可以运行成功的.... 用您的包以后似乎路径有些错误 无法运行数据填充~~

    望大佬测试一下 谢谢

    laravel9/modules/ArticleApi/database/factories/ArticleFactory.php

    <?php
    
    namespace ll\ArticleApi\Database\Factories;
    
    use Illuminate\Database\Eloquent\Factories\Factory;
    use ll\ArticleApi\Models\Article;
    
    class ArticleFactory extends Factory
    {
        protected $model = Article::class;
        public function definition()
        {
            return [
                'title' => $this->faker->title(),
                'content' => $this->faker->text(),
                'show' => 1,
            ];
        }
    }
    
    

    laravel9/modules/ArticleApi/database/seeders/ArticleSeeder.php

    <?php
    
    namespace ll\ArticleApi\Database\Seeders;
    
    use Illuminate\Database\Seeder;
    use ll\ArticleApi\Models\Article;
    use ll\ArticleApi\Models\Tag;
    
    class ArticleSeeder extends Seeder
    {
        /**
         * Run the database seeds.
         *
         * @return void
         */
        public function run()
        {
    
            Article::factory()
                ->count(10)
                ->has(Tag::factory()->count(3))
                ->create();
        }
    }
    
    

    laravel9/modules/ArticleApi/src/Models/Article.php

    <?php
    
    namespace ll\ArticleApi\Models;
    
    use Dcat\Admin\Traits\HasDateTimeFormatter;
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\SoftDeletes;
    use Illuminate\Database\Eloquent\Model;
    
    class Article extends Model
    {
        use HasFactory;
        use HasDateTimeFormatter;
        use SoftDeletes;
        protected $fillable = [
            'title', 'content', 'show',
        ];
        public function tags()
        {
            return $this->belongsToMany(Tag::class)->withTimestamps();
        }
    
    }
    
    
    

    laravel9/modules/ArticleApi/src/Models/Tag.php

    <?php
    
    namespace ll\ArticleApi\Models;
    
    
    use Dcat\Admin\Traits\HasDateTimeFormatter;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Tag extends Model
    {
        use HasFactory;
        use HasDateTimeFormatter;
        protected $fillable = ['name'];
    
        public function articles()
        {
            return $this->belongsToMany(Article::class);
        }
    }
    
    

    数据库迁移文件

    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    class CreateArticle extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            if (Schema::hasTable('articles')) {
                return true;
            }
            Schema::create('articles', function (Blueprint $table) {
                $table->id()->unsigned()->index();
    
    //            $table->foreignId ('user_id');
    
                $table->string('title', 200)->default('')->comment('文章标题');
    //            $table->string ('cover_url')->default ('')->comment ('文章封面图片');
    //            $table->string ('desc', 200)->default ('')->comment ('文章摘要');
                $table->string('tags', 255)->default('')->comment('文章标签');
                $table->mediumText('content')->comment('内容');
                $table->tinyInteger('show')->default(0)->comment('是否显示');
                $table->timestamps();
                $table->softDeletes();
            });
    
            Schema::create('tags', function (Blueprint $table) {
                $table->id()->unsigned()->index();
                $table->string('name');
                $table->timestamps();
            });
            Schema::create('article_tag', function (Blueprint $table) {
                $table->bigInteger('article_id')->unsigned()->index();
                $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');
    
                $table->bigInteger('tag_id')->unsigned()->index();
                $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
    
                $table->timestamps();
    
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('article_tag');
            Schema::dropIfExists('articles');
            Schema::dropIfExists('tags');
        }
    }
    
    
    
    enhancement 
    opened by duolabmeng6 3
  • Commands not finding current folder's module

    Commands not finding current folder's module

    When I am inside my module's folder, and run a command p make:controller it creates a controller under app/Http/Controllers rather than app\Jobs\src\Http\Controllers

    config.php

    <?php
    
    /**
     * DON'T CHANGE ANYTHING EXCEPT FOLLOWING
     *
     * 1. namespace
     * 2. composer.*
     *
     */
    return [
    
        // YOU COULD CUSTOM HERE
        'namespace' => 'Somecv',
    
        /*
        |--------------------------------------------------------------------------
        | Composer File Template
        |--------------------------------------------------------------------------
        |
        | YOU COULD CUSTOM HERE
        |
        */
        'composer'  => [
            'vendor' => 'somecv',
            'author' => [
                'name'  => 'Somecv',
                'email' => '[email protected]',
            ],
        ],
    
        'paths' => [
            'modules' => base_path('app'),
    
            /*
            |--------------------------------------------------------------------------
            | Modules assets path
            |--------------------------------------------------------------------------
            |
            | Here you may update the modules assets path.
            |
            */
    
            'assets' => public_path('modules'),
            /*
            |--------------------------------------------------------------------------
            | The migrations path
            |--------------------------------------------------------------------------
            |
            | Where you run 'module:publish-migration' command, where do you publish the
            | the migration files?
            |
            */
    
            'migration' => base_path('database/migrations'),
    
            /*
            |--------------------------------------------------------------------------
            | Generator path
            |--------------------------------------------------------------------------
            | Customise the paths where the folders will be generated.
            | Set the generate key to false to not generate that folder
            */
            'generator' => [
                'config'        => ['path' => 'config', 'generate' => true],
                'command'       => ['path' => 'src/Console', 'generate' => false],
                'migration'     => ['path' => 'database/migrations', 'generate' => true],
                'seeder'        => ['path' => 'database/seeders', 'generate' => true],
                'factory'       => ['path' => 'database/factories', 'generate' => true],
                'model'         => ['path' => 'src/Models', 'generate' => true],
                'routes'        => ['path' => 'routes', 'generate' => true],
                'controller'    => ['path' => 'src/Http/Controllers', 'generate' => false],
                'filter'        => ['path' => 'src/Http/Middleware', 'generate' => false],
                'request'       => ['path' => 'src/Http/Requests', 'generate' => false],
                'provider'      => ['path' => 'src/Providers', 'generate' => true],
                'assets'        => ['path' => 'resources/assets', 'generate' => true],
                'lang'          => ['path' => 'resources/lang', 'generate' => true],
                'views'         => ['path' => 'resources/views', 'generate' => true],
                'test'          => ['path' => 'tests/Unit', 'generate' => true],
                'test-feature'  => ['path' => 'tests/Feature', 'generate' => true],
                'repository'    => ['path' => 'src/Repositories', 'generate' => false],
                'event'         => ['path' => 'src/Events', 'generate' => false],
                'listener'      => ['path' => 'src/Listeners', 'generate' => false],
                'policies'      => ['path' => 'src/Policies', 'generate' => false],
                'rules'         => ['path' => 'src/Rules', 'generate' => false],
                'jobs'          => ['path' => 'src/Jobs', 'generate' => false],
                'emails'        => ['path' => 'src/Mail', 'generate' => false],
                'notifications' => ['path' => 'src/Notifications', 'generate' => false],
                'resource'      => ['path' => 'src/Http/Resources', 'generate' => false],
            ],
        ],
    
        /*
        |--------------------------------------------------------------------------
        | Module Stubs
        |--------------------------------------------------------------------------
        |
        | Default module stubs.
        |
        */
        'stubs' => [
            'path'         => dirname(__DIR__) . '/src/Commands/stubs',
            'files'        => [
                'routes/web'        => 'routes/web.php',
                'routes/api'        => 'routes/api.php',
                'views/index'       => 'resources/views/index.blade.php',
                'views/master'      => 'resources/views/layouts/master.blade.php',
                'scaffold/config'   => 'config/config.php',
                'scaffold/provider' => 'src/Providers/ServiceProvider.php',
                'seeder'            => 'database/seeders/DatabaseSeeder.php',
                'route-provider'    => 'src/Providers/RouteServiceProvider.php',
                'command-provider'  => 'src/Providers/CommandServiceProvider.php',
                'composer'          => 'composer.json',
                'assets/js/app'     => 'resources/assets/js/app.js',
                'assets/sass/app'   => 'resources/assets/sass/app.scss',
                'webpack'           => 'webpack.mix.js',
                'package'           => 'package.json',
                'readme'            => 'README.md'
            ],
            'replacements' => [
                'routes/web'        => ['LOWER_NAME', 'STUDLY_NAME'],
                'routes/api'        => ['LOWER_NAME'],
                'readme'            => ['LOWER_NAME', 'STUDLY_NAME'],
                'webpack'           => ['LOWER_NAME'],
                'views/index'       => ['LOWER_NAME'],
                'views/master'      => ['LOWER_NAME', 'STUDLY_NAME'],
                'scaffold/config'   => ['STUDLY_NAME'],
                'scaffold/provider' => ['NAMESPACE', 'LOWER_NAME'],
                'seeder'            => ['NAMESPACE'],
                'route-provider'    => ['NAMESPACE', 'STUDLY_NAME', 'MODULE_NAMESPACE'],
                'command-provider'  => ['NAMESPACE'],
                'composer'          => [
                    'LOWER_NAME',
                    'STUDLY_NAME',
                    'VENDOR',
                    'AUTHOR_NAME',
                    'AUTHOR_EMAIL',
                    'MODULE_NAMESPACE',
                    'PROVIDER_NAMESPACE',
                ],
            ],
            'gitkeep'      => true,
        ],
    
    ];
    
    opened by natecorkish 1
  • laravel9 bug

    laravel9 bug

    p custom                       
    
       Error 
    
      Class "Laravel\Package\Exceptions\FileAlreadyExistException" not found
    
      at /Users/chensuilong/.composer/vendor/packagit/packagit/src/Commands/CustomCommand.php:43
         39▕      */
         40▕     public function handle()
         41▕     {
         42▕         $to = config_path('packagit.php');
      ➜  43▕         throw_if(file_exists($to), new FileAlreadyExistException('config/packagit.php is already existing'));
         44▕ 
         45▕         $from = dirname(__DIR__, 2) . '/config/config.php';
         46▕         copy($from, $to);
         47▕         $this->line('Config file copied to  ['.$to.']');
    (base) 
    
    
    bug 
    opened by duolabmeng6 1
  • 执行流程应该调整下吧

    执行流程应该调整下吧

    1. p custom 生成自定义配置文件
    2. p new 生成模块

    同时 custom 的时候,应该就可以安装 wikimedia/composer-merge-plugin 同时配置 composer ; app.php 的 providers 在模块中,已经声明了,这里应该不需要再配置了吧。

    @zencodex

    opened by myxiaoao 1
  • laravel 9 p db:seed 执行失败~~

    laravel 9 p db:seed 执行失败~~

    image
     p db:seed
    Work Module: /modules/ArticleApi
    
       Illuminate\Contracts\Container\BindingResolutionException 
    
      Target class [Packagit\ArticleApi\Packagit\ArticleApi\Database\Seeders\DatabaseSeeder] does not exist.
    
    

    感觉是找错了路径...

    大佬的包挺好用的...我试着写控制器和路由没问题~~很舒服

    bug 
    opened by duolabmeng6 0
Releases(v1.0.8)
Owner
null
A lightway implementation of Laravel's belongs To many

A lightweigth implementation of Laravel's belongs To many relationship in cases you don't need pivot table.

Inani El Houssain 24 Nov 2, 2022
Reproduction of Belongs To Many Timestamp Isssue

Belongs to Many Issue This repository was created to demonstrate issue reported at: https://github.com/laravel/framework/issues/39727 The build fails,

William Lightning 1 Nov 23, 2021
Manage your staff from one place. Featuring Staff leave management 🏖, payslips 💵 generation & emailing, messaging 📨and more 🛠! Built with ❤️ with Laravel

Staff Management System This little buddy can help you manage your staff database! Built with ?? with Laravel #FEATURES 1 Staff management/ database S

Ezekiel Oladejo 45 Jan 3, 2023
Laravel Podcast is Laravel 5.5 web app that enables you to manage RSS feeds for your favorite podcasts and listen to the episodes in a seamless UI and User Authentication.

Laravel Podcast is Laravel 5.5 web app that enables you to manage RSS feeds for your favorite podcasts and listen to the episodes in a seamless UI and

Jeremy Kenedy 35 Dec 19, 2022
Laravel-OvalFi helps you Set up, test, and manage your OvalFi integration directly in your Laravel App.

OvalFi Laravel Package Laravel-OvalFi helps you Set up, test, and manage your OvalFi integration directly in your Laravel App. Installation You can in

Paul Adams 2 Sep 8, 2022
Migrator is a GUI migration manager for Laravel which you can create, manage and delete your migration.

Migrator Migrator is a GUI migration manager for Laravel which you can create, manage and delete your migration. Installation: To install Migrator you

Reza Amini 457 Jan 8, 2023
This Laravel Nova package allows you to manage media and media fields

Nova Media Hub This Laravel Nova package allows you to manage media and media fields. Requirements php: >=8.0 laravel/nova: ^4.0 Features Media Hub UI

outl1ne 25 Dec 22, 2022
Generates and handles Modules for Laravel

L5Modular Keep Your Laravel App Organized This package allows you to organize your Laravel project in a modular manner. You can simply drop or generat

Artem Schander 212 Jan 1, 2023
If you are beginner in WordPress plugin development or if you want to develop your own store product plugin you use this plugin

hirwa-products-plugin If you are beginner in WordPress plugin development or if you want to develop your own store product plugin you use this plugin

NIYIBIZI HIRWA 1 Aug 23, 2022
Laravel Restaurant Management System Project

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Benjdia Saad 8 Mar 26, 2022
undefined is an issue tracking product that allows agile project management.

undefined is an issue tracking product that allows agile project management. Our goal is to make work life simpler, more efficient and stress-free. In

Osvaldas Ulevičius 3 Jun 27, 2021
Listingslab Public CDN & Project Management

Listingslab Public CDN & Project Management pingpong ______ _ ____ | ___ (_)

@listingslab 4 Jan 2, 2022
GitScrum is a Project Management Tool, developed to help entrepreneurs, freelancers, managers, and teams Skyrocket their Productivity with the Agile methodology and Gamification.

What is GitScrum? GitScrum is a Project Management Tool, developed to help entrepreneurs, freelancers, managers, and teams Skyrocket their Productivit

GitScrum 2.8k Dec 29, 2022
This project is a room booking management system developed for Medianet.

This project is a room booking management system developed for Medianet. The purpose of this web app is to allow Medianet employees to easily check the availability and book one of the boxes for a meeting without overlapping with other employees.

louayjeddou 4 Sep 14, 2022
🏭This package lets you create factory classes for your Laravel project.

Laravel Factories Reloaded ?? This package generates class-based model factories, which you can use instead of the ones provided by Laravel. Laravel 8

Christoph Rumpel 372 Dec 27, 2022
Searches for multilingual phrases in Laravel project and automatically generates language files for you.

Laravel Lang Generator Searches for multilingual phrases in a Laravel project and automatically generates language files for you. You can search for n

Gleb 5 Oct 19, 2022
👀 Manage your views in Laravel projects through artisan

Artisan View This package adds a handful of view-related commands to Artisan in your Laravel project. Generate blade files that extend other views, sc

Sven Luijten 842 Dec 29, 2022
Manage self-hosted Google Fonts in Laravel apps

This package makes self-hosting Google Fonts as frictionless as possible for Laravel users. To load fonts in your application, register a Google Fonts embed URL and load it with the @googlefonts Blade directive.

Spatie 386 Dec 19, 2022
A simple package to manage the creation of a structure composed of the service and repository layers in a Laravel application

Chapolim Este projeto tem como objetivo fornecer alguns comandos adicionais à interface de linha de comando do Laravel, o Artisan, para manipular a es

Eliezer Alves 51 Dec 11, 2022