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

tuist library proposal #192

Closed
kwridan opened this issue Jan 4, 2019 · 11 comments
Closed

tuist library proposal #192

kwridan opened this issue Jan 4, 2019 · 11 comments

Comments

@kwridan
Copy link
Collaborator

kwridan commented Jan 4, 2019

As promised, following up from the feedback in #172 re: the library suggestion.

Overview

For one of the (work) projects I’ve been working on that has several Xcode projects, we’ve reached a stage where we can no longer sustainable manage Xcode projects manually, however aren’t yet at a scale to adopt a whole new different build system and toolchain (like buck and bazel) just yet. As such we’ve been experimenting with a few different tools that can assist us with Xcode project generation.

tuist has the most promising workflow which we’d like to explore further. However having a large project and team introduces some interesting cases that need further consideration. Some of which were highlighted in my earlier feedback, which I’m glad to see was well received and many of the items made it for consideration and some have already been resolved!

Some of those items (like custom definitions, conventions) may be only useful for our use cases, and would perhaps be harmful to try and push them onto tuist. As such the idea of somehow leveraging tuist as a library is quite appealing.

In theory that would allow tuist to continue enforcing its conventions without compromise, whilst at the same time allowing 3rd parties to leverage tuist as a library to support their use cases and conventions. Of course, this will come at a cost, it would complicate the internals of tuist and as you rightfully highlighted, would introduce an additional support burden. However this is something we'd be happy to contribute towards.

Actually, if I’ve done my research right, XcodeGen is another potential candidate for such a library. It seems there’s a long standing feature request to support multiple projects and workspaces, something tuist already supports. Additionally, I see tuist is deprecating json and yaml support, as such this does create an opportunity for XcodeGen to continue support for those formats.

Proposal

tuist combines the following functionality:

  • Command line parser for the tuist features
  • Parse standalone Swift file project definitions
  • Lint project definitions
  • Generate Xcode projects & workspaces from a definition
  • (new) Perform project setup via the Up command (e.g. installing tools like Swiftlint)

The proposal, is to separate out some of those to their own libraries within the same swift package (at least initially until they are proven).

  • TuistKit
    • Invoking SwiftFileInterpreter to obtain ProjectDescription
    • Linting of ProjectDescription
    • Generating Xcode workspaces & projects via TuistGen
    • Other tuist logic like the Up command support
  • TuistGen (naming is hard 😛)
    • Generating Xcode workspaces & projects
    • Can be used by 3rd parties wishing to develop their own tooling (e.g XcodeGen)
  • SwiftFileInterpreter
    • Performs the swiftc calls on a given file and returns the output
    • Can be used by 3rd parties wishing to develop their own project definitions.

Splitting is possibly the easy part, the harder part would be figuring out the API TuistGen would need to expose to cater for tuist and other 3rd parties. Can post some more on this if there’s interest.

Alternatives

For 3rd party developers with a customisation need, there are a few options:

  1. Fork tuist and apply customisations
  2. Write tooling on top of xcodeproj directly

Option 1) provides quick wins short term, but has long term drawbacks. Developers would soon lose the ability to contribute back any general improvements and vice versa pull in any improvements made upstream.

Option 2) is probably the most flexible and powerful, but realistically, some if not most of the generator logic of tuist would be replicated to some degree. Additionally like option 1, contributions would be hard to make upstream and it would be a shame to have a divergent yet similar tool out there.

@pepicrft
Copy link
Contributor

pepicrft commented Jan 4, 2019

For one of the (work) projects I’ve been working on that has several Xcode projects, we’ve reached a stage where we can no longer sustainable manage Xcode projects manually, however aren’t yet at a scale to adopt a whole new different build system and toolchain (like buck and bazel) just yet. As such we’ve been experimenting with a few different tools that can assist us with Xcode project generation.

This is exactly what motivated me to build Tuist. Back when I was working at SoundCloud (@RomainBoulay can tell you more about this) we modularized the codebase. As a result, we got more than 10 Xcode projects, with a similar structure with the only difference of having different link settings, sources, and resources. I think reached that point, maintaining those projects is a huge burden, and a declarative interface facilitate things a lot. I agree with you that Buck and Bazel is too much to tackle this problem. It'd be nice if they'd provide just the declarative layer but without replacing the build system. Unfortunately, it does.

tuist has the most promising workflow which we’d like to explore further. However having a large project and team introduces some interesting cases that need further consideration. Some of which were highlighted in my earlier feedback, which I’m glad to see was well received and many of the items made it for consideration and some have already been resolved!

I'm glad that you found the workflow promising to explore further. I wish I had more free time to add some of the workflows and ideas that I had in mind. Most of them help with the common pain areas that developers need to go through when building iOS apps, like dealing with signing, publishing of new versions to the store. I'm also happy that you are giving Tuist and challenging the assumptions that we made. Happy to iterate the tool with all that feedback.

In theory that would allow tuist to continue enforcing its conventions without compromise, whilst at the same time allowing 3rd parties to leverage tuist as a library to support their use cases and conventions. Of course, this will come at a cost, it would complicate the internals of tuist and as you rightfully highlighted, would introduce an additional support burden. However this is something we'd be happy to contribute towards.

This is a cost that we are willing to take if we find the right setup for Tuist that helps other projects codify their conventions and use cases into their own tools. As long as the refactoring of the core doesn't add any friction to Tuist as a command line tool, it's all fine.

In theory that would allow tuist to continue enforcing its conventions without compromise, whilst at the same time allowing 3rd parties to leverage tuist as a library to support their use cases and conventions. Of course, this will come at a cost, it would complicate the internals of tuist and as you rightfully highlighted, would introduce an additional support burden. However this is something we'd be happy to contribute towards.

XcodeGen is wonderful alternative that you might consider. They took a different approach where the manifest format is more aligned with the Xcode project's. Moreover, they added some useful features on top of the format that facilitate defining and reusing the projects. They sticked to yaml and json as formats, which we deprecated because we plan to add features that leverage the Swift compiler. With the refactor of the core though, we could decouple the manifest models from the definition source, so anyone could implement a parser for their own format.

@pepicrft
Copy link
Contributor

pepicrft commented Jan 4, 2019

From your proposal, I drawed the diagram below:

tuist

I think we could have modules with strong conventions such as a the CLI, the support module (i.e the current TuistKit) or the manifest parser, and modules with weak conventiosn such as a the manifest models, the linter and the project generator.

I think structuring the project like that is feasible. The challenge is going to be designing the API for those modules with weak conventions to be flexible enough for Tuist and other third-party projects. For example, having the up section in the manifest is something that is specific to Tuist but that needs to be part of the manifest model.

What do you think @kwridan ?

@pepicrft
Copy link
Contributor

pepicrft commented Jan 4, 2019

Answering to the alternatives section:

Fork tuist and apply customisations

I'd rather not do it. I've seen the Buck project being forked by Uber and never merged back. It also makes developers more confusing because there'd be two development threads diverging overtime.

Write tooling on top of xcodeproj directly

You described the downsides very well. There'd a lot of duplicated logic with this project. When I embarked on building Tuist, I considered reusing XcodeGen's generation logic, but given that I was very proficient on xcodeproj, I decided not to introce another indirection layer and rather use xcodeproj directly.

@kwridan
Copy link
Collaborator Author

kwridan commented Jan 4, 2019

Thanks for your quick response!

This is a cost that we are willing to take if we find the right setup for Tuist that helps other projects codify their conventions and use cases into their own tools. As long as the refactoring of the core doesn't add any friction to Tuist as a command line tool, it's all fine.

Awesome, glad you're open to this!

XcodeGen is wonderful alternative that you might consider. They took a different approach where the manifest format is more aligned with the Xcode project's. Moreover, they added some useful features on top of the format that facilitate defining and reusing the projects. They sticked to yaml and json as formats, which we deprecated because we plan to add features that leverage the Swift compiler. With the refactor of the core though, we could decouple the manifest models from the definition source, so anyone could implement a parser for their own format.

I actually gave XcodeGen a go too 🙂. XcodeGenKit offers a lot of flexibility that allows writing tooling on top of. Sadly, it doesn't yet support workspaces and resolving dependencies between multiple projects like tuist. You are right though, another alternative is to contribute updates to XcodeGen to help support this. This actually why I mentioned it here, as I believe XcodeGen can benefit from this rather than re-implementing it.

I think we could have modules with strong conventions such as a the CLI, the support module (i.e the current TuistKit) or the manifest parser, and modules with weak conventiosn such as a the manifest models, the linter and the project generator.

This is great! It's very close to what we had in mind!

I think structuring the project like that is feasible. The challenge is going to be designing the API for those modules with weak conventions to be flexible enough for Tuist and other third-party projects.

Agreed, this will be the most challenging part.

For example, having the up section in the manifest is something that is specific to Tuist but that needs to be part of the manifest model.

The up command is an interesting case, I'm curious why it's defined at the project level as opposed to the workspace level, or perhaps something even higher level (e.g. Environment.swift). If my understanding of the up command is correct, it caters for setting up the environment of a (work) project. e.g. setting up homebrew, installing tools like swiftlint etc... these tend to be globally scoped to the (work) project as opposed to each individual Xcode project. I'm sure I'm missing some use cases, perhaps the Carthage dependencies use case is what warrants the per Project.swift definition?

Will explore this further with a few of my colleagues and post back some suggestions on the API for us to iterate on.

@kwridan
Copy link
Collaborator Author

kwridan commented Jan 14, 2019

@pepibumur here are some suggestions I've been exploring with @marciniwanicki - we'd be keen on your thoughts / feedback 🙂 - thanks for taking the time to hear us out!

Approach

A change like this will likely cause a lot of code to move around, as such to help minimize impact we can consider the following:

  • Initially, migrate existing manifest models with minimal changes to the generator library
  • Send separate proposals / PRs for further additions or modifications to the library

This will help minimize the changes required for review and allow us to verify that the generated projects are identical before and after the changes. Additionally, it will (hopefully) make the iteration process on the API easier as we'd have a working base!

We can start a feature branch feature/tuist-generator-library which PRs can go to. Once the initial feature/tuist-generator-library is complete it can be merged into master.

Initially on the feature branch we can consider keeping the existing TuistKit as is, however include a new hidden command that exercises the new library code path e.g. tuist _generate. This could help us compare the behaviour side by side and allow us to incrementally re-factor the classes without breaking the build.

Library

Any thoughts on the name, TuistGenerator, TuistProjectGenerator ... ?

The two commands that would use the TuistGenerator:

  • generate
  • up

To distinguish them from their TuistKit counterparts, in the initial stage on the feature branch, we could use _generate and _up (probably nicer and more meaningful than generate2 and up2).

API

Entry Point

try tuistGenerator.generate(basePath: path, at: destination)
public class TuistGenerator {

    private let graphLoader: GraphLoading
    private let graphModelLoader: GraphModelLoading
    private let workspaceGenerator: WorkspaceGenerating

    public func generate(basePath: AbsolutePath) throws {
        // ..
    }

    public func graph(basePath: AbsolutePath) throws -> Graphing {
        // ...
    }
}

The client code would need to implement GraphModelLoading protocol:

public protocol GraphModelLoading {
    func loadProject(at path: AbsolutePath) throws -> Project
    func loadWorkspace(at path: AbsolutePath) throws -> Workspace
    func manifests(at path: AbsolutePath) -> Set<Manifest>
    func manifestPath(at path: AbsolutePath, manifest: Manifest) throws -> AbsolutePath
}

Where Project and Workspace are the ones within the generator module (i.e. TuistGenerator.Project and TuistGenerator.Workspace)

What is your preference for referring to the models here? "graph model" or "manifest model" - perhaps choosing another name to disambiguate between those and the ProjectDescription files which are also manifests would be helpful.

Classes

Candidates for the library:

├── Extensions
│   ├── AbsolutePath+Extras.swift
│   └── Optional+Extras.swift
├── Generator
│   ├── BuildPhaseGenerator.swift
│   ├── ConfigGenerator.swift
│   ├── FileGenerator.swift
│   ├── GeneratedProject.swift
│   ├── GenerationDirectory.swift
│   ├── GenerationOptions.swift
│   ├── LinkGenerator.swift
│   ├── ProjectDirectoryHelper.swift
│   ├── ProjectFileElements.swift
│   ├── ProjectGenerator.swift
│   ├── ProjectGroups.swift
│   ├── SchemesGenerator.swift
│   ├── TargetGenerator.swift
│   └── WorkspaceGenerator.swift
├── Graph
│   ├── Graph.swift
│   ├── GraphCircularDetector.swift
│   ├── GraphLoader.swift
│   ├── GraphLoaderCache.swift
│   ├── GraphLoadingError.swift
│   ├── GraphModelLoader.swift
│   └── GraphNode.swift
├── Linter
│   ├── GraphLinter.swift
│   ├── LintingIssue.swift
│   ├── ProjectLinter.swift
│   ├── SettingsLinter.swift
│   ├── TargetActionLinter.swift
│   └── TargetLinter.swift
├── Model
│   ├── BuildConfiguration.swift
│   ├── CoreDataModel.swift
│   ├── Dependency.swift
│   ├── Headers.swift
│   ├── Platform.swift
│   ├── Playgrounds.swift
│   ├── Product.swift
│   ├── Project.swift
│   ├── Settings.swift
│   ├── Target.swift
│   ├── TargetAction.swift
│   ├── Workspace.swift
│   └── XcodeRepresentable.swift
├── TuistGenerator.swift
└── Utils
    └── ResourceLocator.swift

Manifest/Graph Models

While the goal initially isn't to introduce any new features to the exisiting models, some changes are required:

  • Decouple the models from the ProjectDescription related logic.
  • Add the manifests target outside the library (the Xcode target that allows editing Project.swift)

For this, a new Loader can be introduced to TuistKit that can perform the ProjectDescription > TuistGenerator conversion, and additionally add the manifests target.

Testing

  • The exisiting TuistKit generator related unit tests can be migrated to TuistGenerator
  • Additionally, a few integration tests for the generator can also be introduced
    • While some of those may appear to be duplicates of the acceptance tests for tuist, there is some benefit in having them, as they could cover code paths that may be harder to orchestrate at a higher level
    • These can take two forms:
        1. (heavy weight) generate project and build it
        1. (light weight) inspect/valdiate the pbxproj structures in memory

Up

Based on the example you provided regarding Up, here are some thoughts/suggestions:

Up relies on the graph resolution to get a list of all setup actions required (across all dependencies). This currently lives in the ProjectDescription definition. To generalize, manifests can include some additional metadata which may be unrelated to Xcode project generation directly however there is a need to resolve these within the graph.

Currently (in TuistKit), the graph resolution is shared for both Xcode project generation and extracting a list of additional metadata for processing by other commands.

Option 1) Mantain 2 graphs

  • Resolve a graph of ProjectDefinition manifests
  • Resolve a graph pf TuistGenerator models
  • This would allow for the most flexibility in both graphs:
    • Xcode project related lint rules can be processed within the library
    • ProjectDescription specific lint rules can be processed with TuistKit
  • The only thing which may seem odd is the fact the graph is resolved twice which may seem ineffecient
    • As it stands, up and generate are separate commands so the double resolution may not occurr all the time
    • Some optimizations can be introduced to help mitigate this

Option 2) Abstract the graph models

Another option is to introduce some abstractions around the graph models to allow having different implementation that contain additional properties

class TuistProject: Project {
    // Project
    var name: String 
    //...

    // Additional properties
    var up: [Up]
}

The graph would need to be exposed to make this technique work and some casting may be involved, additionally would require all clients to provide their own types or subclass.

Option 3) Use a single graph from the library but extend it to store custom data (metadata)

Setting up and maintaining two graphs (one in the generator and second in the client code - i.e. TuistKit) can introduce quite a lot of boilerplate.

We can expose Graphing protocol to the client code, extend and make it generic so it could also return some metadata for a given path. In that case second graph resolution wouldn't be needed.
TuistKit could use metadata to store the whole ProjectDefinition in it and use that definition to pull the up instructions.

public protocol GraphModelLoading {
    associatedtype Metadata
    func loadProject(at path: AbsolutePath) throws -> Project
    func loadWorkspace(at path: AbsolutePath) throws -> Workspace
    func manifests(at path: AbsolutePath) -> Set<Manifest>
    func manifestPath(at path: AbsolutePath, manifest: Manifest) throws -> AbsolutePath
    func loadMetadata(at path: AbsolutePath) throws -> Metadata
}

Requires further investigation / prototyping but is something that could work. One downside could be the complexity generics add to the classes within the library.

Option 4) Model Extensions

Another options is to store some additional metadata into the library models that can later be decoded.

// TuistGenerator

class Project {
    var metadata: String?
}

// TuistKit

extension Project {
    var up: [Up] {
        // decode metadata
    }
}

This mitigates the generics complexity, a downside would be the need to decode data twice, once to form the graph in the first place, and then again for the metadata.

Option 5) (Initially) include it in the library

To minimize impact, perhaps initially have Up included in the library and expose the graph. Once more features are added of a similar style it may be easier to re-evalute and explore options given more use cases.

Summary

Perhaps a hybrid of the options above would be possible. Do you have any further thoughts or ideas how to split the responsibilities of the modules and how to integrate them?

Initially (even when it's landed on master) we could state TuistGenerator doesn't yet have a stable API to make sure we can purify its fronted API on the go (similar to Utility in Swift PM)

@pepicrft
Copy link
Contributor

Thanks @kwridan and @marciniwanicki for elaborating a proposal for introducing those changes. Here's my feedback on your proposal:

This will help minimize the changes required for review and allow us to verify that the generated projects are identical before and after the changes. Additionally, it will (hopefully) make the iteration process on the API easier as we'd have a working base!

That plan sounds good to me. What I suggest before doing any change is adding some integration tests that given a project manifest that contains all supported options, it generates the expected Xcode project. I've opened an issue to tackle that.

We can start a feature branch feature/tuist-generator-library which PRs can go to. Once the initial feature/tuist-generator-library is complete it can be merged into master.

I'd avoid having a branch that we merge new branches into. Instead, I'd find the way to make incremental changes that keep master shippable all the time. With those tests in place, which will bring the necessary confidence to introduce changes, I think it's ok to merge directly into master.

Any thoughts on the name, TuistGenerator, TuistProjectGenerator ... ?

I'm actually thinking we can get rid of Tuist from the name, like the SPM does. What do you think about just ProjectGenerator?

API

I like the idea of the TuistGenerator reading the projects and workspaces through the injected dependency that conforms the protocol graphModelLoader. I have one question though, what are the following methods for?

func manifests(at path: AbsolutePath) -> Set<Manifest>
func manifestPath(at path: AbsolutePath, manifest: Manifest) throws -> AbsolutePath

What is your preference for referring to the models here? "graph model" or "manifest model" - perhaps choosing another name to disambiguate between those and the ProjectDescription files which are also manifests would be helpful.

You are right regarding the ambiguity. I'd keep the names in the ProjectDescription as they are: Target, Project, Settings... because those are user-facing, and rename the ones in the TuistGenerator module. Some ideas: xxxEntity, xxxModel. I'd not include graph in the name though. What do you think? That'll make it easier to navigate to the models because right now, if you search for Target or Project, you have to look at the target they belong to.

Classes

Looks good 👍. What about using another name for TuistGenerator that doesn't include Tuist. What about just Generator. If the name becomes ambiguous in the future because there's another generator we can rethink the name.

Up

Do you mind if I add a 5th option that simplifies things a lot 😜? What about extracting the Up metadata from the Project model and decouple it from the graph. There could be another file, Setup.swift, whose definitions would be included in the ProjectDescription and that would contain the following Swift variable:

let setup = Setup([
  .carthage(...)
] 

That way, TuistGenerator does not need to know about Tuist having support for another type of manifest. What do you think?

Perhaps a hybrid of the options above would be possible. Do you have any further thoughts or ideas how to split the responsibilities of the modules and how to integrate them?

The approach looks good to me. Only one more thing. What do you think if modify the API that you suggested to support a closure that gets called before each project gets written?

public func generate(basePath: AbsolutePath, beforeWrite: (XcodeProj, Path) -> Void) throws

That way consumers of the API could hook into the process and introduce any desired tweaks into the project.

Initially (even when it's landed on master) we could state TuistGenerator doesn't yet have a stable API to make sure we can purify its fronted API on the go (similar to Utility in Swift PM)

We should definitively state that. We'll need some internal iterations until we reach an API we are happy with for both internal and external usages.

@pepicrft
Copy link
Contributor

pepicrft commented Jan 16, 2019

Feel free to create issues based on the feedback @kwridan. Feel free to drive the work and let me know if you need any help before making a decision. I'm very excited about this happening and seeing Tuist supporting your project's needs.

@kwridan
Copy link
Collaborator Author

kwridan commented Jan 17, 2019

Thanks for the detailed feedback, it is much appreciated!

That plan sounds good to me. What I suggest before doing any change is adding some integration tests that given a project manifest that contains all supported options, it generates the expected Xcode project. I've opened an issue to tackle that.

makes a lot sense! 👍

I'd avoid having a branch that we merge new branches into. Instead, I'd find the way to make incremental changes that keep master shippable all the time. With those tests in place, which will bring the necessary confidence to introduce changes, I think it's ok to merge directly into master.

Agreed

I'm actually thinking we can get rid of Tuist from the name, like the SPM does. What do you think about just ProjectGenerator?

Funny story, while testing we accidentally added SwiftPM as a dependency in our package rather than just Utility, and this resulted in an interesting issue where Xcodeproj from Swift PM conflicted with tuist/xcodeproj. Similarly module names may conflict with class names too. I'm not sure Swift PM has fully solidified their convention for this just yet 😞

We found some related issues for Swift PM:
Package module name collisions - Using Swift - Swift Forums
SR-1168 Deal with dependency name collisions - Swift

I like the idea of the TuistGenerator reading the projects and workspaces through the injected dependency that conforms the protocol graphModelLoader. I have one question though, what are the following methods for?

func manifests(at path: AbsolutePath) -> Set<Manifest>
func manifestPath(at path: AbsolutePath, manifest: Manifest) throws -> AbsolutePath

oops! too much copy and paste during our prototyping :) you are right these won't be needed.

You are right regarding the ambiguity. I'd keep the names in the ProjectDescription as they are: Target, Project, Settings... because those are user-facing, and rename the ones in the TuistGenerator module. Some ideas: xxxEntity, xxxModel. I'd not include graph in the name though. What do you think? That'll make it easier to navigate to the models because right now, if you search for Target or Project, you have to look at the target they belong to.

I was mostly referring to how we should refer to these models for discussions and documentation. I was confusing which of these are manifests (I assume the classes in ProjectDescription ?)

Technically we’d be able to support having a Platform type in both the ProjectDescription and the TuistGenerator modules without any issues for example:

func platform(from description: ProjectDescription.Platform) -> TuistGenerator.Platform {
        switch description {
        case .iOS: return .iOS
        }
    }

This would only exist in a thin layer (the model loader) that translates between both and wouldn’t spread further. I guess it will be easier to iterate on once we get started.

Do you mind if I add a 5th option that simplifies things a lot 😜? What about extracting the Up metadata from the Project model and decouple it from the graph. There could be another file, Setup.swift, whose definitions would be included in the ProjectDescription and that would contain the following Swift variable:
That way, TuistGenerator does not need to know about Tuist having support for another type of manifest. What do you think?

This is the best one 👍 let's go with that. We weren't sure about the requirements of up and if it needed to remain in the graph.

The approach looks good to me. Only one more thing. What do you think if modify the API that you suggested to support a closure that gets called before each project gets written?

Yes this is a great suggestion, this would allow a lot of flexibility for clients of the API. We could introduce it after the initial version as we’ll no doubt need it.

We should definitively state that. We'll need some internal iterations until we reach an API we are happy with for both internal and external usages.

🙌

Feel free to create issues based on the feedback @kwridan. Feel free to drive the work and let me know if you need any help before making a decision. I'm very excited about this happening and seeing Tuist supporting your project's needs.

Awesome! Here’s a summary of follow ups:

  • We’ll spin off separate issues to tackle the different chunks of work
  • We’ll also spin off a separate issue to track overall progress of creating the library
    • This will have links to all the related issues including this original proposal
  • The first issue to tackle is the introduction of more integration tests, you are absolutely right, we’ll need more of those to gain more confidence
  • Let us know which of ProjectGenerator vs TuistGenerator you prefer as both sound good to us
  • As for the models, at least initially are you happy to keep them as Product, Platform etc… ?

We’re excited to get started on this! We’ll kick off over the next week or so.

@pepicrft
Copy link
Contributor

pepicrft commented Feb 6, 2019

Funny story, while testing we accidentally added SwiftPM as a dependency in our package rather than just Utility, and this resulted in an interesting issue where Xcodeproj from Swift PM conflicted with tuist/xcodeproj. Similarly module names may conflict with class names too. I'm not sure Swift PM has fully solidified their convention for this just yet

😅, let's keep the Tuist prefix then.

Technically we’d be able to support having a Platform type in both the ProjectDescription and the TuistGenerator modules without any issues for example:

I usually refer to manifest models the ones in the ProjectDescription framework. Do you have any idea to make that less ambiguous? I'm not a native English speaker so I'm a bit resourceless when it comes to coming up with words.

Let's keep their names in the frameworks.

@pepicrft
Copy link
Contributor

pepicrft commented Feb 6, 2019

We’re excited to get started on this! We’ll kick off over the next week or so.

I'm also excited about this 🎉. Please, add me as a reviewer on those PRs, and I'll gladly give you feedback and help you get those changes merged into the project.

@kwridan
Copy link
Collaborator Author

kwridan commented Feb 7, 2019

👍 thanks @pepibumur! - will close this proposal.

@kwridan kwridan closed this as completed Feb 7, 2019
marciniwanicki added a commit to bloomberg/tuist that referenced this issue Feb 11, 2019
Introduce new TuistGenerator module (based on the proposal tuist#192).

a#	modified:   Sources/TuistKit/Models/UpCustom.swift
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