diff --git a/.github/workflows/semgrep.yml b/.github/workflows/linters.yml similarity index 68% rename from .github/workflows/semgrep.yml rename to .github/workflows/linters.yml index 325411cf5c..443ee45bf7 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/linters.yml @@ -1,15 +1,24 @@ -name: Semgrep +name: Linters on: pull_request: { } jobs: - semgrep: + + linters: name: Frappe Linter runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install and Run Pre-commit + uses: pre-commit/action@v2.0.3 + - name: Download Semgrep rules run: git clone --depth 1 https://github.com/frappe/semgrep-rules.git frappe-semgrep-rules diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..f3c3447cb3 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,23 @@ +exclude: 'node_modules|.git' +default_stages: [commit] +fail_fast: false + + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.1 + hooks: + - id: trailing-whitespace + files: "frappe.*" + exclude: ".*json$|.*txt$|.*csv|.*md|.*svg" + - id: check-yaml + - id: no-commit-to-branch + args: ['--branch', 'develop'] + - id: check-merge-conflict + - id: check-ast + + +ci: + autoupdate_schedule: weekly + skip: [] + submodules: false diff --git a/codecov.yml b/codecov.yml index bc59416d2f..1326403cfe 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,7 +3,6 @@ codecov: coverage: status: - patch: off project: default: false server: diff --git a/frappe/core/doctype/data_import/importer.py b/frappe/core/doctype/data_import/importer.py index f085709945..f89eb31cc8 100644 --- a/frappe/core/doctype/data_import/importer.py +++ b/frappe/core/doctype/data_import/importer.py @@ -166,7 +166,7 @@ class Importer: if not self.data_import.status == "Partial Success": self.data_import.db_set("status", "Partial Success") - + # commit after every successful import frappe.db.commit() diff --git a/frappe/core/doctype/report/test_report.py b/frappe/core/doctype/report/test_report.py index bf63afa5c5..4e044dd46d 100644 --- a/frappe/core/doctype/report/test_report.py +++ b/frappe/core/doctype/report/test_report.py @@ -314,19 +314,19 @@ result = [ { "parent_column": "Parent 1", "column_1": 200, - "column_2": 150.50 + "column_2": 150.50 }, { "parent_column": "Child 1", "column_1": 100, "column_2": 75.25, - "parent_value": "Parent 1" + "parent_value": "Parent 1" }, { "parent_column": "Child 2", "column_1": 100, "column_2": 75.25, - "parent_value": "Parent 1" + "parent_value": "Parent 1" } ] diff --git a/frappe/desk/doctype/dashboard_chart/dashboard_chart.js b/frappe/desk/doctype/dashboard_chart/dashboard_chart.js index e0d2cab8ef..0b93786e8e 100644 --- a/frappe/desk/doctype/dashboard_chart/dashboard_chart.js +++ b/frappe/desk/doctype/dashboard_chart/dashboard_chart.js @@ -495,7 +495,7 @@ frappe.ui.form.on('Dashboard Chart', { set_parent_document_type: async function(frm) { let document_type = frm.doc.document_type; - let doc_is_table = document_type && + let doc_is_table = document_type && (await frappe.db.get_value('DocType', document_type, 'istable')).message.istable; frm.set_df_property('parent_document_type', 'hidden', !doc_is_table); diff --git a/frappe/desk/doctype/form_tour/form_tour.js b/frappe/desk/doctype/form_tour/form_tour.js index d6390d7613..3f3fc0ff8a 100644 --- a/frappe/desk/doctype/form_tour/form_tour.js +++ b/frappe/desk/doctype/form_tour/form_tour.js @@ -16,7 +16,7 @@ frappe.ui.form.on('Form Tour', { frm.add_custom_button(__('Show Tour'), async () => { const issingle = await check_if_single(frm.doc.reference_doctype); let route_changed = null; - + if (issingle) { route_changed = frappe.set_route('Form', frm.doc.reference_doctype); } else if (frm.doc.first_document) { diff --git a/frappe/desk/doctype/todo/todo_calendar.js b/frappe/desk/doctype/todo/todo_calendar.js index 4545846cf9..8ba020fac1 100644 --- a/frappe/desk/doctype/todo/todo_calendar.js +++ b/frappe/desk/doctype/todo/todo_calendar.js @@ -24,7 +24,7 @@ frappe.views.calendar["ToDo"] = { "options": "reference_type", "label": __("Task") } - + ], get_events_method: "frappe.desk.calendar.get_events" }; diff --git a/frappe/desk/doctype/workspace/workspace.js b/frappe/desk/doctype/workspace/workspace.js index 5377470343..3f912127fc 100644 --- a/frappe/desk/doctype/workspace/workspace.js +++ b/frappe/desk/doctype/workspace/workspace.js @@ -9,7 +9,7 @@ frappe.ui.form.on('Workspace', { refresh: function(frm) { frm.enable_save(); - if (frm.doc.for_user || (frm.doc.public && !frm.has_perm('write') && + if (frm.doc.for_user || (frm.doc.public && !frm.has_perm('write') && !frappe.user.has_role('Workspace Manager'))) { frm.trigger('disable_form'); } diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index b40f517350..f0a3531ae4 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -176,9 +176,9 @@ def update_page(name, title, icon, parent, public): doc = frappe.get_doc("Workspace", name) - filters = { + filters = { 'parent_page': doc.title, - 'public': doc.public + 'public': doc.public } child_docs = frappe.get_list("Workspace", filters=filters) @@ -255,7 +255,7 @@ def delete_page(page): def sort_pages(sb_public_items, sb_private_items): if not loads(sb_public_items) and not loads(sb_private_items): return - + sb_public_items = loads(sb_public_items) sb_private_items = loads(sb_private_items) @@ -292,7 +292,7 @@ def last_sequence_id(doc): if not doc_exists: return 0 - return frappe.db.get_list('Workspace', + return frappe.db.get_list('Workspace', fields=['sequence_id'], filters={ 'public': doc.public, diff --git a/frappe/email/receive.py b/frappe/email/receive.py index b8156d5d9b..8aa32fc1a5 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -630,7 +630,7 @@ class InboundMail(Email): if self.reference_document(): data['reference_doctype'] = self.reference_document().doctype data['reference_name'] = self.reference_document().name - else: + else: if append_to and append_to != 'Communication': reference_doc = self._create_reference_document(append_to) if reference_doc: diff --git a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.js b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.js index 1343faecc4..6915c5c582 100644 --- a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.js +++ b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.js @@ -3,6 +3,6 @@ frappe.ui.form.on('Razorpay Settings', { refresh: function(frm) { - + } }); \ No newline at end of file diff --git a/frappe/patches/v12_0/set_correct_url_in_files.py b/frappe/patches/v12_0/set_correct_url_in_files.py index 4f820c1b24..4613f88694 100644 --- a/frappe/patches/v12_0/set_correct_url_in_files.py +++ b/frappe/patches/v12_0/set_correct_url_in_files.py @@ -15,7 +15,7 @@ def execute(): for file in files: file_path = file.file_url file_name = file_path.split('/')[-1] - + if not file_path.startswith(('/private/', '/files/')): continue diff --git a/frappe/public/js/frappe/form/controls/date.js b/frappe/public/js/frappe/form/controls/date.js index 48f4f3b5ee..0f80371706 100644 --- a/frappe/public/js/frappe/form/controls/date.js +++ b/frappe/public/js/frappe/form/controls/date.js @@ -160,7 +160,7 @@ frappe.ui.form.ControlDate = class ControlDate extends frappe.ui.form.ControlDat get_df_options() { let df_options = this.df.options; if (!df_options) return {}; - + let options = {}; if (typeof df_options === 'string') { try { diff --git a/frappe/public/js/frappe/form/controls/table.js b/frappe/public/js/frappe/form/controls/table.js index d8fb4bb0e9..5b7cf9421e 100644 --- a/frappe/public/js/frappe/form/controls/table.js +++ b/frappe/public/js/frappe/form/controls/table.js @@ -92,7 +92,7 @@ frappe.ui.form.ControlTable = class ControlTable extends frappe.ui.form.Control if (frappe.model.no_value_type.includes(field.fieldtype)) { return false; } - + const is_field_matching = () => { return ( field.fieldname.toLowerCase() === field_name || diff --git a/frappe/public/js/frappe/form/grid_pagination.js b/frappe/public/js/frappe/form/grid_pagination.js index 76a5f7b50b..2be708a87b 100644 --- a/frappe/public/js/frappe/form/grid_pagination.js +++ b/frappe/public/js/frappe/form/grid_pagination.js @@ -66,7 +66,7 @@ export default class GridPagination { } // only allow numbers from 0-9 and up, down, left, right arrow keys - if (charCode > 31 && (charCode < 48 || charCode > 57) && + if (charCode > 31 && (charCode < 48 || charCode > 57) && ![37, 38, 39, 40].includes(charCode)) { return false; } diff --git a/frappe/public/js/frappe/list/list_view_select.js b/frappe/public/js/frappe/list/list_view_select.js index c89815d200..54e88ea05b 100644 --- a/frappe/public/js/frappe/list/list_view_select.js +++ b/frappe/public/js/frappe/list/list_view_select.js @@ -150,7 +150,7 @@ frappe.views.ListViewSelect = class ListViewSelect { const views_wrapper = this.sidebar.sidebar.find(".views-section"); views_wrapper.find(".sidebar-label").html(`${__(view)}`); const $dropdown = views_wrapper.find(".views-dropdown"); - + let placeholder = `${__("Select {0}", [__(view)])}`; let html = ``; diff --git a/frappe/public/js/frappe/ui/filters/field_select.js b/frappe/public/js/frappe/ui/filters/field_select.js index 0bdb9085f0..8f6d3ab89d 100644 --- a/frappe/public/js/frappe/ui/filters/field_select.js +++ b/frappe/public/js/frappe/ui/filters/field_select.js @@ -112,9 +112,9 @@ frappe.ui.FieldSelect = class FieldSelect { // main table var main_table_fields = std_filters.concat(frappe.meta.docfield_list[me.doctype]); $.each(frappe.utils.sort(main_table_fields, "label", "string"), function(i, df) { - let doctype = frappe.get_meta(me.doctype).istable && me.parent_doctype ? + let doctype = frappe.get_meta(me.doctype).istable && me.parent_doctype ? me.parent_doctype : me.doctype; - + // show fields where user has read access and if report hide flag is not set if (frappe.perm.has_perm(doctype, df.permlevel, "read")) me.add_field_option(df); @@ -132,9 +132,9 @@ frappe.ui.FieldSelect = class FieldSelect { } $.each(frappe.utils.sort(child_table_fields, "label", "string"), function(i, df) { - let doctype = frappe.get_meta(me.doctype).istable && me.parent_doctype ? + let doctype = frappe.get_meta(me.doctype).istable && me.parent_doctype ? me.parent_doctype : me.doctype; - + // show fields where user has read access and if report hide flag is not set if (frappe.perm.has_perm(doctype, df.permlevel, "read")) me.add_field_option(df); diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js index dc75239ed5..ff55f5578f 100644 --- a/frappe/public/js/frappe/utils/utils.js +++ b/frappe/public/js/frappe/utils/utils.js @@ -244,7 +244,7 @@ Object.assign(frappe.utils, { }; return String(txt).replace( - /[&<>"'`=/]/g, + /[&<>"'`=/]/g, char => escape_html_mapping[char] || char ); }, @@ -262,7 +262,7 @@ Object.assign(frappe.utils, { }; return String(txt).replace( - /&|<|>|"|'|/|`|=/g, + /&|<|>|"|'|/|`|=/g, char => unescape_html_mapping[char] || char ); }, @@ -1435,7 +1435,7 @@ Object.assign(frappe.utils, { // for link titles frappe._link_titles = {}; } - + frappe._link_titles[doctype + "::" + name] = value; }, diff --git a/frappe/public/js/frappe/views/reports/print_tree.html b/frappe/public/js/frappe/views/reports/print_tree.html index 9300c8df64..817c0c1e9f 100644 --- a/frappe/public/js/frappe/views/reports/print_tree.html +++ b/frappe/public/js/frappe/views/reports/print_tree.html @@ -10,14 +10,14 @@ - +