Finally I have finished first stage of engine development - now there is a sinatra app that could be added to any rack app (although not tested) and can run as a standalone executable (for now using webrick).
Git repo is located here: https://github.com/ShimShtein/detective Key files: - lib/detective/web/endpoint.rb: Sinatra app that exposes the resources. - lib/detective/launcher.rb: Rubocop's CLI wrapper to make use of custom cops. - bin/detective: Standalone mode executable. I would really appreciate if you evaluate this code and see if it is something we want to work with. One caveat though: I still didn't add the code responsible for erb handling, it will be added later. Shim. On Thursday, September 14, 2017 at 4:27:15 PM UTC+3, Shimon Shtein wrote: > > Ewoud: > > About rack endpoint: It should be created for use case 2, where the check > is running in "online"-ish mode. > I prefer creating it as a microservice for scalability reasons, so I > wouldn't want to tie it too tightly with foreman-templates. Besides that, > tying it into foreman-templates will mean the same life cycle that I would > prefer to avoid. > As I already wrote for case 1 and 3, we could use the underlying ruby > wrapper directly, hence avoid the usage of the API. > As for additional dependencies, I probably would add passenger as an > optional (development) dependency, so you will have the full feature set on > development machines. In production it will check if if passenger is > available only if it runs in standalone mode. It will not ask for passenger > if someone has decided to use something else, like webrick (personally I > would recommend against webrick, it's not parallel at all which is > important here). > > About the command line tool, I have nothing against it, it should be > available in the gem. > > > > > > On Thu, Sep 14, 2017 at 2:06 PM, Ewoud Kohl van Wijngaarden < > ew...@kohlvanwijngaarden.nl> wrote: > >> On Wed, Sep 13, 2017 at 12:05:49PM -0700, ssht...@redhat.com wrote: >> >>> >>> First attempt to create a design. It's an open discussion, everyone who >>> wants to chime in, please do. >>> >>> The engine: will be deployed as a separate gem. My name suggestion >>> the-detective <https://en.wikipedia.org/wiki/The_Detective_(1968_film)> >>> (Sinatra >>> plays a cop). >>> >>> It will wrap the invocation of rubocop with defaults and parameters >>> needed >>> to support our use case: >>> 1. Support for erb >>> 2. Support for completely customized set of cops. >>> 3. Parametrized list of folders containing cops to be added to the list. >>> >>> In addition it will add tooling to expose a rack endpoint for rubocop >>> invocation: >>> 1. List of all available cops (kind of metadata) >>> 2. A POST method that receives a source file, list of cops, and output >>> format that will return the result of rubocop's analysis. >>> 3. Will be mountable to any Rails application >>> 4. Will have an option to run as a standalone process (probably using >>> passenger with sort-lived process retention settings, since its one >>> process >>> per request nature) >>> >> >> Why should it be a rack endpoint? My thinking was much more of a normal >> ruby API with a command line tool around it. There should be no passenger >> dependency to keep its dependencies small. foreman_templates can consume >> the ruby API and expose it to the user as it wants. >> >> Usage for foreman needs: >>> >>> Use case 1 (community templates CI): >>> 1. Reference the detective gem from templates plugin. >>> 2. Deploy foreman-core with templates plugin enabled. >>> 3. Add rake task that will invoke rubocop on specified folder using >>> detective's invocation wrapper. >>> >> >> Ideally we'd have a light command line tool that does: >> >> detective \ >> --cops /path/to/foreman/checkout/cops \ >> --cops /path/to/katello/checkout/cops \ >> --cops /path/to/other/plugin/with/cops \ >> /path/to/some/template/dir \ >> /path/to/another/template/dir >> >> That way we can do a simple git clone foreman in community-templates, >> bundle install and run it within Travis. This can indeed be wrapped in a >> rake task but given the paths can change on a developers workstation it is >> good to have an easy manual option. >> >> Use case 2 (Validate single template from templates UI) >>> 1. Reference detective gem from templates plugin. >>> 2. Add cops declaration ability to plugins in foreman core >>> 3. Templates plugin is responsible for adding/maintaining detective's >>> endpoint. >>> 4. Foreman core exposes an option to add actions to template editing >>> screen. >>> 5. Templates plugin uses extension point from 4 to add its own action >>> that >>> will invoke detective's endpoint and modify template editor to show the >>> result as linting (it's possible with ace and monaco). >>> >>> Use case 3 (upgrade scenario): >>> As a first step, we can try and report broken templates after the >>> upgrade. >>> It will be pretty similar to community templates CI use case, only the >>> templates code will be exported from user's database. >>> >>> >>> I want to start working on the engine gem as soon as possible, so I would >>> really appreciate any inputs on the process before I have started with >>> this >>> implementation. >>> >>> Shim. >>> >>> >>> >>> On Wednesday, August 30, 2017 at 11:48:09 AM UTC+3, ssh...@redhat.com >>> wrote: >>> >>>> >>>> >>>> After a great talk on community demo >>>> <https://www.youtube.com/watch?v=aOqA8-wpPKQ>, here is a follow up with >>>> the points that were raised during the discussion: >>>> >>>> Use cases: >>>> >>>> 1. Run all cops as part of community templates CI against the whole >>>> repository >>>> 2. Run all cops against a single template invoked by the user from >>>> template editing screen (foreman core) >>>> 3. Upgrade scenario: Preferably run cops for the next foreman version >>>> before the actual upgrade to make sure the templates will remain >>>> valid. >>>> >>>> >>>> Features: >>>> >>>> 1. List of rues should be pluggable [Shim]: It looks like it is a >>>> must-have for the engine. >>>> 2. Deployment options >>>> 1. Engine as a separate gem, cops in a relevant repository - core >>>> cops >>>> in core, plugin cops in plugins. >>>> 2. Engine with all cops in a single gem, versioned per foreman >>>> version. >>>> 3. Engine as part of templates plugin, cops as part of relevant >>>> plugins. >>>> 4. Separate gems for everything: foreman-cops-engine, >>>> foreman-cops-core, foreman-cops-plugin1, foreman-cops-plugin2 >>>> e.t.c. Engine >>>> is versioned per foreman release version (for the sake of rubocop >>>> version), >>>> cops are versioned per plugin version. >>>> >>>> General comments: >>>> >>>> 1. Cops writing should be enforced on PR's that are changing the way >>>> to write templates [mhulan] >>>> 2. Cops are dependent on core/plugin version [gwmngilfen] >>>> >>>> >>>> >>>> >>>> On Monday, August 14, 2017 at 2:29:02 PM UTC+3, ssh...@redhat.com >>>> wrote: >>>> >>>>> >>>>> TL;DR: I have developed a way to scan any template and see if there are >>>>> suspicious/incorrect code patterns in them, so the templates will >>>>> remain >>>>> valid even after foreman code changes. >>>>> >>>>> Recently I have started to think about user created templates and >>>>> foreman >>>>> upgrades. >>>>> >>>>> When user upgrades foreman, hist default templates get upgraded by the >>>>> installer/migrations, but templates created by the user (both cloned >>>>> and >>>>> from scratch) are not touched. >>>>> This could lead to invalid templates and broken provisioning >>>>> functionality for the user. >>>>> Good example for this would be the change >>>>> < >>>>> https://github.com/theforeman/foreman/commit/7b966530c9ba48b2a37416465a3c9619f7143387 >>>>> > >>>>> from calling to <%= foreman_url %> to <%= foreman_url('built') %> >>>>> >>>>> I was looking for a way to inspect any template, in order to identify >>>>> problematic code as soon as the system is upgraded. >>>>> >>>>> I came down to a solution based on rubocop - it's already analyzing >>>>> source files for patterns. >>>>> I have created a POC that analyzes a template written to a file, and >>>>> presents the resulting errors as regular rubocop (clang style). >>>>> All source codes are available as gist: >>>>> https://gist.github.com/ShimShtein/341b746f15826261053e97c2f435ff1a >>>>> >>>>> Small explanation for the gist: >>>>> >>>>> Entry point: inspect_template.rb >>>>> Usage: >>>>> Put everything from the gist to a single folder and execute: >>>>> >>>>> inspect_template /path/to/template_source.erb >>>>>> >>>>> >>>>> This script aggregates all the parts that are needed to create the >>>>> clang-like output. >>>>> >>>>> The process: >>>>> >>>>> 1. Strip all non-ruby text from the template. This is done by >>>>> erb_strip.rb. It turns everything that is not a ruby code into >>>>> spaces, so >>>>> the ruby code remains in the same places as it was in the original >>>>> file. >>>>> 2. Run rubocop with custom rules and erb monkey patch and produce a >>>>> json report >>>>> 1. foreman_callback_cop.rb custom rule file. The most interesting >>>>> line is "def_node_matcher :foreman_url_call?, '(send nil >>>>> :foreman_url)'". Here you define which pattern to look for in the >>>>> AST, in our case we are looking for calls (send) for foreman_url >>>>> method >>>>> without parameters. >>>>> 2. foreman_erb_monkey_patch.rb file: Patches rubocop engine to >>>>> treat *.erb files as source files and not skip them. >>>>> 3. Process the resulting json to convert it to clang style >>>>> highlighting. >>>>> >>>>> Possible usages: >>>>> >>>>> - Scanning all template after foreman upgrade to see that they are >>>>> still valid. >>>>> - Linting a template while while editing. >>>>> - Using rubocop's autocorrect feature to automatically fix offences >>>>> found by this process. >>>>> >>>>> Long shot: we can create custom rules to inspect code for our plugins >>>>> too, especially if we start creating custom rules in rubocop. >>>>> >>>>> I am interested in comments, opinions and usages to see how to proceed >>>>> from here. >>>>> >>>>> >>>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "foreman-dev" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to foreman-dev+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- >> You received this message because you are subscribed to a topic in the >> Google Groups "foreman-dev" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/foreman-dev/KtVSqPKzXjA/unsubscribe. >> To unsubscribe from this group and all its topics, send an email to >> foreman-dev+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "foreman-dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to foreman-dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.