standardrb / standard Goto Github PK
View Code? Open in Web Editor NEWRuby's bikeshed-proof linter and formatter 🚲
License: Other
Ruby's bikeshed-proof linter and formatter 🚲
License: Other
Starting with everything disabled would ensure that:
Get in touch with SublimeLinter and fork or extend SublimeLinter-rubocop
Some messages are way too long:
app/models/system.rb:3:15: Lint/AssignmentInCondition: Use `==` if you meant to do a comparison or wrap the expression in parentheses to indicate you meant to assign in a condition.
Would be nice to monkey patch RuboCop::Cop::Lint::AssignmentInCondition#message
with a shorter message. This is true for other common failures I imagine.
I want to be able to confidently run standard . --fix
or even standard .
and be assured that my project will be conferment and that I will have to do no work. Ideally, this would happen in my editor or a pre-commit hook. It is my belief that if a rule is not auto correctable, it should not be included in the required set of rules. There is still value in some non fixable rules, but they should not be required.
In my experience, rubocop and like minded tools get run very infrequently and often just on CI. In my opinion, this is the very worst time to ask a user to make changes and invites folks who just want to get their PR merged to make less than ideal choices about how to resolve violations that arise. If we limit standard to only auto-correctable violations, I suspect it will get run by most folks very frequently (ideally via an editor plugin). This ensures compliance at all times and completely removes the 11th hour pressure to make poor code quality choices.
There is prior art here as well. The sort of tool I'm describing is becoming commonplace in other languages with tools like Elm's elm-format
, Elixir's mix format
, and Go's gofmt
.
Rubocop fails with an infinite loop detection if you define a class or module with an empty placeholder for protected
or private
.
class Example
protected
# nothing here yet
private
# nothting here yet
end
The class above will trigger this error.
RuboCop::Runner::InfiniteCorrectionLoop: Infinite loop detected in /path/to/file.rb.
Alright, let's talk about the elephant in the room; hash rockets. I get it, the JavaScript-style hash notation with colons is popular, but I still fail to see the benefit over the good, old hash rocket.
@samphippen recently wrote about this and his arguments pretty much reflect my own.
I openly admit to being biased but here are the arguments as I see them:
If we're trying to define a standard set of rules for Ruby code I'd argue consistency is fairly high on the list of goals; not just consistency across projects, but consistency inside each project. Consistency across programming languages, however, is a pipe dream.
Having both {stuff: "symbol"}
and {stuff => "method call"}
because you have to isn't consistent.
Having {"foo": "bar"}["foo"]
return nil
isn't consistent.
Having {O: :O}.inspect
return {:O=>:O}
isn't consistent.
While I do appreciate the aesthetics of the Javascript style notation, my having to type a few extra characters just isn't worth having my hash keys changed for me behind my back.
There is, however, a political side here that should be considered. JavaScript is the popular style du jour and I believe it is used by Rails. Straying from that path might make it more difficult to gain adoption for standard. I can offer no solution to that, unfortunately.
Another issue is future proofing. Will Ruby 3 introduce breaking changes here, deprecating hash rockets, and making it possible to use colons consistently in all cases?
Also, rockets are cool 🚀
Style/TrailingUnderscoreVariable
will "fix" this:
inner, _ = *node
into this:
inner, = *node
The latter looks very hackish, almost a glitch, whereas the explicit ignored param tells a better story.
In addition to #29, which specifies Rails-specific folders be excluded when Rails is detected, Standard should ignore obvious directories. @palkin suggested these, but we should consider what the right set of directories is:
# auto-generated binstubs
- 'bin/*'
# temp files
- 'tmp/**/*'
# node_modules could contain Ruby code
- 'node_modules/**/*'
# vendor/ dir is used by most CI services
- 'vendor/**/*'
Things to consider:
Additionally, we should consider whether these should be limited to .standard.yml
or Gemfile
relative directories. If my pwd
happens to be in app/lib/foo
and I happen to have a app/lib/foo/tmp
directory, I would not want our default ignores to subsequently fail to run against it
Doesn't Rubocop itself have default ignores? Are we skipping those already by din of delegating to RuboCop?
First off, this library is a great idea!
Now for the complaints:
foo = { bar: "baz" }
Layout/SpaceInsideHashLiteralBraces: Space inside } detected.
I just can't live with: {bar: "baz"}
. Just look at it. I know Rails is not the gospel or anything but it is probably Ruby's most read codebase, and I only see hash literals with the space in there.
A poorly formatted, but simple & syntactically correct ruby script:
class Test
def set_page_request_info
{ timeframe: { ending: session[:ending] ? session[:ending] : nil,
duration: session[:duration] ? session[:duration] : nil,
comparison: session[:comparison] ? session[:comparison] : nil
},
}
end
end
› ruby -c foo.rb
Syntax OK
› standardrb --fix -- foo.rb
standard: Use Ruby Standard Style (https://github.com/testdouble/standard)
standard: Run `standardrb --fix` to automatically fix some problems.
foo.rb:5:61: Lint/Syntax: unexpected token tCOMMA (Using Ruby 2.4 parser; configure using `TargetRubyVersion` parameter, under `AllCops`)
Notice: Disagree with these rules? While StandardRB is pre-1.0.0, feel free to submit suggestions to:
https://github.com/testdouble/standard/issues/new
An extra comma get inserted at the end of the hash, and this is no longer legal Ruby.
class Test
def set_page_request_info
{timeframe: {ending: session[:ending] || nil,
duration: session[:duration] || nil,
comparison: session[:comparison] || nil},,}
end
end
› ruby --version
ruby 2.4.5p335 (2018-10-18 revision 65137) [x86_64-darwin18]
› standardrb --version
0.0.23
I don't know anything about writing RubyMine extensions, and it looks like RuboCop integration comes out of the box, so I'm unsure how to proceed. Any ideas?
Presumably, we'll want to fork or (less invasively) extend the codeclimate-rubocop engine. I'd really like the opinion of someone from Code Climate's input on how to best do this (cc/ @brynary 🙇♂️)
The spec for writing custom engines is here
It'd be great if users could easily wire Standard to Hound CI. I'm not sure based on the docs how to proceed or who to contact. cc/ @salbertson, maybe?
Hey @searls)
Replying to https://twitter.com/searls/status/1066359371599360000.
[offtopic] Btw, what about having a dedicated issue for feedback and proposals (e.g. this one)?
I've added standard
to the project I'm currently working on right after your LT at RubyConf (it was great, thank you).
I'm using it as a default RuboCop config (not as a standalone tool):
# .rubocop.yml
require:
- standard/cop/semantic_blocks
inherit_gem:
standard: config/base.yml
Why? For several reasons:
standard
.I'm not sure that standard
config should handle custom plugin integration–looks like an overkill to me. Using RuboCop with standard
config (like we do) works fine.
Thus, I suggest adding a documentation on how to use standard config with RuboCop for advanced usage.
Btw, there was an idea to add presets functionality to RuboCop (see rubocop/rubocop#5612); maybe, in the future, standard
could be a RuboCop preset and not a wrapper.
Ok, my config is a little bit more complicated:
inherit_from: "./rspec.yml"
require:
- standard/cop/semantic_blocks
inherit_gem:
standard: config/base.yml
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: no_comma
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: no_comma
I know the reasoning behind the trailing comma, but I still cannot unlearn using this style. And I don't think this style is popular among Rubyists (I've never seen it in any project); for me it looks like something from JS world)
Maybe, the reason this style is not popular is that RuboCop by default enforces no_comma
.
What about having a config param to control this behaviour (say trailing_comma: yes | no
) or disable these cops at all?
Another holy-war-ish thing, IMO. And could block the adoption of standard
(one-liner vs. multi-liner rule is much simpler).
TBH, I haven't heard about this style ever (being a RuboCop user and contributor for more than three years).
So, in my config I turned this cop off (the fear of unknown 🙀).
Btw, there is a proposal to add this style to RuboCop as a config option to Style/BlockDelimiters
. Having this in RuboCop itself seems like a better idea than adding a custom cop along with the standard
.
Although standard
allows to configure ignore paths, it would be great if it has some default values which could cover most use-cases–so you can run standard
without adding a configuration at all.
My default ignore list looks like this:
AllCops:
Exclude:
# auto-generated binstubs
- 'bin/*'
# temp files
- 'tmp/**/*'
# node_modules could contain Ruby code
- 'node_modules/**/*'
# vendor/ dir is used by most CI services
- 'vendor/**/*'
Anyone who uses both tools is going to have two 'standard' binaries, which seems very bad. I humbly suggest the name 'nonstandard'.
If I call standardrb with: standardrb --format json > output.json
, the message about disagreeing with defaults is in the output at the end, which prevents a direct parse of that json file, without further preprocessing.
I'd be happy to fix this myself, but not sure the approach you'd like.
1️⃣ STDERR for the message
2️⃣ Don't output the message on an explicit format flag
3️⃣ Something else?
Adding standard to a gem I'm building, I ran bundle exec standard --fix
and my default Gemfile was changed from:
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
to:
git_source(:github) do |repo_name| "https://github.com/#{repo_name}" end
Would we expect standard to decipher or try to determine white space there?
Let's send a PR to https://github.com/w0rp/ale to add support for standardrb
and standardrb --fix
.
I just sent in a PR for one of our apps to try out standard, and I wanted to share the overrides I made.
This one rewrote all extend self
with module_function
which worked for half of my modules, but broke for the ones where I was using private methods in the module. To be honest, the introduction of module_function
went completely past me, so I haven't seen the arguments in favor of it, but this was one of two autofixs that did break my code.
This was the other one that broke me, the auto fix dropped all my single quotes in the percent string arrays. In CSP headers, you need to have single quotes, and this went ahead and removed them all. I use %w[]
arrays otherwise it's a lot harder to read
font_src: %w['self' data:],
form_action: %w['self'],
style_src: %w['self' 'unsafe-inline'],
vs
font_src: ["'self'", "data:"],
form_action: ["'self'"],
style_src: ["'self'", "'unsafe-inline'"],
This one prevented making a single database table method private that we're later exposing as better named readers
private :price_per_month # rubocop:disable Style/AccessModifierDeclarations
def price_per_month_dollars
price_per_month
end
def price_per_month_cents
price_per_month * 100
end
I should probably do a migration and rename the column I suppose, but you know, work. I'm not strongly advocating to remove this one, but it sometimes nice to later make a method private.
The other ones were for rspec, and 2 other single spot places that aren't worth mentioning
Just ran this on a project, and the majority of changes I can live with, one thing that I didn't agree with was that that frozen_string_literal
magic comments were stripped. I can totally see this thing taking a neutral attitude on frozen_string_literal
, but if they're already there it should probably leave them alone?
We did see rather substantial memory savings due to adding the frozen string command. I'm aware that there is a flag you can set to freeze all string literals, but this is problematic because flags are non-local, and also it can be a fiddly to ensure that the flag is always set, both in dev/test/ci/production.
› ls -l lib/*.rb | wc -l
28
› standardrb lib
No output, not even the post-check notice. --format json
says 0 files checked.
This works fine - shows I have things to fix.
› standardrb lib/histogram.rb
standard: Use Ruby Standard Style (https://github.com/testdouble/standard)
standard: Run `standardrb --fix` to automatically fix some problems.
lib/histogram.rb:45:9: Layout/DotPosition: Place the . on the previous line, together with the method call receiver.
lib/histogram.rb:57:23: Layout/SpaceAfterComma: Space missing after comma.
lib/histogram.rb:58:19: Layout/SpaceBeforeBlockBraces: Space missing to the left of {.
lib/histogram.rb:60:1: Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body end.
Notice: Disagree with these rules? While StandardRB is pre-1.0.0, feel free to submit suggestions to:
https://github.com/testdouble/standard/issues/new
A more explicit glob pattern appears to work:
standardrb "./lib/**/*.rb"
# ... lots of correct output
› standardrb --version
0.0.24
› ruby --version
ruby 2.4.5p335 (2018-10-18 revision 65137) [x86_64-darwin18]
I generally think this is a good practice; however, consider the following Rails controller action.
class ExamplesController < ApplicationController
before_action :set_example, except: [:index]
...
def set_example
@example ||= Example.find(params[:id])
end
end
This will produce the following error.
Naming/MemoizedInstanceVariableName: Memoized variable @example does not match method name set_example. Use @set_example instead.
@example ||= Example.find(params[:id])
^^^^^^^^
Standard delegates target_ruby || RUBY_VERSION
to Rubocop's TargetRubyVersion
but since we're already parsing it into a Gem::Version
, I think it would be interesting to attempt to target an old ruby like 1.8 while running a minimum ruby version like 2.2. This would specifically to be to support gems that still support old Rubies like RSpec & Bundler, as well as gems like Suture designed specifically to help people upgrade old code
This will take some spelunking b/c it cuts across several rules:
But indenting rescue inside a method seems good. As does an explicit begin
. If you're going to indent access modifiers I don't get the justification for outdenting rescue
.
Hi! I applied standardrb
to a project (love it ❤️) and I noticed this code didn't get corrected with the semantic block cop:
{
foo: [].map do
nil
end,
}
Should this case be supported? Thanks!
Submit a PR to vscode-ruby adding Standard support
https://rubocop.readthedocs.io/en/latest/cops_style/#stylecollectionmethods
Current standard
option is: disabled
Proposed change: enabled, default RuboCop mapping for PreferredMethods (e.g. favor find
over detect
)
👋
Recent turned on this cop because it is annoying when someone wants to use the more obscure SmallTalk-inspired enumerable methods (inject
, collect
, detect
, etc) and another person likes the more commonly used methods (select
, find
, map
, etc). The later also maps more closely to other languages you might be using (namely ES6).
I see no reason to prefer the SmallTalk-style nor to spend time debating which one to use.
Downsides:
detect
-- can't say that I really care about that kind of micro-optimizing, but that might not be true for the majorityWe were looking to integrate this into our CI suite as a "is formatting needed?" check, but we couldn't figure out a clean way to do that. I think it would be useful if we could enforce the style guide by making it part of the CI flow.
Crystal has a format
tool that uses a --check
option for this which returns a non-zero exit code if any formatting/linting is necessary, but doesn't actually do formatting itself:
https://github.com/crystal-lang/crystal/blob/master/src/compiler/crystal/command/format.cr#L26
That's one way to go about it, but whatever the solution I think it would be useful to have a way to fail CI if formatting is needed.
Make it super easy to add a linting rake task.
This also helps with #3 to resolve cli collision.
I'm not sure this should be fixed, but it came up today with a Rails migration.
Given this migration:
create_table :customers do |t|
t.timestamps
end
It wants to autofix it (Style/SymbolProc cop) to:
create_table :customers, &:timestamps
I get it, but in a migration it seems weird to stray from the t.
DSL.
I think timestamps
is the only method without arguments, so this should be very rare. I hate to disable a cop for a whole directory, seems like overkill. Figured I'd raise the issue though.
$ bundle exec standard
standard: Use Ruby Standard Style (https://github.com/testdouble/standard)
standard: Run `standard --fix` to automatically fix some problems.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:11:24: Style/PercentLiteralDelimiters: `%q`-literals should be delimited by `(` and `)`.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:11:24: Style/UnneededPercentQ: Use `%q` only for strings that contain both single quotes and double quotes.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:12:24: Style/PercentLiteralDelimiters: `%q`-literals should be delimited by `(` and `)`.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:12:24: Style/UnneededPercentQ: Use `%q` only for strings that contain both single quotes and double quotes.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:16:16: Layout/ExtraSpacing: Unnecessary spacing detected.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:16:22: Layout/SpaceAroundOperators: Operator `=` should be surrounded by a single space.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:26:13: Layout/ExtraSpacing: Unnecessary spacing detected.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:26:22: Layout/SpaceAroundOperators: Operator `=` should be surrounded by a single space.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:26:51: Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/etalon.gemspec:40:3: Gemspec/OrderedDependencies: Dependencies should be sorted in an alphabetical order within their section of the gemspec. Dependency `byebug` should appear before `yard`.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/Gemfile:3:21: Style/BlockDelimiters: Prefer `do...end` over `{...}` for procedural blocks.
/Users/olivierlacan/Library/Mobile Documents/com~apple~CloudDocs/Development/perso/etalon/spec/spec_helper.rb:16:9: Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
If you agree it'd be nice to find Dir.pwd
and truncate anything beyond that so this becomes:
$ bundle exec standard
standard: Use Ruby Standard Style (https://github.com/testdouble/standard)
standard: Run `standard --fix` to automatically fix some problems.
etalon.gemspec:11:24: Style/PercentLiteralDelimiters: `%q`-literals should be delimited by `(` and `)`.
etalon.gemspec:11:24: Style/UnneededPercentQ: Use `%q` only for strings that contain both single quotes and double quotes.
...
We currently print standard: Run
standardrb --fix to automatically fix some problems.
unnecessarily. Stop printing it when:
--fix
was used in the run (fixed by #69)Code is in the lib/standard/formatter.rb
Currently the autocorrector of Lint/UnusedBlockArgument
(and its equivalents) will prepend a _
in front of any unused variable.
Example:
items.each_with_index do |item, i|
puts item
end
Will be autocorrected to:
items.each_with_index do |item, _i|
puts item
end
That _i
seems bizarre and out of place, and I've never seen a human write Ruby like this to indicate a variable is unused. If we override the autocorrector to just change the variable to _
, would it be any less safe? If that change would not be safe, should we just turn off this cop?
My case for leading dots on method chains:
.foo
as perform foo on our data
but foo.
is apply foo (to our data depending on if the previous line has a dot at the end) and...
.I read code and PRs more than copy-pasting into a repl, so while I understand the value in trailing dots for that case, it doesn't have as much weight for me personally.
Thanks for this!
require "open-uri"
open "https://github.com/testdouble/standard/issues" do |page|
# logic ...
end
The above code will trigger the following warning.
The use of `Kernel#open` is a serious security risk.
I would like to use Ruby 1.9 hash syntax everywhere, but for a Rails app that doesn't seem possible for some routes.rb
entries, e.g.
get "contact" => "pages#contact", as: "contact"
I wonder if it would make sense to allow mixed keys for this file only?
Hey @searls, hope you're well!
I love the idea of this and am generally supportive. I thought I'd start comparing to my own set of rubocop styles and make a case for ones I have configured for reasons I believe to be tied to code quality/readability/etc vs just "because I like the way it looks"
First on my list, Style/AccessModifierDeclarations
.
I believe a mis-feature in Ruby is that accessibility modifiers are stateful, in that once private
is called, all methods defined later in the module/class have their accessibility modified. Various ways of identifying non-public methods have come and fallen out of vogue over the years, like the indent-an-extra-2-spaces pattern, but none of them really help you understand any given method in context, without scrolling up.
In my codebase(s), I have a strict rule of:
# In-lining access modifiers removes risk of accidentally changing access level
# when re-ordering methods and improves clarity about method access
Style/AccessModifierDeclarations:
EnforcedStyle: inline
This affects code like so:
class BadStyle
def public_1; end
private
def private_1; end
def private_2; end
protected
def protected_1; end
private
def private_3; end # wat
public
def public_2; end # wat
end
class BetterStyle
def public_1; end
private def private_1; end
private def private_2; end
protected def protected_1; end
private def private_3; end
def public_2; end
end
I know this can be somewhat un-Rubyish and more like other languages, but I think it's clearly superior. It keeps accessibility scope tied directly to the method(s) it should effect and it limits their effect to only those methods; it is more immune to inadvertent changes in accessibility during refactoring; and it makes is always much clearer what accessibility the current, in-view method is at all times.
This doesn't work on older Rubies, though I don't recall which versions exactly. It works for every Ruby in which def
returns the symbol name of the method just defined, so is equivalent to:
def x
end
private :x
What do you think?
N.B. I just got out of collar bone surgery a few hours ago so I might be a tad out of it. So, if any of this doesn't make sense or isn't persuasive, I'd be very happy to follow up with any questions, comments, or objections.
Fork rubocop-emacs, maybe?
What do you think about checking if Rails is being used and ignore these files by default:
ignore:
- 'bin/**/*'
- 'db/schema.rb'
- 'tmp/**/*'
Less config, more drop-in. I can try to make a PR if you think this is useful :)
standardrb
reports
Lint/UnneededCopDisableDirective: Unnecessary disabling of `RSpec/ExampleLength` (unknown cop).
I expect other RuboCop plugins might have similar issues.
Consider the following named scope in a Rails model.
class User < ApplicationRecord
scope :with_name, ->(value) do
first_name, last_name = value.to_s.split(" ")
where first_name: first_name, last_name: last_name
end
end
This produces the following offense.
Style/Lambda: Use the lambda method for multiline lambdas.
The required fix doesn't seem better than the original.
class User < ApplicationRecord
scope :with_name, (lambda do |value|
first_name, last_name = value.to_s.split(" ")
where first_name: first_name, last_name: last_name
end)
end
Not a deal breaker, but since it is pre-release....
if post = Post.find_by(id: id)
end
Generates a warning about AssignmentInCondition. The fix is to just wrap it in parentheses, but i just hate the look of
if (post = Post.find_by(id: id))
end
For now, I will likely just add an extra line:
post = Post.find_by(id: id)
if post
end
I would love to see an option to allow simple assignments to pass.
Thanks,
Scott
It's really irritating when in a block and:
do |lol|
if lol.good?
# do stuff
end
end
is corrected as wrong with:
do |lol|
next unless lol.good?
# do stuff
end
If this rule only applied to first line guard clauses I'd be cool, but sometimes you're 5 lines into a block and suddenly it's being broken out of with a "next" halfway down
Talk to someone from AtomLinter and fork or extend linter-rubocop
In my experience, when I use [N].times.map
, it is nearly always when N is a small number less than 5. In all the cases I found in the codebase I'm currently working in, I found readability was hurt by this rule far more than performance would have been saved.
What do you think about shutting this rule off?
Not sure if an issue is the best place to ask, but does anyone have advice on how to hook this up with https://github.com/w0rp/ale ? It already has support for rubocop, so I imagine it's doable, but I'm bad at vimscript :(
Our combination of trailing comma + not forcing freeze is triggering a pretty nasty autocorrect bug: rubocop/rubocop#6498
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.