diff --git a/lib/workers/package-file/dep-type.js b/lib/workers/package-file/dep-type.js
index 45d22cea6ec2dc1a7872b578b5066edff9c4cec3..555e79fb038936cbfefe5f996f5e0f006cb93a6a 100644
--- a/lib/workers/package-file/dep-type.js
+++ b/lib/workers/package-file/dep-type.js
@@ -57,62 +57,83 @@ function getDepConfig(depTypeConfig, dep) {
       `Checking against ${depConfig.packageRules.length} packageRules`
     );
     depConfig.packageRules.forEach(packageRule => {
-      const {
+      let {
         depTypeList,
-        excludePackageNames,
-        excludePackagePatterns,
         packageNames,
         packagePatterns,
+        excludePackageNames,
+        excludePackagePatterns,
         matchCurrentVersion,
       } = packageRule;
-      let applyRule;
+      // Setting empty arrays simplifies our logic later
+      depTypeList = depTypeList || [];
+      packageNames = packageNames || [];
+      packagePatterns = packagePatterns || [];
+      excludePackageNames = excludePackageNames || [];
+      excludePackagePatterns = excludePackagePatterns || [];
+      matchCurrentVersion = matchCurrentVersion || null;
+      let positiveMatch = false;
+      let negativeMatch = false;
+      // Massage a positive patterns patch if an exclude one is present
       if (
-        (excludePackageNames || excludePackagePatterns) &&
-        !(packageNames || packagePatterns)
+        (excludePackageNames.length || excludePackagePatterns.length) &&
+        !(packageNames.length || packagePatterns.length)
       ) {
-        logger.debug(
-          { packageRule, dependency },
-          'packageRule is missing packageNames and packagePatterns so will match anything'
-        );
-        applyRule = true;
-      } else if (packageNames && packageNames.includes(dependency)) {
-        logger.debug({ dependency, packageNames }, 'Matched packageNames');
-        applyRule = true;
-      } else if (packagePatterns) {
-        logger.trace({ dependency }, 'Checking against packagePatterns');
-        for (const packagePattern of packagePatterns) {
-          const packageRegex = new RegExp(
-            packagePattern === '^*$' || packagePattern === '*'
-              ? '.*'
-              : packagePattern
-          );
-          logger.trace(
-            { dependency, packagePattern },
-            'Checking against packagePattern'
-          );
-          if (dependency.match(packageRegex)) {
-            logger.trace(`${dependency} matches against ${packageRegex}`);
-            applyRule = true;
+        packagePatterns = ['.*'];
+      }
+      if (depTypeList.length) {
+        const isMatch = depTypeList.includes(dep.depType);
+        positiveMatch = positiveMatch || isMatch;
+        negativeMatch = negativeMatch || !isMatch;
+      }
+      if (packageNames.length || packagePatterns.length) {
+        let isMatch = packageNames.includes(dep.depName);
+        // name match is "or" so we check patterns if we didn't match names
+        if (!isMatch) {
+          for (const packagePattern of packagePatterns) {
+            const packageRegex = new RegExp(
+              packagePattern === '^*$' || packagePattern === '*'
+                ? '.*'
+                : packagePattern
+            );
+            if (dependency.match(packageRegex)) {
+              logger.trace(`${dependency} matches against ${packageRegex}`);
+              isMatch = true;
+            }
           }
         }
+        positiveMatch = positiveMatch || isMatch;
+        negativeMatch = negativeMatch || !isMatch;
       }
-      if (excludePackageNames && excludePackageNames.includes(dependency)) {
-        applyRule = false;
-      } else if (excludePackagePatterns) {
-        for (const packagePattern of excludePackagePatterns) {
-          const packageRegex = new RegExp(packagePattern);
+      if (excludePackageNames.length) {
+        const isMatch = excludePackageNames.includes(dep.depName);
+        negativeMatch = negativeMatch || isMatch;
+        positiveMatch = positiveMatch || !isMatch;
+      }
+      if (excludePackagePatterns.length) {
+        let isMatch = false;
+        for (const pattern of excludePackagePatterns) {
+          const packageRegex = new RegExp(
+            pattern === '^*$' || pattern === '*' ? '.*' : pattern
+          );
           if (dependency.match(packageRegex)) {
-            applyRule = false;
+            logger.trace(`${dependency} matches against ${packageRegex}`);
+            isMatch = true;
           }
         }
+        negativeMatch = negativeMatch || isMatch;
+        positiveMatch = positiveMatch || !isMatch;
       }
-      if (applyRule !== false && matchCurrentVersion) {
-        applyRule = intersectsSemver(dep.currentVersion, matchCurrentVersion);
-      }
-      if (applyRule !== false && depTypeList && depTypeList.length) {
-        applyRule = depTypeList.includes(dep.depType);
+      if (matchCurrentVersion) {
+        const isMatch = intersectsSemver(
+          dep.currentVersion,
+          matchCurrentVersion
+        );
+        positiveMatch = positiveMatch || isMatch;
+        negativeMatch = negativeMatch || !isMatch;
       }
-      if (applyRule) {
+      // This rule is considered matched if there was at least one positive match and no negative matches
+      if (positiveMatch && !negativeMatch) {
         // Package rule config overrides any existing config
         depConfig = configParser.mergeChildConfig(depConfig, packageRule);
         delete depConfig.packageNames;