If I have a repository that contains multiple crates - let's say A and B, where A has a dependency on B - is it possible to publish A without also requiring B to be published? In particular, the A -> B dependency is specified using local path traversal:
[dependencies.B]
path = "libs/B"
If the answer is yes, then how so? If the answer is no, then are there best practices for how to separate out logic that belongs in a separate crate, but that you don't want published? Is there no other option than to use sub-modules inside the published crate?
It's a crate for querying system configuration information (think Unix's sysconf call, but cross-platform), but I've only bothered to implement the functionality that my main crate requires. I don't want to dirty up the crates.io namespace with a crappy crate that won't be helpful to other people, but I also don't want to take responsibility for maintaining it as a fully-fledged public-facing crate.
Also, I realized that what I said in the original post about being able to make it a module isn't actually true. I'm going to be adding another crate soon (that I do want to be public) that will depend on it. In other words, I've got crates A, B, and C, where I want A and C to be public - but not B - and A and C each have a dependency on B. Thus, the only way I can make B's logic not in its own crate is to duplicate the code and keep a copy in A and a copy in C.
Call it joshlf-hacky-sysconf-thing, note in the description it's unsupported, and call it a day. You only have as much responsibility for maintenance as you fell you do.
If A has unsupported dependencies I would consider A also unsupported.
For me you have two options:
Publish B but state in documentation that its scope is so far only this and that and it may be widened or replaced but help is needed
Get rid of dependency. Instead define in A and C traits that describe functionality they need. Make A and C generic over the traits. Implement the traits in B. Inject implementation from B into A and C in your main crate/application.
Which approach is better depends on your specifics, but with second one you can write unit tests for your high-level logic in A and C by mocking low-level B. With second approach users of A and C will be forced to provide their own implementation of querying system configuration.