From 65f2586bbedd1e1748fc20b4eabf6400177a18fe Mon Sep 17 00:00:00 2001 From: David Sevilla Martin Date: Thu, 28 Nov 2019 14:40:44 -0500 Subject: [PATCH] Allow for job events, fix conf events command, improve url parser, show full commit message if just 1 commit Fixes #43, fixes #29, refs #52 --- LICENSE.md | 2 +- lib/Discord/Commands/Conf.js | 33 ++++++++++++++++++--------------- lib/Gitlab/EventHandler.js | 6 ++++-- lib/Gitlab/Events/Unknown.js | 2 +- lib/Gitlab/Events/push.js | 20 +++++++++++++------- lib/Gitlab/parser.js | 32 +++++++++++++++----------------- lib/Util/filter.js | 4 ++-- lib/Web.js | 7 ++++--- package-lock.json | 5 +++++ package.json | 1 + 10 files changed, 64 insertions(+), 48 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index c1213b5..848bfbe 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Yappy Discord Bots +Copyright (c) 2019 David Sevilla Martin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/Discord/Commands/Conf.js b/lib/Discord/Commands/Conf.js index eb82e70..56ecb75 100644 --- a/lib/Discord/Commands/Conf.js +++ b/lib/Discord/Commands/Conf.js @@ -221,7 +221,7 @@ class ConfCommand extends Command { if (action === Actions.INVALID) { if (!a) { - const events = conf.disabledEvents || []; + const events = conf.get('eventsList'); const embed = new this.embed().setColor('#84F139').setTitle(`#${msg.channel.name}'s disabled events`); if (!events || !events.length) embed.setDescription('No disabled events found.'); @@ -232,7 +232,7 @@ class ConfCommand extends Command { } else if (a.toLowerCase() === 'list') { const embed = new this.embed().setTitle('List of available events'); - EventHandler.eventsList.forEach((evt, name) => embed.addField('\u200B', `\`${name.replace('-', '/')}\``, true)); + EventHandler.eventsList.forEach((evt, name) => name !== 'Unknown' && embed.addField('\u200B', `\`${name.replace('-', '/')}\``, true)); return msg.channel.send({ embed }); } else { @@ -244,25 +244,28 @@ class ConfCommand extends Command { } } - let events = conf.disabledEvents; + let events = conf.get('eventsList'); if (action === Actions.DISABLE && !events.includes(key)) events.push(key); else if (action === Actions.ENABLE) events = events.filter(e => e !== key); - return conf.set('disabledEvents', events).then(() => { - const embed = new this.embed() - .setColor('#84F139') - .setTitle(`Successfully updated #${msg.channel.name}'s disabled events`) - .setDescription([ - `${action === Actions.ENABLE ? 'Enabled' : 'Disabled'} \`${key}\`.`, - '', - events.length ? 'Disabled events:\n' : 'No events are disabled.', - ]); + return conf + .set('eventsList', events) + .save() + .then(() => { + const embed = new this.embed() + .setColor('#84F139') + .setTitle(`Successfully updated #${msg.channel.name}'s disabled events`) + .setDescription([ + `${action === Actions.ENABLE ? 'Enabled' : 'Disabled'} \`${key}\`.`, + '', + events.length ? 'Disabled events:\n' : 'No events are disabled.', + ]); - events.forEach(e => embed.addField(e, '\u200B', true)); + events.forEach(e => embed.addField(e, '\u200B', true)); - return msg.channel.send({ embed }); - }); + return msg.channel.send({ embed }); + }); } format(val, isBoolean) { diff --git a/lib/Gitlab/EventHandler.js b/lib/Gitlab/EventHandler.js index 2a48a22..e0af810 100644 --- a/lib/Gitlab/EventHandler.js +++ b/lib/Gitlab/EventHandler.js @@ -1,7 +1,9 @@ -const bot = require('../Discord/index.js'); +const get = require('lodash/get'); const fs = require('fs'); const path = require('path'); +const bot = require('../Discord'); const Log = require('../Util/Log'); +const parser = require('../Gitlab/parser'); class Events { constructor() { @@ -81,7 +83,7 @@ class Events { icon_url: avatar && avatar.startsWith('/') ? `https://gitlab.com${avatar}` : avatar, }; embed.footer = { - text: data.project.path_with_namespace, + text: get(data, 'project.path_with_namespace') || parser.getRepo(get(data, 'repository.url')), }; embed.url = embed.url || (data.object_attributes && data.object_attributes.url) || (data.project && data.project.web_url); embed.timestamp = new Date(); diff --git a/lib/Gitlab/Events/Unknown.js b/lib/Gitlab/Events/Unknown.js index 1955424..8a7343b 100644 --- a/lib/Gitlab/Events/Unknown.js +++ b/lib/Gitlab/Events/Unknown.js @@ -11,7 +11,7 @@ class Unkown extends EventResponse { return { color: 'danger', title: `Repository sent unknown event: \`${eventName}${action}\``, - description: `This most likely means the developers have not gotten to styling this event.\nYou may want to disable this event if you don't want it with \`GL! conf events disable ${eventName}${action}\``, + description: `This most likely means the developers have not gotten to styling this event.\nYou may want to disable this event if you don't want it with \`GL! conf filter events disable ${eventName}${action}\``, }; } text(data, eventName, actionName) { diff --git a/lib/Gitlab/Events/push.js b/lib/Gitlab/Events/push.js index 31f90f7..27074ac 100644 --- a/lib/Gitlab/Events/push.js +++ b/lib/Gitlab/Events/push.js @@ -18,10 +18,11 @@ class Push extends EventResponse { const commitCount = commits.length; let pretext = commits .map(commit => { - let commitMessage = commit.message.split('\n')[0].replace(UrlRegEx, RemoveUrlEmbedding); - let author = commit.author.name || data.user_username || data.user_name; - let sha = commit.id.slice(0, 7); - return `[\`${sha}\`](${commit.url}) ${commitMessage} [${author}]`; + const message = (commitCount === 1 ? commit.message : commit.message.split('\n')[0]).replace(UrlRegEx, RemoveUrlEmbedding); + const author = commit.author.name || data.user_username || data.user_name; + const sha = commit.id.slice(0, 7); + + return `[\`${sha}\`](${commit.url}) ${message} [${author}]`; }) .slice(0, 5); const description = pretext.join('\n'); @@ -40,16 +41,21 @@ class Push extends EventResponse { const branch = GetBranchName(data.ref); const commits = data.commits || []; const commitCount = commits.length; + if (!commitCount) return ''; - let msg = `⚡ **${actor}** pushed ${commitCount} ${commitCount !== 1 ? 'commits' : 'commit'} to \`${branch}\``; + let commitArr = commits .map(commit => { let commitMessage = commit.message.replace(/\n/g, '\n ').replace(UrlRegEx, RemoveUrlEmbedding); return ` \`${commit.id.slice(0, 7)}\` ${commitMessage} [${commit.author.name || actor}]`; }) .slice(0, 5); - msg += `\n${commitArr.join('\n')}`; - msg += `\n<${data.project.web_url}/compare/${data.before.slice(0, 7)}...${data.after.slice(0, 7)}>`; + + return [ + `⚡ **${actor}** pushed ${commitCount} ${commitCount !== 1 ? 'commits' : 'commit'} to \`${branch}\``, + ...commitArr, + `${data.project.web_url}/compare/${data.before.slice(0, 7)}...${data.after.slice(0, 7)}`, + ].join('\n'); return msg; } diff --git a/lib/Gitlab/parser.js b/lib/Gitlab/parser.js index 5e8996d..35b04ef 100644 --- a/lib/Gitlab/parser.js +++ b/lib/Gitlab/parser.js @@ -1,3 +1,5 @@ +const parseUrl = require('parse-github-url'); + const urlRegex = /^(https?:\/\/|git@)?([\da-z\.-]+\.[a-z\.]{2,7})\/?/; // eslint-disable-line no-useless-escape const getUrl = str => urlRegex.exec(str); @@ -21,21 +23,17 @@ const regex = /^([^\/\s]+)\/?((?:\/?(?:\S+))*)\/([^\/]+?)(?:\.git)?$/; // eslint module.exports = str => { if (!str || typeof str !== 'string' || !str.length) return {}; - const url = getUrl(str); - const domain = url && url[2]; - const parsed = regex.exec(str.replace(urlRegex, '')); - - const repo = parsed && `${parsed[1]}/${parsed[2] && `${parsed[2]}/`}${parsed[3]}`; - - return parsed - ? { - repo, - host: domain, - isGitlab: !domain || domain === 'gitlab.com', - repository: repo, - owner: parsed[1], - group: parsed[2], - name: parsed[3], - } - : {}; + const parsed = parseUrl(str); + + if (parsed.host === 'github.com') parsed.host = 'gitlab.com'; + + parsed.isGitlab = parsed.host === 'gitlab.com'; + + return parsed; }; + +module.exports.getRepo = str => { + const out = module.exports(str); + + return out && out.repo; +}; \ No newline at end of file diff --git a/lib/Util/filter.js b/lib/Util/filter.js index 21651b4..f865807 100644 --- a/lib/Util/filter.js +++ b/lib/Util/filter.js @@ -1,6 +1,6 @@ const isFound = (data, item) => data.includes(item) || data.includes(item.split('/')[0]); module.exports = { - whitelist: (data = []) => item => isFound(data, item), - blacklist: (data = []) => item => !isFound(data, item), + whitelist: (data = []) => item => (item ? isFound(data, item) : true), + blacklist: (data = []) => item => (item ? !isFound(data, item) : true), }; diff --git a/lib/Web.js b/lib/Web.js index 924ea51..0b030dd 100644 --- a/lib/Web.js +++ b/lib/Web.js @@ -7,6 +7,7 @@ const addons = require('yappybots-addons'); const GetBranchName = require('./Util').GetBranchName; const filter = require('./Util/filter'); +const parser = require('./Gitlab/parser'); const Channel = require('./Models/Channel'); const ChannelRepo = require('./Models/ChannelRepo'); @@ -61,9 +62,9 @@ app.post('/', async (req, res) => { .toLowerCase(); const data = req.body; - if (!event || !data || !data.project) return res.status(403).send('Invalid data. Plz use Gitlab webhooks.'); + if (!event || !data || (!data.project && !data.repository)) return res.status(403).send('Invalid data. Plz use Gitlab webhooks.'); - const repo = get(data, 'project.path_with_namespace'); + const repo = get(data, 'project.path_with_namespace') || parser.getRepo(get(data, 'repository.url')); const channels = (repo && (await Channel.findByRepo(repo))) || []; const action = get(data, 'object_attributes.action'); @@ -71,7 +72,7 @@ app.post('/', async (req, res) => { Log.verbose(`GitLab | ${repo} - ${eventName}${actionText} (${channels.length} channels)`); - res.send(`${data.project.path_with_namespace} : Received ${eventName}${actionText}, emitting to ${channels.length} channels...`); + res.send(`${repo} : Received ${eventName}${actionText}, emitting to ${channels.length} channels...`); const eventResponse = GitlabEventHandler.use(data, event); diff --git a/package-lock.json b/package-lock.json index b59ea05..dce6c96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4239,6 +4239,11 @@ "path-root": "^0.1.1" } }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==" + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", diff --git a/package.json b/package.json index 6624866..cb84452 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "mongoose": "^5.7.12", "node-fetch": "^2.6.0", "p-queue": "^6.2.1", + "parse-github-url": "^1.0.2", "pretty-error": "^2.1.1", "punycode": "^2.1.1", "snekfetch": "^4.0.4",