Be lazy, build better systems
compile.com
compile.com
If your "configuration" is powerful enough to do everything you need then it's Turing-complete and is just "code" by another name. If it's not powerful enough then you'll need to drop down into the code layer pretty frequently anyway.
Create a component, then tell the framework how to instantiate it, then tell the framework to instantiate one and give it a name, then pass that name into anything that needs one.... blech.
The reasons you invent things to get rid of the crap work is so that you can do the work you really want to do. In my experience, people replace one pile of work with another and call it progress.
Only the rare few will automate the things they should, and truly live the freedom they have.
Somehow the right amount of configuration seems to save a lot of work as compared to conventions that fall just short of actual need.
I think there's a trap, though, that leads to the 'convention over configuration' one-size-fits-all road, and it's things that require loads of annoying, hard to manage, poorly structured configuration. (Things, like, for example, Apache, IMO.)
Though perhaps I'm just not good at determining when to write my own generators and when not to, I've also had Rails applications where I wrote a generic controller that covered a dozen-plus models and wondered why there couldn't have just been a generic controller built in to begin with (it's not like it'd preclude bumping things out of generic into their own controller if necessary).
I kind of wonder, too, if the evolution towards things like Docker/CoreOS with stuff like etcd from more traditional Linux distros and virtualization might also be viewable as a trend from convention towards a 'right amount' of configuration.
Just some off the cuff thoughts.
Two components are hardly coupled just because they happen to use the same library.
Copy & paste sounds bad but what it really says is: let's make that piece an invariant and don't import the library if you only need one short function.
So I would say the trade off boils down to "simplicity vs flexibility"
In my experience, it changes neither, because the interface of the library just doesn't change. Of course it depends where you make the separation. Basically, if the interface to your library is big, you either suck at API design, or you traced the wrong boundary.
Now if you happen to only need a small fraction of a sizeable library, I can only suspect the library itself fell prey to scope creep. If there's no way to import what you need, and little more, that probably indicates a problem with the library itself.
Even big libraries which by nature must make many different things can often be separated into different components. Like the SDL for instance.
---
Oh, and I was assuming we were talking about internal dependencies. Like, you write the library which will then be used in different parts of your (possibly big) project. That's very different from external dependencies, which are generally bigger, harder to freeze and harder to update.
I've learned to happily repeat code if it means making my programs/components more stateless, more decoupled or simpler to understand. There's nothing worse than trying to make sense of code where a programmer tried to shoehorn two similar but ultimately different concerns through the same code paths.
I'll also happily add complexity if it means reducing coupling and state and add coupling if it means being stateless. State is the ultimate enemy that makes code inflexible and buggy, especially when it's mutable state.