Skip to content
This repository has been archived by the owner on Sep 5, 2020. It is now read-only.

Commit

Permalink
Merge c3fa8e8 into 7b58936
Browse files Browse the repository at this point in the history
  • Loading branch information
natecavanaugh committed Sep 18, 2017
2 parents 7b58936 + c3fa8e8 commit 1dacc0d
Show file tree
Hide file tree
Showing 131 changed files with 19,287 additions and 2,329 deletions.
26 changes: 26 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
test
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
10 changes: 5 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
language: node_js
node_js:
- "5.0"
- "4.0"
- "0.12"
- "0.11"
- "0.10"
- "8"
- "7"
- "6"
- "5"
- "4"
after_success:
- npm run coveralls
168 changes: 159 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ check-source-formatting
### Jump to Section

- [Description](#description)
- [What's new](#whats-new)
- [Installation](#installation)
- [Usage](#usage)
- [Options](#options)
- [Sublime Text Integration](#sublime-text-integration)
- [Custom configuration](#custom-configuration)
- [Known issues](#known-issues)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -54,6 +56,19 @@ This will scan through HTML(-like) files, JS files, and CSS files and detect man
- Variable names starting with `is` (it ignores methods, which is valid, but properties and variables should not have a prefix of `is`)
- **Experimental** Will try to parse JavaScript inside of <aui:script> blocks

## What's new
As of v2, there are a few new features:

- [Custom configuration](#custom-configuration)
- Custom configuration on a per file basis or using globs
- New, [shorter command](#v2-deprecation-notice): `csf`
- Now able to check on both ES6+ and JSX syntaxes
- Uses stylelint for CSS checking, which should reduce false positives
- Now requires Node 4+

### API Changes
For any consumers of the API, there was previously no way to know when the CLI object had finished reading the files and reporting the errors, whereas now, `cli.init()` returns a promise so you can run anything you want to after everything has been processed.

## Installation

```
Expand All @@ -62,33 +77,39 @@ This will scan through HTML(-like) files, JS files, and CSS files and detect man

## Usage

### V2 Deprecation notice:
> The `check_sf` command is now deprecated in favor of the new `csf` command.
> They're identical (though `check_sf` will periodically warn you that it's deprecated), but `check_sf` will be removed in the next major version.
The simplest way to run it is:

```
check_sf path/to/file
csf path/to/file
```

However, you can also check multiple files at once:

```
find . -name '*.css' | xargs check_sf
find . -name '*.css' | xargs csf
```

I find it easier to use it with pull requests and check the files that were changed on the branch.
In my .gitconfig I have:

```
sfm = "!f() { git diff --stat --name-only master.. | grep -E '.(jsp.?|vm|ftl|tag|tpl|tmpl|js|soy|hbs|(s)?css)$' | tr \"\\n\" \"\\0\" | xargs -0 -J{} check_sf {} $@; }; f"
sfm = "!f() { git diff --stat --name-only master.. | tr \"\\n\" \"\\0\" | xargs -0 -J{} csf {} $@; }; f"
```

(You could get rid of the grep portion, but I find it easier to just filter them out on this level).

When someone sends me a pull request, I check out the branch and run `git sfm` and it scans the changed files and reports any issues.

## Options

There are some options that you can pass to the command:

`--config` If you pass this flag with a path to a configuration file, it will use that one instead of looking up one.

If you pass `--no-config`, it will disable any custom configuration look ups, and only use the defaults.

`-q, --quiet` will set it so that it only shows files that have errors. By default it will log out all files and report 'clear' if there are no errors.

`-o, --open` If you have an editor specified in your gitconfig (under user.editor), this will open all of the files that have errors in your editor.
Expand All @@ -112,7 +133,7 @@ If you pass `--no-lint` it will overwrite the default and disable linting.
This is mainly useful when you want to show the file name relative to your current working directory.
I use it mainly when I'm running this on a git branch. In order for it to work from your alias, you would need to change the above alias to be:
```
sfm = "!f() { export GIT_PWD=\"$GIT_PREFIX\"; git diff --stat --name-only master.. | grep -E '.(jsp.?|vm|ftl|tag|tpl|tmpl|js|(s)?css)$' | xargs check_sf $@; }; f"
sfm = "!f() { export GIT_PWD=\"$GIT_PREFIX\"; git diff --stat --name-only master.. | tr \"\\n\" \"\\0\" | xargs csf $@; }; f"
```

`-v, --verbose` This will log out any possible error, even ones that are probably a false positive.
Expand All @@ -128,7 +149,7 @@ However, passing -v will show these errors (marked with a **).

If you pass `--no-color` it will overwrite the default and give you plain text.

`--lint-ids` Previously, all errors that were generated by ESLint included their rule ID in the error message. This is no longer true by default (as it adds a lot of noise), but you can turn it on by adding this option.
`--lint-ids` Previously, all errors that were generated by ESLint or stylelint included their rule ID in the error message. This is no longer true by default (as it adds a lot of noise), but you can turn it on by adding this option.

`-m`, `--check-metadata` If we're inside of a portal repository, and one of the files is in the /html/js/liferay/ directory, check all of the modules in that directory, and see if the requires metadata in the files matches the metadata in the modules.js file.

Expand All @@ -142,11 +163,12 @@ There are now two ways you can integrate this module with Sublime Text:
### As a build system
You can setup a build system in Sublime Text to run the formatter on the file you are working in, and this is the simplest of the options.
You can set up your build system using the following steps:

- Go to the menu labeled Tools > Build System > New Build System
- Use the following code for the new build system and save the file
- Use the following code for the new build system and save the file<br />
```
{
"shell_cmd": "check_sf $file"
"shell_cmd": "csf $file"
}
```
- Go to Tools > Build System and select the system you created
Expand All @@ -159,13 +181,141 @@ You can also use [Sublime Linter](http://www.sublimelinter.com/en/latest/) to vi
[![Sublime Linter](/../screenshots/images/sublime_linter.png?raw=true "Sublime Linter")](https://packagecontrol.io/packages/SublimeLinter-contrib-check-source-formatting)

You can install it via a couple of steps:

- Install [Sublime Linter](http://www.sublimelinter.com/en/latest/) via Package Control
- Install the [SublimeLinter-contrib-check-source-formatting](https://packagecontrol.io/packages/SublimeLinter-contrib-check-source-formatting) package via Package Control
- In order to get it to lint, you may need to either manually lint it (in the Command Palette, type "Lint this view" and select it), or you may wish to change when it lints (in the Command Palette again, type "Choose Lint Mode", and select when you want it to lint the file).

You can read more on [the project page](https://packagecontrol.io/packages/SublimeLinter-contrib-check-source-formatting).
Thanks to [Drew Brokke](https://github.com/drewbrokke) for writing the plugin and publishing it.

### As an Atom Linter plugin

- Install [liferay-linter](https://atom.io/packages/linter-liferay) via `apm install linter linter-liferay`

You can read more on [the github page](https://github.com/mthadley/linter-liferay).
Thanks to [Michael Hadley](https://github.com/mthadley) for writing the plugin and publishing it.

## Custom configuration
Starting in version 2, you can now customize the configuration of the engine in a few different ways.
Here are the items you can currently customize:

- ESLint rules
- stylelint rules

I'm planning on expanding this into more areas, but currently those are the two sections that can be modified.

How do you define a custom configuration?

We are currently using [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) to look for configuration files, which means you can define custom configuration by adding any one of the following files somewhere in the current working directory or one of the parent directories:

- Inside of `package.json`, using a custom key of `csfConfig`
- `csf.config.js`
- `.csfrc` in JSON or YAML format

What does the structure of the configuration look like?

Let's say we create a `.csf.config.js` file, our configuration, at the very least, should export a JSON object like so:

```
module.exports = {};
```

Here is an example of a config with all keys defined:

```
module.exports = {
css: {
lint: {}
},
js: {
lint: {}
},
html: {
css: {
lint: {}
},
js: {
lint: {}
}
},
'path:**/*.something.js': {
js: {
lint: {}
}
}
};
```

(please note, if using one of the JSON files, you'll need to quote the Object keys, however, there are some benefits to using a plain JS file, which I'll mention below).

And here are the descriptions of what they do:

- `css.lint` - These accept any option that can be passed to [stylelint](https://stylelint.io/user-guide/configuration/#rules), which is really just the rule configuration.<br />
This means anywhere the lint object is called, you can set the rules.
- `lint` - These accept any option that can be passed to [ESLint](http://eslint.org/docs/user-guide/configuring), you can set here. This includes any environment or globals you wish to define, rules you wish to define, etc.<br />
This means anywhere the lint object is called, you can set the rules.<br />
The `html.css.lint` property is only applied for style blocks inside of HTML-like files that go through the HTML formatter. This property is merged on top of anything specified in `css.lint`.<br />
The `html.js.lint` property is only applied for script blocks inside of HTML-like files that go through the HTML formatter. This property is merged on top of anything specified in `js.lint`.

You'll also notice that a key there of `path:**/*.something.js`. This allows you to specify a configuration to a specific file path, or a glob referencing a file path.<br />
Any files matching that glob will apply those rules on top of the ones inside of `css.lint`, `js.lint`, `html.css.lint`, and `html.js.lint`.

#### Benefits to using `.js` over `.json`?
As I mentioned before, there are some benefits to using a `.js` file, but mainly is that it's less strict about what can go inside of the file, so you can use comments, and unquoted keys.
But also, any configuration you define with a function as the value, that function will be executed, and anything you return from there will be used as the value.
This means you can dynamically configure the script at runtime.

### Using ESlint plugins
You can configure ESLint to leverage specific plugins for your project.
The way you would do this is slightly hokey, but it's because ESLint only looks for plugins next to where eslint itself is installed. Because of this limitation, we need a path to the plugin you wish to use.

Here's how you would set it up to use, let's say the [Lodash eslint plugin](https://www.npmjs.com/package/eslint-plugin-lodash):

1. In your project, run the following command:<br />
```
npm install --save-dev eslint-plugin-lodash
```
2. In your configuration file, add the following:
```
{
"js": {
"lint": {
"plugins": ["./node_modules/eslint-plugin-lodash"]
}
}
}
```
3. Then, in the same block, you can configure any rules from the plugin by adding a `rules` object, and configuring it like so:
```
{
"js": {
"lint": {
"plugins": ["./node_modules/eslint-plugin-lodash"],
"rules": {
"lodash/prefer-noop": 2
}
}
}
}
```

Right now, it's not possible to use stylelint plugins, but I'll be adding support for that soon.
You can still, however, configure the rules included with stylelint.

### JSX and ES6/7
We include the [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) by default, but we only turn it on for projects that are using JSX syntax (whether it's React or [MetalJS](http://metaljs.com)), but you need to explicitly opt into ES6 or above in your configuration.
We currently handle es7 code, but we don't enable any of the future focused rules such as [prefer-template](http://eslint.org/docs/rules/prefer-template), unless you set your lint.parserOptions.ecmaVersion to 7 in your config file.
This is how you would do it:
```
"lint": {
"parserOptions": {
"ecmaVersion": 7
}
}
```
Once you have that set, it will enable the react plugin rules for JSX syntax checking, and for upgrading your code to more future focused syntax.

## Known issues
The following are known issues where it will say there's an error, but there's not (or where there should be an error but there's not)

Expand Down
38 changes: 31 additions & 7 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
#!/usr/bin/env node
#!/bin/sh
":" //# http://sambal.org/?p=1014 ; exec /usr/bin/env node --harmony "$0" "$@"

var ConfigStore = require('configstore');
var updateNotifier = require('update-notifier');

var notifier = updateNotifier(
{
pkg: require('../package.json')
}
);
var deprecationCheck = require('../lib/deprecation');

var pkg = require('../package.json');

var notifier = updateNotifier({pkg});

if (notifier.update) {
notifier.notify();
}

require('../lib/cli').init();
var config = new ConfigStore(
pkg.name,
{
lastPackageVersion: pkg.version,
lastUpdateCheck: Date.now()
}
);

var cli = require('../lib/cli').init().then(
function() {
var deprecated = deprecationCheck(
{
config,
pkg,
scriptName: process.argv[1]
}
);

if (deprecated) {
console.log(deprecated);
}
}
);
Loading

0 comments on commit 1dacc0d

Please sign in to comment.