I have a Composer package which contains a test-suite.
The test-suite has some components that are only useful for testing, and these get autoloaded via require-dev to make sure you don't access them as a consumer of the package.
Now, it turns out, there are some other packages that need to use some of these components for their test-suites after all.
What I don't want to do, is simply make these components autoload by moving them from require-dev to require, because, again, these are components that we should only depend on for tests.
I also don't want to move these test-components to a separate package, as I want them versioned together with the package they belong to.
What I'd like to do is add a sub-package of some sort.
This would contain autoload configuration for these test-components, so that e.g. acme/foo includes a sub-package acme/foo-test that other packages (and the package itself) can explicitly add to their require-dev - making it possible to share these test-dependencies with other packages for testing only, e.g. without polluting the autoloader in production environments.
Is it possible for a package to define sub-packages that can then be installed from other packages?
Edit: I also don't want to use a "hack", like actually adding autoload rules to other packages like "Acme\\Foo\\Test\\": "vendor/acme/foo/src/Test". (Not even sure if that would work.)
Related
just starting to learn about Go Modules. I have a question on importing local packages inside the same module. The example I am looking at is this repo:
https://github.com/Azure/azure-service-bus-go
The module is module github.com/Azure/azure-service-bus-go. There is a separate package inside that module, atom (but it's not a module itself).
When files inside the main package import atom, they do it like this: import "github.com/Azure/azure-service-bus-go/atom" -- see queue_manager.go as an example.
What I do not quite understand -- how does GO know to look at the local atom package, as opposed to, say the one on Github? It seems confusing to me that something that is part of the module being modified is referenced by a remote/absolute URI. Is it guaranteed that if I modify the file on local disk and build I'm actually referencing the latest version as opposed to something already pushed?
As a toy exercise I tried to create a module with a non-existent Github URI and it did in fact appear that go mod tidy tried to look that up against Github, even though a local copy did in fact exist
A module is a collection of go packages.
A package is a directory of .go files. Using packages, you organize your
code into reusable units.
We can add a module to go project or upgrade the module version.
The module directive in the go.mod file declares the import-path prefix for all of the packages within that module.
If you are just starting to learn about Go modules, the
Create a Go module tutorial might be a good place to start.
When I use some package manager like Composer I want to use some 3rd-party module and to have an ability for example to change some views (templates) of this module, and simultaneously to have an ability to update this module trough composer.
How can I do this?
If not - may be it is question to think about to integrate to package managers some pattern to have an ability do this well ?
Pattern - I mean some rules with that programmers will be able to show some files that will be able to be edited by consumer and to do it, developer should do some api for it by some standartized method that will be written in rules, f.e. in some composer config of his module developer will write, what files should be duplicated to userpath. After install, these files will be copied and user will be able to change it, and composer will do it able modules to see these files in users folder. And after update this user folder will not rewrite these edited files... Something like that or maybe somehow more flexibly
How to modify views of packages installed by composer in Laravel:
https://laravel.com/docs/5.0/packages#views
Customized views should be placed in folder /resources/views/vendor/
with same names as original
This is the first place where views are searched by framework
So, I am setting up a new site and my project's folder structure looks like this now.
foo.com/
index.php
assets/
css/
img/
js/
vendor/
I have added vendor/ for js/css libraries that I must install to keep them separate, since I want anyone who installs my project to install those in vendor from package.json - most libraries contain too many files 99% which I don't want to push to production.
Now once the project is finished, I would like to push the code to production with only the necessary js/css files.
This is where the problem comes. For example, if I install bulma css using:
yarn add bulma --modules-folder ./assets/vendor
It will dump all bulma-related files which are almost 70 into /vendor/bulma/ but I will only be needing one or two css files afterwards, since I will compiles the sass file to css as:
sass vendors/bulmna/style.scss assets/css/style.css
So my questions is: I am assuming this is how every developer does it and there are no documentations I can find that suggest how to do it. Is it safe to ignore the /vendor directory? What if I install vue, font-awesome, bootstrap .. how can I only fetch the files I need but not everything in /vendors folder?
Your question is actually quite broad - however, I'll try to list as much as possible.
Lets say you're building a project from scratch and needed to include vuejs, jquery, fontawesome but only need to include a couple of files.
The issue you're hitting here is module dependency with respect to npm modules. (and there are many different tools that you can use to manage versions on your library dependencies as well as ensuring they are included into your project, i.e. package managers).
Ok - now from here, you may say to yourself
but I only need say, one icon from fontawesome in your final build (dist) and I don't want to commit all my modules into source control
Again, this is where you omit node_modules and other dependent libraries from source control (i.e. include node_modules your .gitignore)
To reiterate
You can install the required library,
add node_modules to .gitignore ,
bundle those libraries into a vendor single file to be consumed by your users (can be via browserify/webpack/rollup/gulp/grunt/yarn etc).
generate bundle within npm script
Now you may ask further -
Why would I use any of those tools? - they're distracting me from simply copy/pasting vendor libaries into my source control.
Build tools were created to
streamline the developer pipeline so that you DONT have to copy/paste vendor libaries into a vendor folder.
ensures that all files are bundled to the client automatically
allows you to keep track/restrict library version updates/ when required via package.json
allows you to add other build steps (such as minification, md5hash versioning, compression, code splitting, asset management to name a few).
Now lets break down the original question here:
How to ensure other developers get everything they need when cloning the repository
how do I ensure I can provide only the necessary files to the end user (if I only use specific parts of vendor libaries?)
1. How to ensure developers get what they need
Again, to reiterate above, adding devDependancies and .gitignoring allows you to only add the necessary files to your project.
2. How can I ensure clients get what they need without bloating request files?
This is where build tools such as webpack, browserify, gulp, grunt, rollup, attempt to achieve. This is because with some libraries that exceed in file size of 200kb minified, you may need to separate these files into different client requests (and as such, not demand the user to request one large file, which was symtomatic of browserify projects).
The second technique you will need to be aware of, is with specific libraries, you can use import mdn link where you can require one function/class from a dependant library (which further reduces file size).
Another technique is using less import statements (which can extract less functions/styles similar to above, but this isn't currently supported in SCSS). for SCSS, you're basically left with copy/pasting the necessary styles into your base scss and that'll save you space as well.
EDIT
How to create a bundle from npm install libaries
From the comments you've mentioned above (about not wanting to include a tool into your workflow, there's no point outlining any one particular strategy - you can find answers/tutorials online about how to setup gulp/browserify/webpack for your particular needs).
However, As you are currently using yarn - I'll go into details about that.
Firstly, yarn is a package manager (like npm). All it does with the --modules-folder is install the package into the specified folder, that's all. So we don't really care about that (since it's doing the same thing as npm). (i.e. your vendor folder is the same as node_modules in many respects).
We could use
webpack
gulp
grunt
rollup
browserify
brunch
(All build tools that essentially allow you to bundle all those packages into a single entry point to be packaged to the client).
I won't go into how, because that is a process you can find online, and from the above comments, I can tell you don't particularly care either.
What you are looking for is a zero-config javascript build tool. (Extremely out of the scope of your original question, and i'll only answer that in a separate Q&A).
I'd try Googling on "tree shaking CSS" to see if that gives you something.
Maybe something like: https://github.com/jacobp100/es-css-modules
Rollup plugin may be useful. It works for js, with postcss, the link says it works with css also.
https://code.lengstorf.com/learn-rollup-css
Have a look at Pancake. It has been built specifically for the purpose of moving only those files out of the node_modules folder that you need. I wrote an article about it here: https://medium.com/dailyjs/npm-and-the-front-end-950c79fc22ce
(probably not an answer but a good tip)
PS: I am the author of both, the article and the tool so with clear bias :)
I am making my own personal package to have collection of usefull programs and configs. Main idea is to emerge this package and have system prepared for my prefferencies. Mainly it works (it simply depends on all my favourite programs), but I have two problems here:
how to install USE flags, UNMASK and such before affected programs are installed?
how to uninstall it (emerge --unmerge does NOT delete files in /etc, so even after uninstalling the package the USE flags (and others) are still kept - my intent is to REMOVE them, so next rebuild of world would NOT use them anymore - yes it means a lot of programs would lose some functionalities like support for some languages, support for some other programs and so on, it is desired result)
My solutions so far are:
The package have some files in /etc/portage/package.*
1.1. I emerge that package with --nodeps (so the config files are installed)
1.2. I emerge it again without that flag (so dependencies are installed
with right configuration))
I create (and install) script to parse /var/db/packages for my package CONTENTS and delete all /etc/portage/something files "manually" and I have to rum this script before unmerging the package
Is there better way to do it ?
You just doing/understanding it wrong! (sorry :)
First of all, instead of a metapackage (an empty ebuild that have only runtime dependencies) there is other ways:
use sets to describe your preferred packages. Manage your USE flags in a usual way (including per package USE if needed).
medium complexity solution is to write a metapackage ebuild (your current case) -- but, you can't mask/unmask USE flags anyway…
if you already have your overlay (obviously) -- defining your own profile would solve everything! Here you can manage everything just like you want: mask/unmask any USE flags, define what is system predefined package means for you, & etc…
Unfortunately, I don't use Gentoo portage (and emerge) and have no idea if it's possible to have multiple additive profiles. I have my own profiles here and it works perfectly with Paludis.
Second, never remove any configuration files (config-protected) after uninstall! There is no packages that do that, and there is a bunch of reasons for that… The main one is that user may have them modified and don't want to loose his changes. Moreover, personally I prefer to have all configs that I've ever touched to be in a dedicated VCS repo -- it wouldn't be nice, if someone, except me, would remove smth…
Imagine a real life example: user wants to reinstall some package and he has a bunch of configuration files, he spent some time to carefully edit them. Trivial way is to uninstall and then install again -- Oops! He lost his configs!
Moreover, from ebuild's POV, you have pkg_prerm and pkg_postrm functions, but both of them are called even at upgrade time (i.e. when unmerge followed by immediate merge phase). You have to be really careful to distinct that use cases… And what is more scare, having any "hardcoded" (and unique) rules in any package, you don't have any influence on them…
So, please, never remove any config protected files, let the user to take care of them (he is the boss, not a package manager)…
Update: If you really want to be able to remove some config-protected files, setting up your own profile looks even more better idea. You can set CONFIG_PROTECT_MASK to enforce unprotect files and/or directories. In that way you don't need to modify any ebuilds and/or write an ugly cleanup code.
I have a composer project, call it MyVendor\Database. That project uses composer and autoloading. There are several files in that project that have:
require_once __DIR__."/../vendor/autoload.php";
in order to utilize autoloading.
It all works great, until I include MyVendor\Database in another project.
I have another project, call it MyVendor\CoolPackage that requires MyVendor\Database.
I run composer install on CoolPackage and it downloads MyVendor\Database into the vendor folder.
The problem from here though, is My files within vendor\MyVendor\Database fail because they call require_once __DIR__."/../vendor/autoload.php", but there is not vendor folder inside of \vendor\MyVendor\Database.
In your composer.json you define the autoloading scheme. For reasons you found out yourself now, it is not a good idea to call the Composer autoloading inside any of the files that are supposed to be autoloadable not only inside that application or module, but in any other application as well.
Basically, the files in any Composer project should be divided based on the definition of PSR-0 or 4 autoloading: They either ONLY do declaration of classes or functions WITHOUT any side effects (like executing code), or they execute code without defining classes or functions. Only the former files can be autoloaded (with the exception of functions, which would only be able to always be declared by loading the file containing them with a files autoload section), the latter should NOT be autoloaded.
And then it should become relatively easy: All the classes that can be autoloaded can also be used when this component is included in another application. Anything else that is not a class cannot directly be used.