Fix the README CI badge. (#15)
Summary: Signed-off-by: Phil Dibowitz phil@ipom.com
Pull Request resolved: https://github.com/facebook/bookworm/pull/15
Reviewed By: davide125
Differential Revision: D93903852
Pulled By: dafyddcrosby
fbshipit-source-id: 2b5b7a8e4039be95e818b58362755e52c49d5273
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802032778号
fb_bookworm
Bookworm is a program that gleans context from a Chef/Ruby codebase, which recognizes that Ruby source files in different directories have different semantic meaning to a larger program (ie Chef)
It currently runs on top of the Chef Workstation Ruby, although there is nothing preventing running bookworm on vanilla Ruby using bundler, etc.
Usage
Bookworm is designed to be installed via Chef cookbook as well as running directly from the cookbook. This assumes you have at least Chef Workstation 20 installed. If you run this cookbook in a Chef run, it will also install Bookworm into
/usr/local/lib/bookworm(with a shell script launcher at/usr/local/bin/bookworm)Configuring Bookworm
Bookworm currently checks 2 different places for configuration,
~/.bookworm.ymland/usr/local/etc/bookworm/configuration.rb~/.bookworm.yml
A typical bookworm YAML configuration would look something like this:
/usr/local/etc/bookworm/configuration.rb
If you need to programmatically determine what your
source_dirsare (ie if you don’t know what directories Bookworm will be running on ahead of time), you can use/usr/local/etc/bookworm/configuration.rbto setDEFAULT_SOURCE_DIRSandDEFAULT_DEBUG. This might be overkill for your needs, and~/.bookworm.ymlis probably your best bet.Glossary
Bookworm key
A bookworm key is a type of file, and all the information that should be necessary to handle that file throughout the Bookworm pipeline. By encapsulating the “what” and the “how” of a file here, adding new types of files to Bookworm shouldn’t involve more than adding a new key.
Of note, a ‘metakey’ isn’t a file - it could be a concept or a group of files. This is particularly useful with Chef code, since the notion of a ‘cookbook’ is several things, and rather than doing backflips trying to match information to specific files within a cookbook directory, it’s much simpler to say “this cookbook provides this resource/class/attribute.”
Crawler
The crawler is what transforms whatever the key finds into a navigable Ruby representation of the file (for Ruby files, this would be an AST representation of the source file as generated by the rubocop-ast gem).
KnowledgeBase
The KnowledgeBase is the singleton object that holds all Ruby representations of the crawled files, as well as all information derived by the Bookworm rules.
Rule
A ‘rule’ in Bookworm is an auto-generated class that takes the crawled representation of a file and extracts specific information about it. If you want to know about 3 unrelated patterns in a source file, consider using (or writing, if they don’t exist yet) 3 rules. Small rules encourage re-use in reports, and since rules can reference information about a file derived from other rules, this is a good place to do any heavy lifting when figuring out what’s going on with your keys.
InferEngine
The InferEngine runs the necessary rules against each key that was crawled.
Reports
The report takes the information that you’ve extracted from the codebase, and pulls it together into a human or machine-readable representation. While this is a good place to store specific logic for representation, it doesn’t hurt to ask ‘how do I delegate the hard work to rules’ - think of reports as the glue that pulls together a bunch of derived facts into something nice that you can hand to your boss ;-)
Guiding design principles
Implementation notes - Why Rubocop for AST generation
Because we wanted to use something that was already in Chef Workstation, the two choices were Ripper or Parser a la RuboCop (ruby_parser uses racc which has a C extension, but no sexp pattern matcher that I know of).
Ripper is fast, but the sexp output is kind of nasty, and cleaning that up could be a big timesuck. Since the larger Ruby/Chef community has a bit more familiarity with Parser/RuboCop’s node pattern matching, it’d be better to stay with that for now (there’s no reason this couldn’t be migrated later with helpers to translate patterns). Work could also be done to speed up RuboCop (ractor and async support could go a long way here). This repo contains attribute-driven-API cookbooks maintained by Facebook. It’s a large chunk of what we refer to as our “core cookbooks.”
License
See the LICENSE file in this directory