GithubHelp home page GithubHelp logo

sourcerypro-feedback's Introduction

Sourcery Pro is a Mac App that extends Xcode with the ability to create your own live templates that understand your code structure.

Do you hate writing same repetitive Swift patterns over and over again?

Now you don't need to, it's just a shortcut away.


Popular use-cases:

  • Create mock implementation from a selected protocol
  • Add Codable support to enums with associated values
  • Kickstart your Composable Architecture boilerplate
  • Generate property level tests
  • Generate test specs from your classes
  • Generate SwiftUI view from a struct
  • Create Prisms and Lenses for your data

It comes bundled with 14 starting templates and features a powerful Template editor with code completion, inline documentation, and a built-in error checker/linter that makes writing your custom automation a breeze.

Built on top of my Sourcery tool that is used in over 40 000 Swift apps, including products like Airbnb, Bumble, and The New York Times.

It saved those apps millions of dollars in development time, and now you can save both your time and regain some of the sanity by stopping to write the same code over and over again, how much is your time worth?

This app is the culmination of 5 years of work and thousands of development hours, it's simply the most powerful Xcode extension ever created.

Even if you never heard of Sourcery, you'll have no problem creating your own templates, and if you are a Sourcery user this tool not only makes creating your templates a completely different experience but also adds additional use-cases that are simply not possible with full CLI automation that I normally recommend with it.

You can share your templates with your friends and team by drag & dropping or right-clicking on the template in the list.

sourcerypro-feedback's People

Contributors

krzysztofzablocki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sourcerypro-feedback's Issues

[BUG] String replacement with regex does not work

Describe the bug
A filter from StencilSwiftKit does not support regex mode

To Reproduce
Steps to reproduce the behavior:

  1. Open Sourcery Pro
  2. Create a new template, clean it up
  3. Enter the following example: {{ "Test string"|replace:"^.","Prefix ",regex }}
  4. Generated code reads Test String

Expected behavior
Generated code should read Prefix est string

Screenshots
image

Sourcery template
Regex bug.sourcerytemplate.zip

repository/diff compatible sourcery template file format

The .sourcerytemplate file contains a single line. This is bad for having the file in a repository. Changes are not visible. It would be an improvement, if the text was a single line but plain text (json or something), than at least some changes can be viewed in the diff with a good diff tool - although bigger changes might be hard to follow.

Alternatively, it would be good, if there was an export function in the editor that exported the plain template text file - I will copy the content now manually into a file and check it in. Or the keep in sync function woudl be nice to keep a textfile in sync.

[BUG] Preferences not reflected

Describe the bug
Even if you change the font size and change the margin and tap size, it is not reflected in the app.
It doesn't change when I restart the app.

To Reproduce
Steps to reproduce the behavior:

  1. Go to 'Preferences'
  2. Click on 'font size'
  3. Change to '14'
  4. Not working

Expected behavior
Change font size
Change margin
Change tab size

Screenshots

2022-09-23.12.54.40.mov

Additional context
version 1.3.4
macOS 12.5.1
Mac Studio (2022)
M1 Ultra 64GB

Comments not treated as comments

Comments are sometime interpreted. Check line 21:

image

{% macro customTypes %}

class Timestamp {
    
}

class Category {
    
}

class ClosedRange<Range> {
    
}

{% endmacro %}

{% macro qualifiedName name %}{% typed name as String %}{{ name | split:"."| join:"" }}{% endmacro %}

{% macro convertPrimitiveTypeName typeName %}{% typed typeName as TypeName %}{% if typeName.name == "Bool" %}bool{% elif typeName.name == "Int"%}int{% elif typeName.name == "Float"%}double{% else %}{% call qualifiedName typeName.name %}{% endif %}{% endmacro %}

{# % macro convertTypeSignature type %}{% typed type as Type %}{% if type.typeNa %}Option<{% call convertTypeSignature type. %}>{% elif typeName.isDictionary %}IMap<{% call convertTypeName typeName.dictionary.keyTypeName %}, {% call convertTypeName typeName.dictionary.valueTypeName %}>{% elif typeName.isArray %}List<{% call convertTypeName typeName.array.elementTypeName %}>{% else %}{% call convertPrimitiveTypeName typeName %}{% endif %}{% endmacro % #}
{% macro convertTypeSignature type %}{% typed type as Type %}{{ type }}{% endmacro %}
{% macro convertType type %}{% typed type as Enum %}{# Enum seems to by subclass of Type and we don't seem to need functionality of Class/Struct subclass #}
{% if type.kind == "struct" %}
class {% call qualifiedName type.name %} {
    {% for ivar in type.variables | !computed %}
    final {% call convertTypeSignature ivar.type %} _{{ ivar.name }};
    {% endfor %}
    {% call qualifiedName type.name %}({% for ivar in type.variables | !computed %}this._{{ ivar.name }}{% if not forloop.last %}, {% endif %}{% endfor %});
    {% call qualifiedName type.name %} copy({ {% for ivar in type.variables | !computed %}{% call convertTypeSignature ivar.type %}? {{ ivar.name }}{% if not forloop.last %}, {% endif %}{% endfor %}}) => {% call qualifiedName type.name %}({% for ivar in type.variables | !computed %}{{ ivar.name }} ?? _{{ ivar.name }}{% if not forloop.last %}, {% endif %}{% endfor %});
    @override String toString() => "{% call qualifiedName type.name %}({% for ivar in type.variables | !computed %}{{ ivar.name }} = $_{{ ivar.name }}{% if not forloop.last %}, {% endif %}{% endfor %})";
}

{% elif type.kind == "enum" %}
{% if type.cases.count != 0 %}{# don't generate empty enums #}
enum {% call qualifiedName type.name %} {
    {% for case in type.cases %}
    {{ case.name }}{% if not forloop.last %},{% endif %}
    {% endfor %}
}

{% endif %}
{% elif type.kind == "extension" %}
// extension {% call qualifiedName type.name %} {
{% for var in type.variables %}
//     var {{ var.name }}: {{ var.typeName }}
{% endfor %}
// }

{% else %}
// todo: unknown type {% call qualifiedName type.name %}: {{ type.kind }} with content {{ type }}

{% endif %}
{% endmacro %}
// Generated {% now %}

import 'package:dartz/dartz.dart';

{% call customTypes %}

{% for type in types.all where type.name != "Category" %}
{% call convertType type %}
{% endfor %}

//    static final title = lensS<Article, String>((article) => article._title, (article, title) => article.copy(title: title));
//    static final sections = lensS<Article, IMap<String, Section>>((article) => article._sections, (article, sections) => article.copy(sections: sections));
//    static final section = (String id) => sections.andThenE<Section, String>(imapLensE(id, () => "No section '$id'"));
{% newline %}

[BUG] First marked as unknown type

Describe the bug
Stencil code var.typeName.generic.typeParameters.first marked with warning as unknown type.

Expected behavior
first should not be marked as unknown type and use type of array element

Crash of code generator 2

The following code crashes when typing ivar in {% call convertType ivar %} - of course I was not finished typing. I wanted to type {% call convertType ivar.typeName %}, but code generation crashed as soon as ivar was entered - it is of the wrong type of course.

{% macro convertType typ %}{% typed typ as TypeName %}{% if typ.isDictionary %}IMap<{% call convertType typ.dictionary.keyTypeName %},{% call convertType typ.dictionary.valueTypeName %}>{% else %}{{ typ }}{% endif %}{% endmacro %}

<<<<<<<
{% for type in types.all %}
class {{ type.name }} {
    {% for ivar in type.variables %}
    final {% call convertType ivar.typeName %} _{{ ivar.name }};
    {% endfor %}
    {{ type.name }}({% for ivar in type.variables %}this._{{ ivar.name }}{% if not forloop.last %}, {% endif %}{% endfor %});
    {{ type.name }} copy({ {% for ivar in type.variables %}{% call convertType ivar %}{{ ivar.name }}{% if not forloop.last %}, {% endif %}{% endfor %}});
}
{% endfor %}
|||||||
class Article {
  final String _title;
  final IMap<String,Section> _sections;
  Article(this._title, this._sections);
  Article copy({String? title, IMap<String, Section>? sections}) => new Article(title ?? this._title, sections ?? this._sections);
  @override String toString() => "Article(title=$_title, sections=$_sections)";

  // Technique: Lenses for accessing/updating relevant properties
  static final title = lensS<Article, String>((article) => article._title, (article, title) => article.copy(title: title));
  static final sections = lensS<Article, IMap<String, Section>>((article) => article._sections, (article, sections) => article.copy(sections: sections));
  static final section = (String id) => sections.andThenE<Section, String>(imapLensE(id, () => "No section '$id'"));
}
>>>>>>>

"now" is treated as Error

According to the stencil definition, there is an expression now. It renders as expected, but it is marked as an error in the editor.

image

[BUG] App shows "No License Found" on every launch

Describe the bug
With an already activated license, the app still shows the "No license found" overlay when launched. Quitting and relaunching fixes the issue, until next computer reboot.

To Reproduce

  1. Launch the app with an activated license.

Expected behavior
The app functions normally.

Actual behavior
The activation overlay is displayed.

[BUG] Editor issues.

Describe the bug

  1. Sourcery Pro when editing file randomly moves cursor to end of file. It happens pretty often. especially when deleting symbol or adding new line.
  2. Sourcery Pro undos changes randomly when typing. It often happens when 1. happens also, but sometimes when just typing.

To Reproduce
Steps to reproduce the behavior:
For me the easiest way to reproduce is to copy/paste long line in template file and start typing/editing in the middle of newly pasted line.

Screenshots
https://user-images.githubusercontent.com/2234720/133056887-0b8bb82b-23c8-435b-b7f4-2589c7b5c35c.mov

Protocol Mock for async methods is available ?

Hi Thanks for amazing app
I tried to use Protocol Mock template and added some async methods , but no generated code appears here is the sample

protocol SwitchWithTextCellProtocol {
    var title: String { get }
    var titleFont: UIFont { get }
    var titleColor: UIColor { get }
    
    var switchOn: Bool { get }
    var switchColor: UIColor { get }

    func onSwitchToggleOn(on: Bool)
    func doSomeThing(on: Bool) async
}

Sourcery Pro download for existing direct purchase customers

Some time ago, I made a direct purchase of a Sourcery Pro license from https://www.merowing.info/sourcery-pro. I am currently facing a situation where I need to re-download the application due to an OS upgrade. However, upon reviewing the website, I have noticed that my available options seem to be limited to either purchasing the app from the Mac App Store or acquiring a new license.

Could you please guide me on how to directly download the executable for Sourcery Pro from your website or another official source? I have a valid license and am willing to provide any required information.

I tried to send an email at [email protected], but the delivery failed.

Thanks!

[BUG] Editor is disabled during first run

Describe the bug
During the first run, the editor functionality in Sourcery Pro was disabled. It didn't show any errors, it just wouldn't let me edit any templates (existing, cloned, or newly created). For me as a new user, this was very confusing, I was ready to request a refund, but thankfully restarting the app fixed the issue.

To Reproduce
Steps to reproduce the behavior:

  1. Complete purchase via https://www.merowing.info/sourcery-pro/
  2. Download the app from the website (was version 1.3.3 in my case).
  3. Start the app, complete the activation using the provided license code.
  4. Create a new template, try to edit it.

Expected behavior
The app was activated, so I expected editing to work. If something went wrong and the app still thought it wasn't activated, it should have shown an error message.

[BUG] Parentheses in stencil code

Describe the bug
Parentheses is marked with warning as unknown type.

Expected behavior
Parentheses should be parsed normally and can be used to change operator precedence. Stencil code {% if (one or two) and three %} should be valid and not marked with warning.

[BUG] SourvceryPRO from App Store doesn't recognise template

Describe the bug

Old sourcery and stencil inside sourceryPro app in Mac App Store.
I would suggest to update the app with up-to-date utilities or add ability to select sourcery executable path to avoid unnecessary app updates.

To Reproduce
Steps to reproduce the behavior:

  1. Go to AutoMockable template
  2. Copy it to SourceryPro from MAS
  3. Receive valudation error
  4. See error

Expected behavior
Template should work

Screenshots
If applicable, add screenshots to help explain your problem.

Sourcery template
Exported template (right click on the template list) that the issue occurs in.
Template here - https://github.com/krzysztofzablocki/Sourcery/blob/master/Templates/Templates/AutoMockable.stencil

Additional context
Add any other context about the problem here.

[BUG] Sourcery Pro getting extremely slow few minutes after start.

Describe the bug
After starting Sourcery Pro it's getting extremely slow 1-2 minutes after start. Typing single symbol takes from 1 to 5 seconds. Rainbow spinner is showing some times. It does not matter which template i'm editing, is template or sample code. It also doesn't matter if Code Generation enabled or not. Deleting symbol or new line takes most time as i can see.

Expected behavior
Sourcery Pro should work fast as normal code editor. Currently it is almost unusable to make big changes in templates.

Screenshots
https://user-images.githubusercontent.com/2234720/133051115-f3072039-8654-470b-8d3b-61519b28f810.mov

[BUG] Xcode stops responding on startup for some time when extension is enabled

I recently upgraded to Monterey and Xcode 13.4.1. After the upgrade, when I start Xcode, it stops responding for 30-40 seconds and starts working after that. This only happens when the extension is enabled. When the extension is disabled, it works fine.

I have tried resetting Xcode (removing all cache and even re-installing), I also re-installed Sourcery Pro, but it didn't help.

Website shows as html source

If you got the menu Help -> Documentation you will be redirected to the website
https://cdn.jsdelivr.net/gh/krzysztofzablocki/Sourcery@master/docs/index.html

Unfortunately it displays as html source. See image:

image

It would be cool, if it displayed as rendered html.

Also I would suggest to add to the Help menu the menu item Stencil Documentation with a link to
https://stencil.fuller.li/en/latest/builtins.html (or some similar page with a definition what's possible to write)

[FEATURE] Arguments for templates in editor

Is your feature request related to a problem? Please describe.
I'm trying to write a template which will generate code based on arguments, rather than existing code. It's going to be used in a codegen script to generate some basic classes but they need to be named based off the feature name, like ExampleClass.swift where Example is the feature name. However, I don't see a way to specify those args in the editor.

Describe the solution you'd like
The ability to specify args for a template (probably in the right sidebar?)

Describe alternatives you've considered
I've considered using a basic swift model source file to gen off of, but it would mean writing one to disk that just has a struct with my arg name. Would be better to just have an arg.

Additional context
The template I'm developing will be triggered by a script and not only run in xcode or in the Sourcery Pro editor.

Variables with isOptional should have `optional` method

For TypeNames there are checks isArray and isDictionary. If this check returns true, it is possible to use the .array and .dictionary getters respectively, which return objects, that allow to get to the inner types. It would be cool to also have a .optional getter to get to the inner type for optionals.

Here is how my sample code would look like, if there was such a getter:

{% macro convertTypeSignature typeName %}{% typed typeName as TypeName %}{% if typeName.isOptional %}Option<{% call convertTypeSignature typeName.optional.elementType %}>{% elif typeName.isDictionary %}IMap<{% call convertTypeName typeName.dictionary.keyTypeName %}, {% call convertTypeName typeName.dictionary.valueTypeName %}>{% elif typeName.isArray %}List<{% call convertTypeName typeName.array.elementTypeName %}>{% else %}{% call convertPrimitiveTypeName typeName %}{% endif %}{% endmacro %}

Here is how I worked around it, because it is not available (qualifiedName now also strips "?" chars, which I did not have to do before):

{% macro qualifiedName name %}{% typed name as String %}{{ name | split:"."| join:"" | split:"?"| join:"" }}{% endmacro %}
{% macro convertTypeSignature typeName checkOptional %}{% typed typeName as TypeName %}{% typed checkOptional as String %}{% if checkOptional != "false" and typeName.isOptional %}Option<{% call convertTypeSignature typeName "false" %}>{% elif typeName.isDictionary %}IMap<{% call convertTypeSignature typeName.dictionary.keyTypeName "true" %}, {% call convertTypeSignature typeName.dictionary.valueTypeName "true" %}>{% elif typeName.isArray %}List<{% call convertTypeSignature typeName.array.elementTypeName "true" %}>{% elif checkOptional == "false" %}{% call convertPrimitiveTypeNameStrippingOptional typeName %}{% else %}{% call convertPrimitiveTypeName typeName %}{% endif %}{% endmacro %}

With my workaround there is the problem, that nested Optionals are not correctly dealt with.

[DOCUMENTATION] What does Xcode expose?

Xcode system is really limited, literally all I get access to is:

  • Current file text
  • Any user selection ranges in that text

So generally you want to be basing templates on typeName rather than type properties.
I'm writing a blog post about some basic feature's Apple could add to Xcode that could give us more power that shouldn't be too complicated for them to implement.

If you have fully automated use-cases and need full project AST then standard Sourcery is your friend, Pro makes writing those templates really straighforward and next release of Sourcery CLI will support running normal sourcerytemplate files.

[BUG] Crash of code generator

The following template crashes the code generator. Please have a look at the first line. I typed typ.dictionary.keyType. I wanted to type typ.dictionary.keyTypeName, but since keyType is a variable of dictionary, which is of the wrong type in this context, the code compiled, but with wrong types and then probably the exception during running the code generator was not caught.

{% macro convertType typ %}{% typed typ as TypeName %}{% if typ.isDictionary %}IMap<{% call convertType typ.dictionary.keyType %},{% call convertType typ.dictionary.valueTypeName %}>{% else %}{{ typ }}{% endif %}{% endmacro %}

<<<<<<<
{% for type in types.all %}
class {{ type.name }} {
    {% for ivar in type.variables %}
    final {% call convertType ivar.typeName %} _{{ ivar.name }};
    {% endfor %}
}
{% endfor %}
|||||||
class Article {
  final String _title;
  final IMap<String,Section> _sections;
  Article(this._title, this._sections);
  // Technique: Copy "constructor" for concise partial updates
  Article copy({String? title, IMap<String, Section>? sections}) => new Article(title ?? this._title, sections ?? this._sections);
  @override String toString() => "Article(title=$_title, sections=$_sections)";

  // Technique: Lenses for accessing/updating relevant properties
  static final title = lensS<Article, String>((article) => article._title, (article, title) => article.copy(title: title));
  static final sections = lensS<Article, IMap<String, Section>>((article) => article._sections, (article, sections) => article.copy(sections: sections));
  static final section = (String id) => sections.andThenE<Section, String>(imapLensE(id, () => "No section '$id'"));
}
>>>>>>>

[DOCUMENTATION] How to learn to write custom Sourcery templates?

A good way to start learning how to write your own templates is Sourcery Workshops I did.

It features step by step commits and wiki page and as a Sourcery Pro user you can jump directly to writing your templates since CLI integration is not required.

When you are writing templates for Sourcery Pro live templates workflow, you don't need to use phantom protocols or annotations since you can rely on the fact that you have user selected type informations, so your live templates can be simpler than the CLI ones.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.