Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for shared definitions #36

Closed
lukespice opened this issue Feb 10, 2022 · 3 comments
Closed

Support for shared definitions #36

lukespice opened this issue Feb 10, 2022 · 3 comments

Comments

@lukespice
Copy link

We use multiple git repositories for distinct services / functions in the same domain. Do you have any ideas for how we could share the definitions.yml file between them (other than copy and paste 😜)?

@chrissimon-au
Copy link
Contributor

Yes, there are two use cases for bringing definitions into a workspace that aren't in the current repository:

  1. When a context is split into multiple repositories and you don't want to duplicate the context's definitions in each repo (your scenario)
  2. When a term is used in multiple contexts, I'd like Contextive to draw attention to that fact, as I think that focusing on the current context's definition while noting the other definition, could be a good way to aid clarity for teams that have to work across multiple contexts.

In either case, there are a few options:

  1. Update the contextive.path vscode setting to contain a git url and rely on vscode to obtain the file - this won't work with the current version, but shouldn't be hard to do. It would support both use cases - the first, unambiguously. The second, only if all contexts were defined in the same definitions file in some central repo.
  2. Update the definitions file to have an imports array at the top level, which would allow to import definitions from a remote git or https url(s) and merge them with the current definitions file

Given your use case, I think for now, I will see about the first option first - just allowing the existing contextive.path setting to support a git url - and will see how we go.

Stay tuned!

@chrissimon-au chrissimon-au changed the title Support for shared defintions Support for shared definitions Feb 10, 2022
@chrissimon-au
Copy link
Contributor

chrissimon-au commented Feb 12, 2022

From initial spikes on this, it's not as straightforward as I'd hoped. Support for vscode just working when requesting to load a git:// url depends on an extension the user may not have - and there are authentication questions on top of that. Similar authentication issues are likely to affect using an https:// url to define the definitions file assuming it's in a private repo and we're trying to use the https://.../raw/... url of the git host. Not to mention, this pushes more responsibility into the IDE which would lead to conflicting experiences in different IDEs in the future.

An alternative approach that I'm considering which might make a lot of sense, is to include the definitions file in a package and distribute it to other 'services'/'repos' via the native package management tools of the programming languages in question.

Consider a bounded context Demo which has three repos:

  1. demo-common
  2. demo-service-a
  3. demo-service-b

As demo-common contains all the common code for the bounded context (possibly some entity definitions? or other domain-specific logic that needs sharing with other services as a library), it actually makes sense that that would be the owner of the definitions.yml file, and that the definitions.yml file should be versioned along-side that code.

If we ensure that the definitions.yml file is included in the published package from demo-common then when demo-service-a and demo-service-b retrieve demo-common via their package distribution tools (e.g. go get, nuget, npm, gem) the definitions.yml file will come down with it.

demo-service-a and demo-service-b could have a vscode workspace settings file that sets the contextive.path setting to point at the package manager's copy of the definitions.yml file.

The challenge with this approach is differences in the way package management tools store the downloaded packages. There are three common options, not exhaustive, but to illustrate the breadth of possibilities:

  1. store directly in the working folder (e.g. npm in node_modules)
    1. this is easy - contextive.path can just be set to node_modules/demo-common/.contextive/definitions.yml
  2. store in a global package cache, but copy assets from the package into the binaries folder on build (e.g. dotnet)
    1. this is also easy, contextive.path can be set to Demo.ServiceA/bin/Debug/.contextive/definitions.yml (assuming Demo.Common package is setup to include the definitions.yml file correctly by including it in the lib folder)
  3. store in a global package cache, and don't copy assets into the local folder (e.g. go get, python, java).
    1. this is a bit trickier, as the location could vary on dev machine to dev machine depending on local configuration, so a workspace vscode setting isn't great. Individuals could setup user-level settings to override, but that is an extra level of friction I'd like to avoid.

A proposal for resolving scenario 3:

Contextive will shell out and echo %contextive.path% and use the result as the file location.

As an example, with go:

In demo-service-a and demo-service-b, set contextive.path to:

$(go list -m -f '{{.Dir}}' org.git.domain/org/demo-common)/.contextive/definitions.yml

Contextive will execute:

echo "$(go list -m -f '{{.Dir}}' org.git.domain/org/demo-common)/.contextive/definitions.yml"

Which on both linux and windows will return the exact path of the file in the package manager's cache.

I'll need to check, but I suspect it will be possible to find similar shell commands for other package managers that will help identify the local path of the package, and thus the location of the definitions file.

Pros

  1. With this approach, a common contextive.path setting could be stored in the workspace, and once the extension is installed, and the common package is setup correctly, Contextive should just work for all developers.
  2. Leverages existing package distribution tools including hosting and authentication (e.g. should work with private package hosts and any source control system).

Cons

  1. Are there security risks of having Contextive execute arbitrary scripts via the echo $() mechanism? Contextive does not run privileged, and it will only be executing scripts that are stored in a trusted and reviewed repository, so perhaps it's ok?
  2. Having to publish a new common package, just to update some contextive definitions.
  3. Harder to update definitions if you identify a need to update them while working in service-a.
  4. May be more challenging when working in a polyglot environment, as service-b may not be in the same language as demo-common and thus wouldn't depend on it via the package management system. As there are no real users with this use case yet, I'm deferring consideration of this scenario until I can get more details of a real-world situation.

Next Steps

I'm proceeding with a spikes to verify the feasibility of this approach, but thought I'd throw it out here for feedback - any thoughts?

chrissimon-au added a commit that referenced this issue Feb 13, 2022
…s to enable more complex location discovery scripts #36
chrissimon-au pushed a commit that referenced this issue Feb 13, 2022
# [1.5.0](v1.4.0...v1.5.0) (2022-02-13)

### Features

* **language-server:** allow contextive.path to contain shell commands to enable more complex location discovery scripts [#36](#36) ([dc17612](dc17612))
@chrissimon-au
Copy link
Contributor

See v1.5.0 for support for the 'shell escape' approach, and https://github.com/dev-cycles/contextive-demo-go-service for a sample of it in operation with a shared golang package.

More details in the readme here: https://github.com/dev-cycles/contextive/blob/main/src/vscode/contextive/README.md#single-bounded-context-multiple-repositories

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants