Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce ESLint (JavaScript linting) with pre-commit hooks #11699

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,32 @@ repos:
language: node
files: ^airflow/www/.*\.(css|scss|sass)$
# Keep dependency versions in sync w/ airflow/www/package.json
additional_dependencies: ['[email protected]', '[email protected]']
additional_dependencies:
- [email protected]
- [email protected]
- id: eslint
name: ESLint
entry: "eslint"
args:
- --config
- airflow/www/.eslintrc
- --ignore-path
- airflow/www/.eslintignore
- --resolve-plugins-relative-to
- airflow/www/node_modules/
language: node
files: ^airflow/www/.*\.(js|jsx)$
# Keep dependency versions in sync w/ airflow/www/package.json
additional_dependencies:
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- id: mermaid
name: Generate mermaid images
entry: ./scripts/ci/pre_commit/pre_commit_mermaid.sh
Expand Down
2 changes: 1 addition & 1 deletion BREEZE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2001,7 +2001,7 @@ This is the current syntax for `./breeze <./breeze>`_:
check-apache-license check-builtin-literals check-executables-have-shebangs
check-hooks-apply check-integrations check-merge-conflict check-xml
consistent-pylint daysago-import-check debug-statements detect-private-key doctoc
dont-use-safe-filter end-of-file-fixer fix-encoding-pragma flake8 forbid-tabs
dont-use-safe-filter end-of-file-fixer eslint fix-encoding-pragma flake8 forbid-tabs
helm-lint incorrect-use-of-LoggingMixin insert-license isort language-matters
lint-dockerfile lint-openapi mermaid mixed-line-ending mypy mypy-helm
no-relative-imports pre-commit-descriptions provide-create-sessions pydevd
Expand Down
2 changes: 2 additions & 0 deletions STATIC_CODE_CHECKS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ require Breeze Docker images to be installed locally:
----------------------------------- ---------------------------------------------------------------- ------------
``end-of-file-fixer`` Makes sure that there is an empty line at the end.
----------------------------------- ---------------------------------------------------------------- ------------
``eslint`` Checks JS files with ESLint.
----------------------------------- ---------------------------------------------------------------- ------------
``fix-encoding-pragma`` Removes encoding header from python files.
----------------------------------- ---------------------------------------------------------------- ------------
``flake8`` Runs flake8. *
Expand Down
14 changes: 13 additions & 1 deletion airflow/www/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
{
"extends": "airbnb-base",
"parser": "babel-eslint",
"plugins": [ "html" ]
"plugins": [
"html",
"import",
"node",
"promise",
"standard",
],
"settings": {
"import/resolver": {
"node": {},
"webpack": {},
},
},
}
3 changes: 2 additions & 1 deletion airflow/www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"dev": "NODE_ENV=dev webpack --watch --colors --progress --debug --output-pathinfo --devtool eval-cheap-source-map --mode development",
"prod": "NODE_ENV=production node --max_old_space_size=4096 ./node_modules/webpack/bin/webpack.js -p --colors --progress",
"build": "NODE_ENV=production webpack --colors --progress",
"lint": "eslint --ignore-path=.eslintignore --ext .js,.html .",
"lint": "eslint --ignore-path=.eslintignore --ext .js .",
"lint:fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.html ."
},
"author": "Apache",
Expand Down Expand Up @@ -37,6 +37,7 @@
"css-loader": "^3.4.2",
"eslint": "^7.5.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-import-resolver-webpack": "^0.13.0",
"eslint-plugin-html": "^6.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-node": "^11.1.0",
Expand Down
54 changes: 27 additions & 27 deletions airflow/www/static/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
/* global $, moment, Airflow, window, localStorage, document */
/* global $, moment, Airflow, window, localStorage, document, hostName, csrfToken */

import {
dateTimeAttrFormat,
Expand All @@ -27,7 +27,8 @@ import {

window.isoDateToTimeEl = isoDateToTimeEl;

// We pull moment in via a webpack entrypoint rather than import so that we don't put it in more than a single .js file. This "exports" it to be globally available.
// We pull moment in via a webpack entrypoint rather than import so that we don't
// put it in more than a single .js file. This "exports" it to be globally available.
window.moment = Airflow.moment;

function displayTime() {
Expand All @@ -47,57 +48,56 @@ function changDisplayedTimezone(tz) {
});
}

var el = document.createElement('span');

export function escapeHtml(text) {
const el = document.createElement('span');
el.textContent = text;
return el.innerHTML;
}

window.escapeHtml = escapeHtml;

export function convertSecsToHumanReadable(seconds) {
var oriSeconds = seconds;
var floatingPart = oriSeconds- Math.floor(oriSeconds);
export function convertSecsToHumanReadable(secs) {
const oriSeconds = secs;
Copy link
Member

@mik-laj mik-laj Oct 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have Babel? I know there were some compatibility issues with older browsers.

const floatingPart = oriSeconds - Math.floor(oriSeconds);

seconds = Math.floor(seconds);
let seconds = Math.floor(secs);

var secondsPerHour = 60 * 60;
var secondsPerMinute = 60;
const secondsPerHour = 60 * 60;
const secondsPerMinute = 60;

var hours = Math.floor(seconds / secondsPerHour);
seconds = seconds - hours * secondsPerHour;
const hours = Math.floor(seconds / secondsPerHour);
seconds -= hours * secondsPerHour;

var minutes = Math.floor(seconds / secondsPerMinute);
seconds = seconds - minutes * secondsPerMinute;
const minutes = Math.floor(seconds / secondsPerMinute);
seconds -= minutes * secondsPerMinute;

var readableFormat = '';
let readableFormat = '';
if (hours > 0) {
readableFormat += hours + 'Hours ';
readableFormat += `${hours}Hours `;
}
if (minutes > 0) {
readableFormat += minutes + 'Min ';
readableFormat += `${minutes}Min `;
}
if (seconds + floatingPart > 0) {
if (Math.floor(oriSeconds) === oriSeconds) {
readableFormat += seconds + 'Sec';
readableFormat += `${seconds}Sec`;
} else {
seconds += floatingPart;
readableFormat += seconds.toFixed(3) + 'Sec';
readableFormat += `${seconds.toFixed(3)}Sec`;
}
}
return readableFormat;
}
window.convertSecsToHumanReadable = convertSecsToHumanReadable;

function postAsForm(url, parameters) {
var form = $('<form></form>');
const form = $('<form></form>');

form.attr('method', 'POST');
form.attr('action', url);

$.each(parameters || {}, function(key, value) {
var field = $('<input></input>');
$.each(parameters || {}, (key, value) => {
const field = $('<input></input>');

field.attr('type', 'hidden');
field.attr('name', key);
Expand All @@ -106,7 +106,7 @@ function postAsForm(url, parameters) {
form.append(field);
});

var field = $('<input></input>');
const field = $('<input></input>');

field.attr('type', 'hidden');
field.attr('name', 'csrf_token');
Expand All @@ -130,7 +130,7 @@ function initializeUITimezone() {

function setManualTimezone(tz) {
localStorage.setItem('chosen-timezone', tz);
if (tz == local && tz == Airflow.serverTimezone) {
if (tz === local && tz === Airflow.serverTimezone) {
$('#timezone-manual').hide();
return;
}
Expand Down Expand Up @@ -211,11 +211,11 @@ $(document).ready(() => {
setInterval(displayTime, 1000);

$.ajaxSetup({
beforeSend: function(xhr, settings) {
beforeSend(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrfToken);
xhr.setRequestHeader('X-CSRFToken', csrfToken);
}
}
},
});

$.fn.datetimepicker.defaults.format = 'YYYY-MM-DD HH:mm:ssZ';
Expand Down
73 changes: 38 additions & 35 deletions airflow/www/static/js/connection_form.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
/* global $, document */
/**
* Created by janomar on 23/07/15.
*/

$(document).ready(function () {
var config = {
$(document).ready(() => {
const config = {
jdbc: {
hidden_fields: ['port', 'schema', 'extra'],
relabeling: {'host': 'Connection URL'},
relabeling: { host: 'Connection URL' },
},
google_cloud_platform: {
hidden_fields: ['host', 'schema', 'login', 'password', 'port', 'extra'],
Expand All @@ -33,27 +34,27 @@ $(document).ready(function () {
cloudant: {
hidden_fields: ['port', 'extra'],
relabeling: {
'host': 'Account',
'login': 'Username (or API Key)',
'schema': 'Database'
}
host: 'Account',
login: 'Username (or API Key)',
schema: 'Database',
},
},
docker: {
hidden_fields: ['port', 'schema'],
relabeling: {
'host': 'Registry URL',
'login': 'Username',
host: 'Registry URL',
login: 'Username',
},
},
qubole: {
hidden_fields: ['login', 'schema', 'port', 'extra'],
relabeling: {
'host': 'API Endpoint',
'password': 'Auth Token',
host: 'API Endpoint',
password: 'Auth Token',
},
placeholders: {
'host': 'https://<env>.qubole.com/api'
}
host: 'https://<env>.qubole.com/api',
},
},
kubernetes: {
hidden_fields: ['host', 'schema', 'login', 'password', 'port', 'extra'],
Expand All @@ -62,8 +63,8 @@ $(document).ready(function () {
ssh: {
hidden_fields: ['schema'],
relabeling: {
'login': 'Username',
}
login: 'Username',
},
},
yandexcloud: {
hidden_fields: ['host', 'schema', 'login', 'password', 'port', 'extra'],
Expand All @@ -76,36 +77,38 @@ $(document).ready(function () {
};

function connTypeChange(connectionType) {
$(".hide").removeClass("hide");
$.each($("[id^='extra__']"), function () {
$(this).parent().parent().addClass('hide')
$('.hide').removeClass('hide');
$.each($("[id^='extra__']"), () => {
$(this).parent().parent().addClass('hide');
});
$.each($(`[id^='extra__${connectionType}']`), () => {
$(this).parent().parent().removeClass('hide');
});
$.each($("[id^='extra__" + connectionType + "']"), function () {
$(this).parent().parent().removeClass('hide')
$('label[orig_text]').each(() => {
$(this).text($(this).attr('orig_text'));
});
$("label[orig_text]").each(function () {
$(this).text($(this).attr("orig_text"));
$('.form-control').each(() => {
$(this).attr('placeholder', '');
});
$(".form-control").each(function(){$(this).attr('placeholder', '')});

if (config[connectionType] != undefined) {
$.each(config[connectionType].hidden_fields, function (i, field) {
$("#" + field).parent().parent().addClass('hide')
if (config[connectionType] !== undefined) {
$.each(config[connectionType].hidden_fields, (i, field) => {
$(`#${field}`).parent().parent().addClass('hide');
});
$.each(config[connectionType].relabeling, function (k, v) {
lbl = $("label[for='" + k + "']");
lbl.attr("orig_text", lbl.text());
$("label[for='" + k + "']").text(v);
$.each(config[connectionType].relabeling, (k, v) => {
const lbl = $(`label[for='${k}']`);
lbl.attr('orig_text', lbl.text());
$(`label[for='${k}']`).text(v);
});
$.each(config[connectionType].placeholders, function(k, v){
$("#" + k).attr('placeholder', v);
$.each(config[connectionType].placeholders, (k, v) => {
$(`#${k}`).attr('placeholder', v);
});
}
}

var connectionType = $("#conn_type").val();
$("#conn_type").on('change', function (e) {
connectionType = $("#conn_type").val();
let connectionType = $('#conn_type').val();
$('#conn_type').on('change', () => {
connectionType = $('#conn_type').val();
connTypeChange(connectionType);
});
connTypeChange(connectionType);
Expand Down
19 changes: 10 additions & 9 deletions airflow/www/static/js/datetime-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ export const convertAndFormatUTC = (datetime, tz) => {
};

export const secondsToString = (seconds) => {
let numdays = Math.floor((seconds % 31536000) / 86400);
let numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
let numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
let numseconds = Math.floor((((seconds % 31536000) % 86400) % 3600) % 60);
return (numdays > 0 ? numdays + (numdays === 1 ? ' day ' : ' days ') : '') +
(numhours > 0 ? numhours + (numhours === 1 ? ' hour ' : ' hours ') : '') +
(numminutes > 0 ? numminutes + (numminutes === 1 ? ' minute ' : ' minutes ') : '') +
(numseconds > 0 ? numseconds + (numseconds === 1 ? ' second' : ' seconds') : '');
const numdays = Math.floor((seconds % 31536000) / 86400);
const numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
const numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
const numseconds = Math.floor((((seconds % 31536000) % 86400) % 3600) % 60);
return (numdays > 0 ? numdays + (numdays === 1 ? ' day ' : ' days ') : '')
+ (numhours > 0 ? numhours + (numhours === 1 ? ' hour ' : ' hours ') : '')
+ (numminutes > 0 ? numminutes + (numminutes === 1 ? ' minute ' : ' minutes ') : '')
+ (numseconds > 0 ? numseconds + (numseconds === 1 ? ' second' : ' seconds') : '');
};

export function updateAllDateTimes() {
Expand All @@ -86,7 +86,8 @@ export function updateAllDateTimes() {
// Since we have set the default timezone for moment, it will automatically
// convert it to the new target for us
$('.datetime input').each((_, el) => {
el.value = moment(el.value).format();
const $el = $(el);
$el.value = moment(el.value).format();
});
}

Expand Down
Loading