Complex project setup with plugins and git submodules, need help building very specific output
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 139
Description
Hello everyone. I have some questions about getting my build to work the way I want. The issue appears fairly complex and I have been unable to receive any help from anywhere else. Please keep in mind that this project is over 10 years old and riddled with some bad design choices.
Let me explain.
### The App
```
MyApp/
├─ plugins/
│ └─ Directory.Build.props
├─ lib/
├─ src/
│ ├─ MyApp/
│ ├─ MyApp.Core/
│ ├─ MyApp.Register/
│ ├─ MyApp.View/
│ ├─ MyApp.UpdateManager/
│ └─ Directory.Build.props
├─ test
│ ├─ MyApp.*.UnitTests/
│ └─ Directory.Build.props
├─ Directory.Build.props
└─ MyApp.sln
```
Firstly I need to mention one extremely important point: **every sub-directory in `MyApp/plugins/` and `MyApp/lib/` is a `git` submodule**. This means that they all need to exist and require the ability to be built on their very own.
1. A connection to the parent `MyApp` repository or directory must still be given, because all of the plugins reference `MyApp.Core` and `MyApp.UpdateManager`. I was planning on handling this via a `Directory.Build.props` file in `MyApp/plugins/` which sets a property like `$(MyAppSrcDirectory)`.
2. `MyApp/src/MyApp/` must remain the startup project of the solution.
3. Building and running (I am willing to accept publishing here as well) `MyApp/src/MyApp/` must build the following projects as well (they are required for `MyApp` to run with all functionality):
- `MyApp/src/MyApp.Register`
- `MyApp/src/MyApp.UpdateManager` as `OutputType=WinExe` (it's `Library` by default, which is required for the other projects)
- all projects in `MyApp/plugins/`, placed in a `Plugins/` sub-directory in the output directory.
4. Duplicate assemblies which are already present in the output directory should be omitted from the `Plugins/` sub-directory.
### The Plugins
```
MyApp.SomePlugin/
├─ src/
│ └─ MyApp.SomePlugin/
├─ test
│ └─ MyApp.SomePlugin.UnitTests/
├─ Directory.Build.props
└─ MyApp.SomePlugin.sln
```
As mentioned, all plugins are `git` submodules. That means when only the plugin is cloned on its own, there must be a way to build it even then. A requirement for this, of course, is that `MyApp` must also be cloned, but this can be a shallow, non-recursive clone. When building the plugin, the user then merely passes the path to the required directories: `dotnet build -p:MyAppSrcDirectory=...`.
### Directory.Build.props
Since `Directory.Build.props` files help me apply a lot of properties all at once on relevant projects, I use them everywhere. That means I am also using them in the plugin projects. This obviously causes some problems:
1. If I can, I don't want to conditionally import a `Directory.Build.props` from the directory above in the plugins. The `Import` needs to be conditional, because the plugin may be cloned *not* as a submodule of `MyApp`, which means the `Directory.Build.props` file in a directory above would not exist.
I am currently doing this to include `MyApp/plugins/Directory.Build.props`, which sets the aforementioned `$(MyAppSrcDirectory)`, which is in turn used in the `ProjectReference`s of the plugins.
2. I set `UseArtifactsOutput` to `true` in all top-level `Directory.Build.props` files. I want the artifacts to be placed in the same directory for all projects, including the plugins. This is hindered because the plugins' top-level `Directory.Build.props` file overwrites the `ArtifactsPath` from `MyApp/Directory.Build.props`.
### MyApp.sln
This might be the most frustrating part. I personally work exclusively on the command line. But most users will want to clone the repository (recursively), open the solution file, press F6, and have a complete running app. This is difficult to fulfill due to the fairly complex output structure.
Additionally, the `MyApp/` solution file includes the plugin projects themselves as well, which probably causes issues when building the entire solution.
---
That's the gist of it.
I'm looking for some help on what I need to do to get this to work the way I need. I'm desperate at this point. Please ask any clarifying questions and I'll be happy to provide more information.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.