From 7a8ce44eea5a7582cb516ccb73df9d2c38a4727d Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 08:49:58 -0600
Subject: [PATCH 01/28] Adding test cases and logic
---
.automation/test/README.md | 7 +
.../ansible/ghe-initialize/defaults/main.yml | 182 ++++
.../files/ghe-initial-config.json | 11 +
.../ghe-initialize/files/ghe-license.ghl | 873 ++++++++++++++++++
.../ansible/ghe-initialize/handlers/main.yml | 14 +
.../tasks/collectd-settings.yml | 90 ++
.../tasks/ghe-api-config-apply.yml | 68 ++
.../ghe-initialize/tasks/ghe-config-apply.yml | 32 +
.../tasks/ghe-initial-configuration.yml | 87 ++
.../tasks/ghe-ldap-configuration.yml | 31 +
.../ansible/ghe-initialize/tasks/main.yml | 67 ++
.../ghe-initialize/tasks/splunk-settings.yml | 67 ++
.../templates/collectd-settings.json.j2 | 10 +
.../templates/forwarding.conf.j2 | 9 +
.../templates/ghe-config-apply.sh | 211 +++++
.../templates/ldap-settings.json.j2 | 35 +
.../ghe-initialize/templates/settings.json.j2 | 112 +++
.../templates/splunk-settings.json.j2 | 9 +
.automation/test/ansible/github-playbook.yml | 42 +
.../coffeescript/coffeescript_bad_1.coffee | 82 ++
.../coffeescript/coffeescript_good_1.coffee | 84 ++
.../test/docker/docker_bad_1.DOCKERFILE | 14 +
.../test/docker/docker_good_1.DOCKERFILE | 13 +
.../test/javascript/javascript_bad_1.js | 220 +++++
.../test/javascript/javascript_good_1.js | 215 +++++
.automation/test/json/json_bad_1.json | 10 +
.automation/test/json/json_good_1.json | 10 +
.automation/test/markdown/markdown_bad_1.md | 20 +
.automation/test/markdown/markdown_good_1.md | 20 +
.automation/test/perl/perl_bad_1.pl | 39 +
.automation/test/perl/perl_good_1.pl | 38 +
.automation/test/python/python_bad_1.py | 178 ++++
.automation/test/python/python_good_1.py | 181 ++++
.automation/test/ruby/ruby_bad_1.rb | 28 +
.automation/test/ruby/ruby_good_1.rb | 23 +
.automation/test/shell/shell_bad_1.sh | 17 +
.automation/test/shell/shell_good_1.sh | 17 +
.automation/test/xml/xml_bad_1.xml | 6 +
.automation/test/xml/xml_good_1.xml | 6 +
.automation/test/yml/yml_bad_1.yml | 17 +
.automation/test/yml/yml_good_1.yml | 19 +
lib/linter.sh | 10 +-
42 files changed, 3221 insertions(+), 3 deletions(-)
create mode 100644 .automation/test/README.md
create mode 100644 .automation/test/ansible/ghe-initialize/defaults/main.yml
create mode 100644 .automation/test/ansible/ghe-initialize/files/ghe-initial-config.json
create mode 100644 .automation/test/ansible/ghe-initialize/files/ghe-license.ghl
create mode 100644 .automation/test/ansible/ghe-initialize/handlers/main.yml
create mode 100644 .automation/test/ansible/ghe-initialize/tasks/collectd-settings.yml
create mode 100644 .automation/test/ansible/ghe-initialize/tasks/ghe-api-config-apply.yml
create mode 100644 .automation/test/ansible/ghe-initialize/tasks/ghe-config-apply.yml
create mode 100644 .automation/test/ansible/ghe-initialize/tasks/ghe-initial-configuration.yml
create mode 100644 .automation/test/ansible/ghe-initialize/tasks/ghe-ldap-configuration.yml
create mode 100644 .automation/test/ansible/ghe-initialize/tasks/main.yml
create mode 100644 .automation/test/ansible/ghe-initialize/tasks/splunk-settings.yml
create mode 100644 .automation/test/ansible/ghe-initialize/templates/collectd-settings.json.j2
create mode 100644 .automation/test/ansible/ghe-initialize/templates/forwarding.conf.j2
create mode 100644 .automation/test/ansible/ghe-initialize/templates/ghe-config-apply.sh
create mode 100644 .automation/test/ansible/ghe-initialize/templates/ldap-settings.json.j2
create mode 100644 .automation/test/ansible/ghe-initialize/templates/settings.json.j2
create mode 100644 .automation/test/ansible/ghe-initialize/templates/splunk-settings.json.j2
create mode 100644 .automation/test/ansible/github-playbook.yml
create mode 100644 .automation/test/coffeescript/coffeescript_bad_1.coffee
create mode 100644 .automation/test/coffeescript/coffeescript_good_1.coffee
create mode 100644 .automation/test/docker/docker_bad_1.DOCKERFILE
create mode 100644 .automation/test/docker/docker_good_1.DOCKERFILE
create mode 100644 .automation/test/javascript/javascript_bad_1.js
create mode 100644 .automation/test/javascript/javascript_good_1.js
create mode 100644 .automation/test/json/json_bad_1.json
create mode 100644 .automation/test/json/json_good_1.json
create mode 100644 .automation/test/markdown/markdown_bad_1.md
create mode 100644 .automation/test/markdown/markdown_good_1.md
create mode 100644 .automation/test/perl/perl_bad_1.pl
create mode 100644 .automation/test/perl/perl_good_1.pl
create mode 100644 .automation/test/python/python_bad_1.py
create mode 100644 .automation/test/python/python_good_1.py
create mode 100644 .automation/test/ruby/ruby_bad_1.rb
create mode 100644 .automation/test/ruby/ruby_good_1.rb
create mode 100644 .automation/test/shell/shell_bad_1.sh
create mode 100644 .automation/test/shell/shell_good_1.sh
create mode 100644 .automation/test/xml/xml_bad_1.xml
create mode 100644 .automation/test/xml/xml_good_1.xml
create mode 100644 .automation/test/yml/yml_bad_1.yml
create mode 100644 .automation/test/yml/yml_good_1.yml
diff --git a/.automation/test/README.md b/.automation/test/README.md
new file mode 100644
index 00000000..3b56fe42
--- /dev/null
+++ b/.automation/test/README.md
@@ -0,0 +1,7 @@
+# Test Cases
+This folder holds `template test cases` that are used to validate the sanity of the **Super-Linter**.
+The format:
+- Folder(s) containing test cases for each language supported
+ - Passing test case(s) per language denoted in naming scheme
+ - Failing test case(s) per language denoted in naming scheme
+- Script to run test cases and validate the sanity of **Super-Linter**
diff --git a/.automation/test/ansible/ghe-initialize/defaults/main.yml b/.automation/test/ansible/ghe-initialize/defaults/main.yml
new file mode 100644
index 00000000..6e8741f0
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/defaults/main.yml
@@ -0,0 +1,182 @@
+---
+##########################################
+##########################################
+## Standard Variables for GHE Configure ##
+##########################################
+##########################################
+## These variables will be the defaults. If you want to override them,
+## then change them in 'vars/main.yml' instead of here
+github_admin_password: U53r1234
+github_initial_user_password: U53r1234
+github_host: github.service
+github_admin_port: 8443
+
+#####################
+# Default Rate Vars #
+#####################
+api_rate_limiting_enabled: "true"
+api_rate_limiting_unauthenticated_rate_limit: "60"
+api_rate_limiting_default_rate_limit: "5000"
+api_rate_limiting_search_unauthenticated_rate_limit: "10"
+api_rate_limiting_search_default_rate_limit: "30"
+api_rate_limiting_lfs_unauthenticated_rate_limit: "100"
+api_rate_limiting_lfs_default_rate_limit: "3000"
+api_rate_limiting_graphql_unauthenticated_rate_limit: "0"
+api_rate_limiting_graphql_default_rate_limit: "5000"
+
+######################
+# Default Abuse Vars #
+######################
+abuse_rate_limiting_enabled: "true"
+abuse_rate_limiting_requests_per_minute: "900"
+abuse_rate_limiting_cpu_millis_per_minute: "90000"
+abuse_rate_limiting_search_cpu_millis_per_minute: "7500"
+
+####################
+# Default Cas Vars #
+####################
+cas_url: "null"
+
+#########################
+# Default Collectd Vars #
+#########################
+collectd_enabled: "true"
+collectd_server: "metrics.service"
+collectd_port: "25826"
+collectd_encryption: "null"
+collectd_username: "null"
+collectd_password: "null"
+
+#####################
+# Default Core Vars #
+#####################
+core_private_mode: "true"
+core_public_pages: "false"
+core_subdomain_isolation: "false"
+core_signup_enabled: "false"
+core_github_hostname: "null"
+core_http_proxy: "null"
+core_http_noproxy: "null"
+core_builtin_auth_fallback: "false"
+core_expire_sessions: "false"
+core_package_version: "null"
+
+#######################
+# Default Github Vars #
+#######################
+github_ssl_enabled: "true"
+github_ssl_tls_mode: "tlsv12"
+github_ssl_cert: "null"
+github_ssl_key: "null"
+
+#########################
+# Default Governor Vars #
+#########################
+governor_quotas_enabled: "false"
+governor_limit_user: "null"
+governor_limit_network: "null"
+
+#####################
+# Default LDAP Vars #
+#####################
+ldap_host: "null"
+ldap_port: "389"
+ldap_method: "None"
+ldap_base_dn: "dc=demo,dc=github,dc=local"
+ldap_bind_dn: "cn=admin,dc=demo,dc=github,dc=local"
+ldap_password: "U53r1234"
+ldap_user_groups: "null"
+ldap_admin_group: "Autobots"
+ldap_user_sync_emails: "true"
+ldap_user_sync_keys: "false"
+ldap_user_sync_gpg_keys: "false"
+ldap_user_sync_interval: "1"
+ldap_team_sync_interval: "1"
+ldap_sync_enabled: "true"
+ldap_profile_uid: "uid"
+ldap_profile_name: "displayName"
+ldap_profile_mail: "mail"
+ldap_profile_key: "null"
+ldap_profile_gpg_key: "null"
+
+#############################
+# Default Loadbalancer Vars #
+#############################
+loadbalancer_http_forward: "false"
+loadbalancer_proxy_protocol: "false"
+
+########################
+# Default Mapping Vars #
+########################
+mapping_enabled: "false"
+mapping_tileserver: "null"
+mapping_basemap: "null"
+mapping_token: "null"
+
+####################
+# Default NTP Vars #
+####################
+ntp_primary_server: "0.ubuntu.pool.ntp.org"
+ntp_secondary_server: "1.ubuntu.pool.ntp.org"
+
+##########################
+# Default GHE Pages Vars #
+##########################
+pages_enabled: "true"
+
+#####################
+# Default SAML Vars #
+#####################
+saml_sso_url: "null"
+saml_certificate: "null"
+saml_certificate_path: "/data/user/common/idp.crt"
+saml_issuer: "null"
+saml_name_id_format: "persistent"
+saml_idp_initiated_sso: "false"
+saml_disable_admin_demote: "false"
+saml_signature_method: "rsa-sha256"
+saml_digest_method: "sha256"
+saml_username_attribute: "null"
+saml_full_name_attribute: "full_name"
+saml_emails_attribute: "emails"
+saml_ssh_keys_attribute: "public_keys"
+saml_gpg_keys_attribute: "gpg_keys"
+
+#####################
+# Default SMTP Vars #
+#####################
+smtp_enabled: "false"
+smtp_address: "null"
+smtp_authentication: "null"
+smtp_port: "0"
+smtp_domain: "null"
+smtp_username: "null"
+smtp_user_name: "null"
+smtp_password: "null"
+smtp_support_address: it.broke@github.com
+smtp_support_address_type: email
+smtp_noreply_address: "noreply@test.github.local"
+smtp_discard_to_noreply_address: "false"
+
+#####################
+# Default SNMP Vars #
+#####################
+snmp_enabled: "true"
+snmp_version: "2"
+snmp_community: "public"
+snmp_users: "null"
+
+#######################
+# Default Syslog Vars #
+#######################
+syslog_enabled: "false"
+syslog_server: "null"
+syslog_protocol_name: "udp"
+syslog_tls_enabled: "false"
+syslog_cert: "null"
+
+#######################
+# Default Splunk Vars #
+#######################
+splunk_host: splunk.service
+splunk_port: 9997
diff --git a/.automation/test/ansible/ghe-initialize/files/ghe-initial-config.json b/.automation/test/ansible/ghe-initialize/files/ghe-initial-config.json
new file mode 100644
index 00000000..f47772cd
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/files/ghe-initial-config.json
@@ -0,0 +1,11 @@
+{
+ "private_mode": false,
+ "signup_enabled": true,
+ "github_hostname": "github-test.local",
+ "github_ssl": {
+ "enabled": false,
+ "cert": null,
+ "key": null
+ },
+ "auth_mode": "default"
+}
diff --git a/.automation/test/ansible/ghe-initialize/files/ghe-license.ghl b/.automation/test/ansible/ghe-initialize/files/ghe-license.ghl
new file mode 100644
index 00000000..777c809b
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/files/ghe-license.ghl
@@ -0,0 +1,873 @@
+$ANSIBLE_VAULT;1.1;AES256
+61383339303139386235623338336365616565666363313538613164656664333962656164336231
+3032323336636539373430383035623736623930613232330a326364356264386533643031383038
+38636131363364653962346261383335326561366136373663333532313831323764646261353131
+6534663063346261660a343163306561633862333635666632373234366464663265316334323261
+61636536666335333931343236393562653261353664383130336564626561313932303564336434
+34366261313637653136373261313337626365366339383330303866646263626435373336666564
+35613763643334643362316235613130366664306336323939343331313733626135346266613233
+33653536616164623939323161313337666132336233373561616636636364653734303430303033
+32336466353332393664353536376363643965613665356633366165316138623437373262666365
+63383731316665623362383831393663343736653465363839613437363765393137393635653232
+33633132663837383138333330303130383232316566633363653138623364363664313535646132
+32323039353361306361626634613332336637313066353330396465356232346136373138346235
+32666532356433666430616230613464613332656661356435313430613731333962613464666365
+30376138333337613538366366616264326236303932623336313033363061643037346338633731
+63663134316238316330353865613938623936386563383532303137323864353061386164333430
+30346532383539373031616162643233646331623535333863363931663131393865303566336633
+35353439353239623830323936373363646639656532623136346335636362373937616165343331
+36613038653666376336663832626333643339373933326563366135366134326563336233303261
+35313263363065386562333662313032613632323235333632313332303563643336303762303363
+64303765356436386465316665633832356264393033633862353065666130643731323739353133
+37336633653535313639326438376462366232663531636561663136653366363865346131623039
+34646234323736303233656537653132666636373264333662373635626434666530316339303363
+63323163333339323062613763626337643835303665646536666261616435663761383461623731
+65323865316261323732316164326438646635643634656636386563383732363335343762313834
+66343934393063343730613734316166343966366362666236663362663731396531643366363531
+37386363613266353537313366323863366163383233343961323037636235643538313230383330
+34636164313061393433316263613632626665653432366232313635653864646136366631333938
+31393135303663323765333262353338386461356137366335643034616166643862316134633666
+64383930383137393666386466626630346165643962313233656635646331393062373830656337
+33306538653066633061616331326234393865313831653864663832323663616631373836636236
+66353739323434636637316633663231616239326465373633626432653339393933313839666464
+64326238373862303937643635373835386339393264386362346334626538613533336466616435
+37653536313033643134316636653166346461323965653530393637366564663038333534623830
+32386330323962646631316235373634393965356535626633346666303532343938343334366361
+36636638633966316362306362626535306662303361653836643532656339653838313063313232
+62653937653465336163366630353236656230343330376636336539346630353765396636346265
+63333761626361616137316230323966333132386433333365363961346464656432386461373037
+38303430333336626137623337646633386334626438363939653734393135376538646433623633
+32663963393761643666623834643162373164353038666533653439343332346563613662356663
+31636562383662623138613432666565643331396133353232663634333464303462393663373130
+38383932363264616666393633383239613262666634653831313261616665356336613839323439
+32333764363630656165633339633434623338363065343437613134353435303563333839613264
+34646565346330323036376436623933343037383065353538623764366130376639323535356461
+64363639396362346639636235306565663066366564386337666664633034323761373032646233
+36616162363335353562366434396664636664643034336264633633366533653462303263323965
+34636633653463363565636536353039303962316534636530353031343966356635643262343534
+30373466666565396135653630373830616432343863376265646438643265353337633530343637
+33313062626235646630353637656466643239323466653731333531633063373333393633653038
+39336461656634373533376366383237366364366434353163633263636163633036376138393162
+61636537653564663634343534616431356635663061613036353338613234663634633561616238
+33306534656130633537383634653763303736373035363466313138613762653139386366373933
+61303335643063663063333234363264653962323939656566633533643535366239313335376165
+31646537373933366239613063666636313535393765363165373539626531633062656439313235
+34383738316366306563623031303761393265343366643264303564356339376437643963643035
+34303035386539353435626566306133336335613534666462303537373764643836643735643034
+30373237363330633963656337346638346463636439383732313663663636653763353666306562
+37633330326664616166353330343264303565396438616463656361656532666130636334366562
+30363630323230373036636135653533326661333836613934616466346564376161626131623337
+31306338623534613662313233616134346330343561306438646461613165386166636136633132
+62396337613265616530613061653762383565393434323931633330616530643833336136623034
+34326661343464376364613132316531393134613335343162396238656562346162393038376166
+39636331346235336465633237396637653038316261333565616439656633636532663137623633
+31393463303331343734313465653337343564303133633034303466643766626630333333396337
+66646234346435313535343536333865316639336230373732616531363337316361356635663066
+61366163643364336339643133633339313831356164336566613431663832346133626139383130
+64633933396462666633353661643737636164633930323165653831623435653539616630353036
+32336535313635313066376338343434396631653365356264313661366331363839363263356531
+37323663363863636134333531633766623637653664316333626333616333356466663230323737
+30653138323333336661316537643831623564646133313636313934383061386235346330623632
+61396536336461356632356434346337363538646133393932626533643335313862376436366336
+64636634396332363639383866656662623564306435366564383936613665306338383264623635
+37346165323139313930323838633033663536616361306664653231396465396130613561343733
+38313039353930313263653930643338653438663965643435663864326336386437653333376362
+38653962363164326131363235363736633534373362646532333661326638623363353435366661
+37353665636437386435633666373836356566333733393732383739316531623437386336366562
+64656336396139303766363930663430626330613265363238336538373538643434383263303434
+64633532316331306534613134613035396132386463313063383062626133656135373131393335
+37386161666365323039306238623533653131363933663035333065363535346262643466373131
+66303736333038653233633932373061316161373061313964656332336637636237333834373763
+30366336613233343461653134386263383331323935666363323463663161636565333037633262
+66363539656461346363333562393963613462386531616337353132623962393562336661383438
+33666230663034316532633766643934356461353262643635646138366165323966316637383436
+32393065393830646637613539633237663232613234626465376563373738396263313361663532
+64613461326366363637613665303963643862316136636333313066336562656133663261373231
+36663234373166613864353130663761353262396232336563363534396135373463623761653839
+61613863373834306365396539333839626133343239353232663335313237636638626536373466
+36353065616433383165316465643362623937363337323437336566623665353032336564346161
+37323161653432306532366439383231343936626661323161643430633065373664333538343032
+61373036343839306539326164323737363037646237313666646366303138303565383663363239
+35643736303536646436343330316661663061303261636338633237383935633961313833396532
+31313732613939623661396336376435643030336263316639353034616530346566386536643235
+35613765666232623639363530346166643736643333333564356631623635636233313335346564
+61346232393833326562613834383132373366333965663061306438633737353037353261346663
+33363062633366363634333139326532363630383333353565396435353565313564623534613338
+36666536383932626664353361313333343135346639626336343663323238376336663561316362
+64303433303162363863393864333462353766646232353565646665653936623261643639646264
+38613031326362623039326331633161666231646139666530326238623733653538376232313663
+32356630313162333065356532326463623661373266386338383531313330653463353036363965
+61653935363464663764646661656136356165333237373233346236613165323662373565343532
+65383935323033383039623938366530306266633763643239386435303037356466653565386533
+36313764646561343737346335363031386634333961316333633038636532336161376562633064
+65323139333533666464656239356234363135666266663466656461613732623536656565666632
+61616435653732663537353066363664626366303064363039356337353431376136653738343462
+62663431363665636166393166393334383332623635666562313037363965353664373965316265
+31383436306663623463336261363337663538326336623564356264376434653130343535313762
+30626137323838313264353030356265626233373236623262313661333833363139633639363664
+31393638303738353030373639393931656534376131613061353162623364643732656232333436
+34633238383331353366323663623238636237326134356665646533646638333166366633383231
+39643531616264616133386431326234323731366132393033316638366538626531303735363066
+38623662633438396565626535616361396264653465343939653134656230313062306232373930
+33656139616361343432643835393039353761313334343663306263626164386339353564363135
+63633463353231636665323433363038623031336463393034616538346638343863663530663932
+61363065303031663463343762306238303765313230373738336661396465373061383636656265
+37623535393938383839306466326137306361643962646166653836303730613665323165336665
+34316439326332336339373236393264636536653036363135396166663565383864613235373061
+31613663313866386531343361633262346637646363653031343637336563396638396530393237
+36383635303633306438623136356638613465353439303730313031633338336631653264396138
+31373865646335346331383838356634373737363737316130663931383635396235353561393137
+63336365616466363766616532376462323336656166396664353966623562306363313463303234
+61626663346563333162326366666361643330353439376631636233343466353763613866366461
+61336636646331646231313561613436666134613934353938636330306261623132306166653838
+30306664613962623336363836636232303461303333633030373065336664323336353134313733
+32346531343535316436353663623936393065653132653337393364383830323538323332393536
+32353937343335393761316539666438306262646131356563333238613064343764653832623133
+66333365343331346635636630353932653837343264646165333535393664386161343337656138
+62353962393866626336383264396331306637633162663932623831373535303939663031636633
+61663761313732666464643361653635383032313932346466636634316431613663663163646133
+33363138313861343965376637386331663339616562383262313934353032616264653337323933
+35356666653134343162333634313430346437303262613562393839616238306239333339353630
+38653531636536333665303766363866656533303562336135376236643931316563333362636164
+63653564633362613465393562326637306538313936386231393663616164656163393438376436
+65383636393230363963336131353634393265396461626131616233666663666466326234326331
+61616436623166373232383131663663646237396563663335383935366537376330653462626366
+31633036306337666439633931623038393330316633623533306238303832353932366235633339
+39396234356634373339356131353832333832356263356366663133336236363337653631636132
+65316638633831626531343464666636313764313134363931303365363862306439366138666138
+37323639376566356338643965343464313236626239616438613964363930653030333938633538
+30616636393236336437313436313638303062636334356266383537346435386438326635376232
+35373965613462666331616337303333323836666532626465653933373562643834306237633830
+65303835363266613235613136656132396631326237643130336338386230373061326333343464
+37663565636330323765646536623961643832303030333564643664663030653232656534366162
+33316439646132636132323933623635636536666263636465336665633935643830386130356662
+35343833656330663139333065393330626533663137613734666366643962376131343236363831
+61636464643439613238363837333130656236363433303461363566396536633430323837326238
+63333263333836313535643439313865393437616431643230333732393036663833613832323233
+34303631323038653139396634633630346163363262393662313865613635656130626531343164
+33333437333037383133636238323364373035393563366331663333633133633161393239626264
+35626236323961626636646466663061653736376465393965636635663637313537323733613533
+37376535663163353266336565643363353936353537373938306639313765646438353730386631
+61386334346135613333666261333430366263633665646234336233626561323362626337306639
+36653962313037343837396235663530346231353565326233396565623337653831386530333031
+64656561663534303262356363383035376436366562643430643162616264656430383139346663
+62393735343639303638663831393330336234393438313862393839376636636563396634386561
+34363064663036303633613365393164333433636366393838373939303562333135613864316261
+32326333653337366361303439373464303961303164626461353533383263326665623465353937
+38313536353932613038633561656530663665626637626232303662663565393236636264343334
+35393838306535363735386464323164363937326530656561613235393434653864646338393135
+31356537363364643135653936363762646232343663653636366131383862353264313333373863
+66373735386334643764373237306636366132373161353134343836663761313334366334356633
+36646537393034366336386133643338326635303538653964366164316161366261633562343630
+62346461316239346661336662343137373039656339353534333437626466663161323366326535
+31373338636462663130613232666334333434643463383665396537656332623338363062326134
+64323761643366626233336163356638383665363139653439356438633666313432646237666233
+37613033613731323661663137666532333462636166303863373761633061613764373232343666
+62646232656432383831646361316663323964343263363065383136393737663430643234333130
+31303666666262396638616136393765383335623130326630353037303335376266336563343738
+65663163646563666533316231643334363133366335363661336466333835656436333961313431
+39356364313863343431646633646636336236386661643032636139386662613266336633653363
+39306264633766346532343635633231356238376533396533363632376438336164383463376630
+37333238313334306230316363616131326333616333353037346262656666656333623736323134
+33326663383237616663666339653230613034623831303362653330646634613766613333663762
+66356431343739303962663932316435643538356165333564646530373763333636333332313033
+32376135336439336661396564306432393763653835366664353331336537643535396237633363
+33343064346130616135633262643631636233373930393531303739653234393566396132383361
+66333835363763303330613833333532353933633964343137633065633266656532313738316661
+64653564643333393164313565643035663431323535353330613062656531666361316638366262
+65386233376661383035373230343363616663653033313036353730373131306666633237343032
+36353239623839636664643531363561663636366563373638303030363832613430343134653662
+37376131383238653038396263313364396233316232363665353634633734633462656561616631
+37323566306135346335623733626637356531313034363437356364363337353730363436363836
+38666637363263626635313836626630633262313332356230393733323832303237376364313764
+32383637366139636462633834333066303637616631306439633931353534323830663538383664
+33323861643431363065363061326366333534636135613738393863633332366461663132633232
+66643764646337613533636661643637326533633832346230386465616465643366643166333935
+66653230633635663439386366623932316365653539656462363531653264336437393035393231
+38336135343065643736363337376138663063663131636562623036353366323236616466633536
+36313266653564396436383864316464373431666533306236326237363632393236663062393231
+63386565363865623734663738396665656330346137666665393564323137613131303965346538
+34336662626164306139353762373365323932633436303339366236373232393238396231373038
+61346266666239663339303431616233643034623434653132316234373136623532383832666330
+36663539306563303931616338356430336438336237376234633238633662396134363262636233
+34383639626533333034636637356434383466343530356337326264303531653263616462643961
+37393334363862366138323437393139333730373838653764353761383061656661636665633135
+34383036356663353938346530643035623939316134663138663939656132616461396339636539
+65346263316263613137343539343232353833613134333863366237373463326466316137366166
+37306632346363636137303061613132373263363062653534303131323539666536303230633637
+66393931393436306635356139663832653166383337656262383339396331346230633163616461
+61386635643034656538323638623738613534363932353233633330323033623530653137313361
+30643331393538346433653933366232356364306264353337633431303662303765623333396463
+65363730653933323431323961363839623837333964333930633166663936353062623366333331
+31363164623032363333643430366530343237633063666564623630643362656164393635326530
+31646366363962656333323533383835363734666166653561363561333430666233356562353630
+64393731336535343435313164353532333132623338376236346230393966333164616537323231
+34653962643337333961633663373333343435326261343032633662623239316364653839303130
+65363062656336376661326334306161663238626238633537613437386632356638323064373866
+32383464313064326533396663316666646134363534386163313366356664396433313632363236
+32396136396338616237333630336130313036653734646435393539373630643264646633386232
+66653833363962663633396331643530333563383463313862656535393932363039306131353732
+31613934616438333062383033623765386437363235393462333264376133353030623534313266
+39383830393631386538323637303365323665613936373237393639626239346666373866363662
+37616231373864303462616534336662353761653330326163656230346564353237646637653734
+30306133393039633566303332626164393235626163333133343133333762333461343835366239
+62373066333866653730633030316234366234353431363430396531666636373539333135656334
+34383735353966663166343732633938613230303362363861386363346330336139363932653436
+65303162643331343836613766346536323236366462623363613963613839663237383030393561
+65373762323265396433633738626530366363636630346132333066383363353834313333303432
+34393239323336616434633731333861346332663939386561343931376634346561613939613934
+65666338663434326337313237623931353937336164666366306662333664396266666662303662
+38333532653839663762626431613437386564333462653665626231653737353039663330396135
+33373039353632656361613266333932383262396265326638376163316432643362636336653439
+38353330303031313131376439616131396330363538663734633362323239346138663539326665
+33323437323530653264613165636635353131336538623864393033353132666338333832653561
+38333965386433373432366361666233396337643861663837636633623865383134313030343064
+33333035616161383039353839313438363733353535323635623264363666346630303431643038
+33643938666337353262346533643463313465303964313736333435613835386365373232636465
+34656434316532633437666439393732353965366637393165363062623665633035636336646439
+31316631313733303030333333613935383961613839623035363235643539646431646638363766
+30346133393838373439643563646161343265373334316161383631326663623935623437343865
+31353232653863316365393439336634396261373336643765613566636563373733303634626366
+34613935376463373834353931643630336630393438653238666561323334653338323936356630
+63386262393439313731346262663766626137386235633839323562323561623966663162353062
+38623263393164643733646332376365306638303838356461323335653536646439373334393562
+35646435333061326439383966336535373936373134303265366433653330346665613762316537
+65346363626666656261343761363838616432303264326133396234653461326632393339376665
+35663235373562383733343034396538653261646539376436356534383066646435303863336464
+36373330623138333739653435363261386165633361336439343539383939636463616163633638
+31393937653435323833666430346136353630313433306433356630366464313530613365663931
+38656136636430616139626235326230323731333164333466366164636439303063643732346633
+62303233643261656665306538356238333031313138363338643738353134613630343162326639
+37326262303432663638626331343038633835303231373532386165643831633337363737663736
+38616233643461326539353638363039316638616530633435643839306263623463376563366161
+33353365636130643033356330653432633433373232383137633931313332373362326135376435
+34656336366163386335323738343763653838343838303931643437373366646133353738666236
+65343661363161393165336632306462616137613061366636303764356435613738653036313834
+38326639663361376237386233363265333261646336653763316532353934353037323130633266
+38346266323936373338636666333832613733346135616336323735383963643830656439636533
+37306530356532383864383432616130393534356432636663633936613631366566363939633236
+64376133616333306430653161663863663838373634333437383031623939636665313030666537
+64396632366264646434616334323036613664333065303437396563666339613232336362656136
+39376532366132306238316434373066396336306132633631323731633364326233356334323936
+35623938353762643730643438663235636464663662643162326132373139373065343632396166
+63643933373531333161323864376332323663363833353434363763353133313566323337636332
+33396165343962383236356332616631643235306265393932656632373138336263313562323963
+38373431623236383866366631333031643735316163336332353033396435333762636331646538
+30343034616235666162376338383263373139386438303836653935303639383765643761643837
+35323336613164343765336138356134613166383339323865343762663461623339656533663939
+66653436353630623032626439386565303237333366623662336436326533646334313263356366
+32313962373333646664346438363931363864616636326531313733353632663539343865666665
+38373038616338623632303133346466313339643632663261313164363366393465623036333138
+65376330386266383035623564653064636439323664366237616237613633393331356430333432
+34656662313465303434623466666566663538666464646133653530656166373230373865653939
+63336138333434343463396335663230303865393836663263346463633865383966653232636262
+32613362613266643134356637363338313563363662643135653037633433383265363535353336
+39353661663234636263613039303666333135393536396666663532366530303665326537306564
+39336231663135656238653761343235623063643637343565363866656133366266373764333430
+31303666393231353238376166656264383466633038643338633737346435653736376133383636
+38333238363861353939303431653432633836373331663330623838373736326166373461363864
+39363438633236386563356635366265386363323462353435633330386265323632643234643436
+38326363323830313631616636616633396532393232383438646465626239343661313030326265
+62643165353963643834653534636364613165323965653732336261633063323931663666303765
+30306262626366306238646632326566326663346539376333376535666266373038663633656138
+34663566343231613733333931393138366339323936646331336232363730376331643963623135
+63343466343132313864333736323435303835383462666332316631323761323435623231643939
+38643562353936616434356164626539376335393231306164386135633261383935316366306434
+34303662376130303436623036636230303830383464616336393833393239396537646231656336
+30616361646634366634653336626133373136663562353630653862313731383337326230613965
+35383238363335373165653562656535303764316237316537346133616235393961663238333735
+38633536386130303832346635393438363061313862343538333061323063623538333730646332
+30363132323235303231643331383263343666646535363532313366396266646266373039633137
+61613134313930323837336638333337323965386635643338376337626135376536643332643037
+39313931343038653439353734303239346132383763633833616665336361336231666437346330
+65346466663233363761393037633663346464313963363661366464393130313739323661633634
+64383733316635383062616465383765663130376565636262363439623763633862303731323665
+63333630343064396137616437303937336234336634373264303433643564343264626561393365
+38343230336662333638623038646536373131326163376232636439616332363864316434653530
+61663239366232393861363535336533326462633331633739613333616538383833373838323134
+62313537343865366536363436373365346134333730303936663438333737643830303238616162
+34623466653963363831366361393739373431666464613933383761396662346438666234353236
+35303335613931633861326236356533336532623038643238336366643362363936393863616264
+66353435343565353037643361326630616464366664633731326161656334383764643034396361
+63613862366437353035333932306530383738303866623535353135313537326433376231653134
+34636332316565383237616532363735653962636361356466366335613934326566323230616232
+36356135626233323863386662313838356339343337353663333161313138363566306134386263
+37313439613161366639323338373839666130656138663437373830356264316632653866663633
+37366534633463636136643438333466333737613763393338306236303430633139373763373563
+63653561656137353933333832653735333030366661663537636138306164626662343866333230
+34333131643762396465333632366135393364333037623932656134323733636634646431636435
+31626334393836373730643333393832613162343332653362623832323038626461323062376238
+64346362353666393563333733373462616630356265303765343939323431353834366137306463
+38333266393233333933396630353065616363626162383737373237663036323235346636373739
+65303262393965326138656536616436376132316530313732386536336461386665633434343165
+37313531363633356130653539323364663039386338313434306561353632323766316363663162
+32366665616136636533333765613566333334356565623062303439643964653266356534636531
+36366462306639326239316438656333386238646334636238323038666566396135613363363239
+61396630663662323134363233666564396163646666633336306266613262313061643730333331
+33303036313638613137656630626262326338636361363265663936636462363732663833346366
+62656162356465643939636434323061333861343838626533393237663431623563346134353562
+39633632326130343732306538353761626665346236313037393039643366613634663365343666
+61653739373837666334393539306663636562373531383435653932646635386636323066316330
+65646265393038336664383539363536383534346562326262333565303764636533663966643463
+36366335646432313161366265643231326238303930653031386166633939613831363262343465
+35356634366631333937343161353934373962303862626463613564323334376666383630333231
+65383334656439646239383864323535396365316263376537373832636134646132646665396137
+39323266343938656137363266613239346563613761343532313735353663356264333165623662
+62333334333163326161646662353963616364386361653964653735663231373861623134663133
+38316262343937663830396437386439353934326166663231353563626636663561363136333066
+30316434343965393437343565373865326537653765396430383962323263356537383331643264
+66306465636162363366663235323530633133396234613135366664313739313838623236643330
+36623136626264326133343537396663303333636637303435393638383166663962366236653064
+64666133333939376331336662356164663265653237636233383532323437303066363765316262
+62376464653431663463336638613134376337303166336534663362623962363638663531346433
+32353536646230333463663938303438396339656436313332333936313434633364363839666535
+31353064653135633662306466353362613133373239616234363765343433356537656330666539
+30373036393063623439623465393864623030633539313332383736323430383764396337303834
+32626665323737633764383835643261623535313366376333306130363733356436613335653862
+64383364663633303566316164313438643236633930636166353233386638646139653339646363
+63326266313139336635626130633135643936356463656661663866393833353236343739393939
+63633861313666376665643730393361396437666236333039383630386535316665656561366538
+65363664373363363665306261306466333161653533373262313563623062653464313037396664
+66373465346363373131656234326633306434353630333531343838646431316233343830336362
+36663264613166303330393332356230626631613338633934373532336565343264376661346134
+37666666653439326234616439616637396434633333623737383563613832653130393662363665
+31363866613832383636373434326162383535363133663732656665356336313039636432303439
+34396137666337303338373936353230386338386631633534306364323236313739363636626431
+30386132653435383062376635376162366162643335303864396230366431386366386262653435
+32303037636337396663626564626336333033393539393130643162306166323236646561303833
+38323965363061396534623761663631343938626661306633366565653735333865626166353663
+34663731323735376662326465623730366662373436396266383636616633616230616463656335
+38643564353738643461383437363139366431653438306632356262633031623930626166626332
+61646136656539653638613665626566613039373836313933656636373931313762306466663265
+38363765313135633931376335323364616530366366623931363834653234636530333131303032
+65383735643234626566323266363238386564636263393564366235346333303733323132656239
+63326332613838666161383861613037373965646332656565666566336338633232653161346131
+62303039373264666239623962633436313438643030633236333539653936363432376461633835
+30636264356237666532653338373031616236366264383831656561363230636535616337393537
+34363536336361353733323030383131626564663236303161306332303736333034326366326265
+35363963353163653065363633333364666664393631316239383331316462346537376263633630
+31613631653538313366653733363163383365383665633432656532613633386235383761636665
+39663061313761313233666532633366613736653766313166326234373766343532393735653664
+32363965633434363130386664303663643534373236373838313065363634313664376137386130
+62326432306461663630636231663735613535623834333931343664633536396235313531333034
+62346135303939366435336664346539616436303465316439643932666433653164366163303435
+65633064663339613032376462643566313535356464363861646561383437633463666633646431
+32333765653363343436356663323439383030613762653566623832386464303931623465396433
+62323961316662376265626637623630626463376530633834623461376563323033616363613637
+36663165666461306666666338303230663937613036643066343665323465653337366462303234
+37663330643431396537326162353838386437323536303431613664656464613261303334336234
+39323530306338373132643666333266626330613661316632623732316636323731383338376166
+37333665323961653939663066346432303134366139326563653363303337613638613334643935
+33386133363236316638306235323737346231353139346562393639393032366638303237303234
+34346262346535623566636338663765643961616131336462636534663064313134663232346130
+62646538626366643466646338626464313838376239396462663166336337306166656565346433
+63656265616166653461656263353662303066373864623061336365326666346332653233396530
+38373366303665383133613063303736303663323338356532623139303733343962356364383134
+65643834376531333261643835623264636664383431656664303961343834663665646366666361
+35313463376263363263303664393636313231366261303738376134376236333764353633333836
+64326565643136306138663262363232333066306162363363383230646461336163333431303963
+62613937326132666638386236333465393438336666303865396266383738396366303236626665
+62343732303266356432343164316432663466663335383433336632396364616165326433363266
+33636530303735323462346135393939306535383566346530643862336232653134383165353734
+31626363353639336438363465353565303635313835626538393566623861383263646131313765
+38633733303162623363363130383637663366643666663038633537393261333166363963303837
+34653331323862306464313064363964633761383361336362316334323562323730326563643636
+62363035356564346361633030613064333663303933366134613764626534383830353461626462
+30653830663730626230363231616339383738363030393865363835633738333236313538636137
+35373937383837323566353461623936373963666437646334353066373266386435356434626463
+30663835666235636362663332636538363639393439613966373366303062336461303966643664
+33366161633639333661653765363561393564363364326265656262393030343531356534393038
+61336264646132306466396637346136623231336631646635306264373166343864353662346630
+34316630383432383664366334343434396435636532393461616565623436396566333731663937
+35383139633966343566393962356132383232636564363338663066386339373538336166343965
+62656436646136353833623339323163643131653863383866626364663432303930643835346238
+65386662663263376536373731376638356366383965313863666538343632623334306531343337
+31613465343662623333373865373564303935376434353530316665643932643234633834383331
+37633534396665666564363361326139353939363861643530383231316231326232613038333930
+63366463373862626338626531326137376265616430303961383239343264343936656461613339
+35343766393235653563653831326530623761396665393739666362393330646134623961373233
+35396634363063366163643334646135346664653737623632646535393861393264656263336639
+32356263623366303566356430313439623065393366636463653633343736376234326266656632
+62356464376530656533646237656339313161393165353431633462363062336264616565323831
+32323135623938663839633433386432386530656238613464333731636463393964313931613934
+36323035336532626232333762653136323631373538316536393364366537336265326334336135
+30306332343533613163626531366638366533613163303833313561623333633836353934643562
+64386666633335643731613832656230343930336435343930396633353962663630633035346431
+33333361313336306135616539643037656262383937323437613332626333323234313861323165
+62343338666466346266613433303735663437356462333133373330653963643364666536376263
+35333537313762313037633839313130373239376336376431396635373463643164666635353432
+64303364653130666333666361356531343465306462373032353433653061626335393437303332
+36663962323063646663393966316236616663623734383030653239346533393766663861363739
+31396630356264383338363364313862366161663966306135643639343362343466396136633232
+30323231383061326134616366353631656462396166343938393463383539633039393364316362
+63326161313137623964336663636637616530373262313031643064633631623239373736623461
+39626435376238626130383931333665383935383765343630383135336631383336366465306136
+64376230386235363138636130333930653039346332383266643463613531663530333930396339
+34653961613035633231373833346638663533366335613139393365303163613036626233363462
+66316235323236636565326230376133316137373131643166663135633465303636333962616539
+33323033316661663238653433616239386633356439363365333039636136363265636539643264
+32616639383462373639626238396261313037306239323434336664623261346162373039373662
+37626661306365653039313939646164633565386533396136663330646431393030366333356264
+63396332343139643839353033343562396131363035383665623964626366393939613637306361
+62383237343962623662626332326238646233663865623932666134393836393461346633303237
+64636231353732323434356662326230363936633861393965633438326236616561396165303365
+63383436373139393331633264313062353839616131346338613336386662366362346136663234
+32333534336161396562616664343666356233646435633633316465643161333862623062353933
+30363261373065393937343039313662346163336530376166383738346261656438346565653239
+62653237383437626361613037613039646562393261366633653837303461356562306562373239
+61356634393361646330336332343932363334633637613339636637356338313031333263643538
+63303962383664383565646530346634636463656437303262376366303035383962666230393963
+36643462633730303564623261313531393336363830326363376135303436643531636465336532
+61623333303832323964643038643237353164633633303636623233396639346332323737656631
+37666331366239353339303636653437313665373837613566396665316165313138646261326262
+62653365323538653566303434653031363966613839636661306130393133363932326166333739
+33623932633138633035383363363962313932366634646263356631653836643932616632656163
+63306334616261663933316165363736363232643536633561373636343131653633336436613531
+39366234373836313166636239356137313166346133366332643430363437613331326265386536
+65646461396435376265333262383061613931356261303938666334633836666137633962336636
+36646535653235623638326264643464316533313031333665633338356133646363303931346431
+39613438306663326630396664376238363761633136326135323564326361386164373639386136
+37353966343838336538333231336263303438343339336531663932383131326166663932613236
+31356530613938383364383262616338366635316636363061373832663563373536613062643939
+62613532376630666134363564333430643532613361653138326330656235623231306435613233
+32356635306135363335313431366139643335393634643738643135303835636138633736373932
+39306463393538636165666439656231333066363632633364636266646663356535336237336530
+31393436303437323531306232383262613661303430643237626337363835353731343862643863
+31626561616136313835363433313165363762313038613132643330393465323362366636636538
+30343331313037633262336332613361356130323136353864633432386432653534353837656665
+62343765363935323964616632336339616364376130313463613739653732636234373334343539
+37356236303463323163613038623166366464643531346536346136643631626665363262656130
+64626334336138343062343738326132393866613531303436636436636262616237636333393464
+38363962643236336335626130353833356536303235303930333636636332623230626534336436
+62373037313261383261666433303635633834336133353231383532383864626536306337303966
+36393736363030396337346132396463636565303737313065643233363732366661626264623632
+37313535353032356531656635323366366563313932333564343962636430393862313231313333
+37623231333834626535646639373536333031666661386163326339623835316632336639663533
+61313733643530303065343137386564323335303937623835343862666630303233656438343163
+37356537326131366131346433663635333734666630623530306232626233303562613231363733
+34653330383334333366393239386135333732313734313266316361316630616530393038633863
+36333363626165633264636162393339356162623130313162363064393065666437393564653831
+63326336613265663664326337643333666332353961373061303536353563346166376535636362
+66343233653265663564616331336263396334393534333664613533383566663437633466306566
+36303363613238313933653739356639306263346539376131363132346337363965646333663230
+31363962643634386663383634396163653761313639306663633864646265633464366130353037
+31623631626330333663353935336434313333376465366463306233383066396163636233663739
+32316663613365326661633235343838623564386134303832623164356362353833313631323961
+64376362383536316537633138376138313266303738323866626365613963323531373736386534
+64666231663935363262383536636665653463616465323661393331373539386332663131313034
+63306230366262373332613638363434656261336236353739383539326233316130633064333162
+38343864333638363933636234326664316338623136386436663038326234386433303635656530
+37636137363934326561666663383362656430306132366161383765393632303263666437643535
+65316438633435626434323135326262643263636437376232616463393663353431333034653536
+66613139666365333062623763373737313935373763663534346536386636326131323532613762
+30353066326635343432393435353737656465373639386366333863626334343664626138373838
+61656665633761343735366236333261613132363965653866306233356133353333643933623463
+63313533383036396461343138353935303637316133643166383335663631633436646332326365
+66383961393034646633313364653765613434333561333638323237383165666163643162323364
+36316534346361636264323866616439623062626462373361616138343261643732303638363262
+30373162353039623463356136633262623039626532343464613066613635643062636232396165
+64346263623564616165333631376466653539323761316165303233653839333138393436323836
+30353466363639306662386165306666393137323264323461636239636232386536373039633136
+35366436663362303065373431386530623666353666353630343337333030363036333365633762
+35613061373530353264643163663064376563346262616138333938643961326664326638306665
+32653037366563373861343961363836666436336332613063356466643335666266306531383736
+64313063393365646466393366396166613835393933346461313434373164313432663432633432
+37616439353963656165346165336261316535326639633363343131336565353338666461386662
+31396531336666366131373664636130376538323062633238373238326637373633653864313762
+35323264336438303634626237343332656362343736633538636166323834343064616333653164
+61613766326236353761303733393862613166323465376561623731333832336336613038363063
+37313665333237623539346237643530663763393263373963356265363831633233623439633132
+30356664363933353064343433333338383762326632653338343039623662373262346564313130
+63626239383166663330373961623265376162396537373561663632363933313835383762636639
+30386434353131393062323663663662653966333532333938353036323833633138613435323133
+62373631313234303434623366653531333139646632323065343137346231373666336139343566
+64376266303931626564643632616665313933393732373235626363663235613561633765616462
+61633335646332393439393534326435376638616462613261646636663062326130356437376238
+33353064383537643536643238656437636365383563653934396132373761386666633232363133
+65656631313232633839333330633735326433316436666233633132616332306361346361313134
+38623966323066616663303663613136646562633061373765393663373738303666323736393565
+32643439636230643139383562343565313265323739613134326465643435663936353233396331
+37383862343666393766323132613262303530363731366231343961396135306332373066653931
+35396462353964363365663234386437663238383431396564666434613237386238646338376334
+36303463343762363365613965386566303461343435626437326562643736656431393632356337
+61323431346635613637363665663233373932633362343862636261306161313637666363396435
+39326564363061323861653763313862663834376631326565383763343832623163383661373762
+31353233636431666130386338303263333039633436636561363939663432613735626630336236
+31303339616439393130643961646433646433663234663738623662666162333036383665663230
+36653665323636306132353032373435623639336364323937306637333138623638636434663161
+62623064656166343562313466653062373361366530366639333861366261343235306536653732
+39663366616666356335336439643262343463646232643933373631326530306165346530386631
+34366665653833353364613339323539383034636230643537636237316539616665383332343330
+38333661373135363430633631336166663866393834373238616263323934313530653465363261
+34396463363665343063393632346363646137383833343730386337663035636137366434306231
+35623737333962623235363563303165633766313330326330633138633830616539363133303765
+39613566373732376633376638363532633833353737396434326666623331356161643033373533
+34373538346262333664633438643339663766653862396666333664373036393838663662383263
+61613639653063633230383536623165316166333534393866363533366363313161386339313034
+61373636346331353032353664663339623736323031623438373331323962393564393866663363
+64336662646561386537313464383236653839336432646566396363306235303166346164393763
+39626465336539356364373266303866636365643633316139313036383033346433613332386638
+66336535316233316638316434613466373639393831623333653831326262616231616566326137
+31613236363236393039313265666532353736306238663036343434336237626539373333303430
+63313462316161303666383863363439623433383862346232663466373636636335366364393630
+63643639313733326165616364396463636237633035313738393333626635366538333563353565
+65666238646530623337376232366138393832363530633865326333633564396461383666326638
+30376233396631613536643565333866636265623366383336386131383661643835376566393031
+37646664633638653837643135633831333662616264613434623930373334346232643965383533
+65303766366434623236336538643761613131616134396366316435333636353837623239646234
+36623730383264656131353463393631333862633433343437663438613738353133303030346635
+32343039383333376132303063363530343539383431393865343834323430653934376330393632
+39663133383466346562323863646233376664306662663331333262366331363130386332396638
+39643061353532626637306265353231376266353665333031613734616539343064326136373833
+34663638643239363132653965653733653836303838346433336161356262363533636566613239
+63333234346561356665656530333461303838363230336538643061393566383764613134623966
+30303465383636376164313066623863393737386335303036356632653761306533643737313437
+36373038633330363935633137653665346166306634633161326662363739643363613366613636
+38353638343465646635363164373066386261643963366161646536323566316539323532653434
+34323965373264383335393265313834646436363338383237373634346437356266383463646663
+32303436353166396130346432333962363365336663346131386366646132646234386135613537
+31353138323635316130623663656634653861663430343137633434303563343831656530643934
+65636235386231623430373734623534323839363639613566323231333536613833626336326335
+39373232333764656666666264323431353762343137643031393436633533613663366631643764
+31373433323131303230366263653064356539396462383464363039363735336363326164623363
+39386263666366626538626163376466373463613366383266316633633565333363323734663334
+33383965633061636437393935646166326263636265666163333431613036633066613861633165
+32373163333430353234346262643933313138333262633530353361616564316664643336343865
+39353665633434613939373838323636383662636262333836613932386366366363616131643337
+63333762303737323062376166633531653065653332346236613766646163373936343164613735
+65666163633033653634663931363738346134323835373132366165666665313338653233333064
+38313139313265303838343162326238666433666432613038613465333032626536326264366238
+30323239303538316463613238663163656430336531386138343661663537326364356135366239
+65303830663631626638623131386532373435393136386365366431356232383933303665363439
+64333730336565663036303166316461313439623263303862323334633361643866663932613633
+37303765323331336333393831333935646134636263613632346661313134366434656637373134
+66386236316633646436616639306130623361633662666336663337326533626436346462306536
+61636135663038336461633530333335393231666163303737643030663235613938643162363166
+33333338373934343634323030663265386339323965346566326237313965376139333631663432
+62333932653532636632323730646434623730653366366337326235613631643634663437323864
+33343361313462653065393439306431356561616432383761643038656534316330336563343739
+62396335306636646535643036613731393463333033666236376630613930663334306332613766
+35633864653233353863613034373434373032653035653364346466613431306632383563323234
+34316663643632323962383831643662333632326632663065343830393131303937336231313435
+62303737643664323762386438373631366161363833626665343236323765353131626434373237
+31393437326266646633396134343535333434643532373264303438616536303435653832343836
+30363566633264333533376262356234626561326663663932326265306139393163353632383534
+66383335396639303239653439383233313266326137393731663761666564386135633934343763
+37623434383935316634316333303830313935316166323161396332376265656530316566616566
+64623732393938666333346336366538323436383136333161656463316337383832316530373531
+37383335306536656230303065346630386633656334663432613362653462653039376533313831
+65386431633234383237393235343236613538346333633839373165656663303735346238323535
+30393132643330643735613433373666626630366339326661363935666336386333323831623930
+36306635646536386561343038633938663866626462626239633062623039363163316133373330
+38373038343333653139393264303735653362313063643630373563373638626332663934323861
+38613936363636633863376535653365643732313135633736616435373930353136633337363263
+65306230613964646136663235393161333163313234633261613965333531306238666137333430
+35313233323032356662643931393164383765336361346239306435353035373339653364613962
+66336632616133396431626265663634613434633834316538643434326565643461616432613266
+32663032636537626564613761326239393033353666623136656435366266656133623332643639
+38643431373430366239396463626338633038613634636362653865633561623934356130623465
+34636139323932393931373538393033343061653232386164333137393837323630646166383231
+62393366323663386265386232363135346164373839666638343235313433656336383766306637
+37306230303030333633613335396462343162323063663733616230663138326366616533393762
+62313162626639383166643636653165353263643335666161386433366539333530376138646237
+36343132333463666432363065636333623561343135393730333134333161613763616232383832
+32623365323435306436623836366663623566653330333461663263343964646164663666646330
+39623533343664653364376233356261316365343265343134636432373264343230393135613763
+31356238303263656261356237613139303836306166613234666266383966333037343862353466
+38643731366537326331356334323931663863646362613831323063326266353434646539653130
+39343865386231316130396636326231313463663435393135383333623135613434373062326664
+66346461666333666337316565393634326630353331346362386334613564356561373539623030
+62323638343936363735613436653466353037633864623163373161623837313462396231333637
+64643036626135373364636339646637636231653666363765386533373066663132633161376433
+39643730313534306337626161643265626634633666346539323662326533393738666437663033
+32306365663231343938663832663363346432646531646332623966383862326662643463383936
+65666631363237663734633733393234323337353738376633373036626331313663633734353762
+35366239343339623632616632653865653239323831326566613630363463393233323933373863
+61343131336236393164393563386539656536306333333137636461373966653266343861343631
+66303439323964363365383466666633356335376665393239623861363838373032303036653438
+38626239393035383438386639643137396665613531323864356162616435333236346530393166
+62326434303838343331623664396664613962333262303435313966633133366466643966383166
+36633866313830633532643934333935643661653833366663306538366161623634393665333464
+31633161663562653031366465666232313434333635373435326330316234633132623436653163
+32366334356233363265623438353430623131376637343636653237326334323930363239343765
+37383630613630653939663462366538386161663833646138643734313332376434613366336239
+36666363386464393663396263353862383932333962393362393638376564366330333538633733
+33666363306634356334343230656231363534383734326331636165653164633232653935353731
+31343633396236363936613138363266656562306364323738666539326563396639616364623538
+66343336616165626436333134373336613463346334336432383331656535366439323332313765
+33656231653939373362653062353438333232343266653566646361343132616234656661336432
+36626137653330386633316332383036393834643461363563343831326266636462306639613232
+62393931363431613738356630663636613139326465333666643533373739663763653266363537
+36613333383035333933353038633437633435333061303463323161366634376261396463313961
+62613536326665366534363761346231656566396332373866356138653731663762633733303831
+65336561636333336533633036356638623039376261306632653038383138646164666635633130
+33376161366364303138666139326164303966666636343436373633306134396663616231656638
+62656163343264383939393964633332616162653861623334313865316331613733356133396164
+38626438623430656538316161616538306636393762303966363534643661353037666561636362
+36386466353632646638643831313665613862343431633561383837363433643630643136646234
+63663538643465663536333265306139313839653338373134306562646537313135666437373364
+31623236663164323235323661363534373763326261646365323435376665356162326635313339
+64613731363039616166623930653839653865323036383331643864313137393136643631306262
+32623666396536356435333862616461616365646333636366323633656338393464333035616136
+66333737643037346630306366636338376133663964623165386136303863616134643163346565
+61376339343661343962653532383431653662313534383435306165623936656331646131333165
+30333233313261616261653439396464656132306137646535333639666463303464396530356435
+64363137343335343961313665623135636564343061396666343765373865313535346130653462
+32356638343862376335616232613964373535396230323738393334303435396264616236613763
+61343435646130326464306466623161303730393830336536623865643635616462666436633833
+65353936623335623431313863633138613566356134313966383635343731323039373566333030
+31643139376261373436333437333563303034636663633563373335313163316332643839306261
+39656330653334343231393937336666313539303863646638363539666634343538623432376635
+61643161396632356462363331316664346231393266653035646565643434376332383836643932
+39653933323065366330343039326565616539326336626539346466323136366431363734663731
+31613534323661376364386464356135633235353435353532316563356639376431316431356235
+61376266643334373561636336373535316166373538376165653637323661646233376439316465
+39323465356436326334616465306432353665616631623566313638363962313066353636393033
+62633133346438323735386563626564613938626363346561613138303537376330633066326237
+33666231396333616562323238326334383932393439363134326362653532623432396635343235
+62306338613664353336663933356436663430613935313437613332353363383435633434393935
+36316161326435323235623961393535366534346366346439316131623834633066393162393363
+39633265643536643962376130383038306139303633616665666166323038356232666566626665
+39363539366335626564653536366462303535383337646437383064363837303232326638336639
+36633031356134623864356435366434363763393036616236373437313735663964653136393561
+30333732656363306238646461303065383836373333663766333534623233623863346431353036
+65313661666236376631333832343138363735633035366435303636336131336435363463646332
+63316461333533336637656435643333663062333464616562613465376337353361356165376134
+62646561323866636265353865343931643237326439353738633832343837323466663731333834
+38333632376435666663363665323862656162626563623938303135393432323531373865656431
+61313737613064303033663633336161363366653735323461623734616663643766366632333761
+35363836643964666438336263623536643536333264653933613961666634613438646233373733
+65363035316631383733373934353830373365393034303032633062366466336334666266356365
+34376435336639386139633136663031333331356462323961373239636539326662653363333139
+32613037373630393464386437373338623833313638326136623564616333653436366635363633
+63373735333435343863636235656439613034333539633861643365383938613764633566303464
+31386132373635323264376436373637383364326361343838333034626462376432373539643137
+34313865306135636262666537373465633564613465626438656133313537656235653262373836
+30626264663332626161396439393636333965383763363739663239663861373530393233343630
+33363161343435663561343862336262333132613537316664663937653062316133363436646531
+33393736336434306132616130303131333335633166626634666266636436383939396634613664
+34386665393933353131333061323366306430666661316164326665363664323630366165376465
+36303365383130336631653166613365353264343461666232313964643236333761306131386364
+37666434653133393435356663323637333138373262633731333735663633353736623738336462
+36393965333336376664626238316335636463343165653235373334346462633863383266343336
+38393837303162313736356462323432666161663565386133643531383833666537316232616565
+62363439313230383162643336306466643836333032626337666133613032366636333162373536
+65383836363435616435343737316331363232333838366533313166656133663232353232313837
+32613838393463626632343836323966316131636433663865356366303331336231633864636262
+61656466356432323931393831393436333963396138333733303630313133353461346535363930
+61653637306636366261633032633935333966323164336436653564356631396430383135663738
+62666536663666346338626430663439376631623863643665366636393736316432653835663938
+65376132653661656235663364383630663262646138636438303933363830613231666261306666
+39613731633765313163386237313636663632333263623734646133316364313061386630333862
+34346662646139393434313432653236333134613430383939353136633462353830656264383862
+36613764313036663431666363333731656338336238643036323363373732373137396166333762
+32373835633261373338623031646562653664613232303865316631393562393631343265363734
+61666462313334623938613032306131616135633266323763636533656534373138333336366636
+31653831616437303637363364653330393336643865393438383834353636616130643834353330
+66613162393435613566613838353136343634353061316666383832303633303865633531333665
+66613032353939616639656463333137333234656263666233373532623463646466363662626630
+31653039383534656239333339613832613233363037306465643437376130316337653262353030
+31363761653932313061306663376661353138343735383337373634396131623233666264633365
+34343936313739616536613531343437613963613163366636386661643631343963346632386532
+31313338656236313432336662643835653935633063626432393963626436656463653231613536
+66383462313737363436376438666232383635353662356532653030383537636661323262323833
+32363761383035373330356137346663366364376237343535383231306538376139616235633463
+66343632636565653363356563323831623030656134303733313535656164646439653966636366
+30336530373733313163373030393930613030386531366565363439653738626262326533616264
+32643964376435333638663131663730306436353664643835643132663865376232363862366566
+37366130623933623761306437363135316339356635373565626132346338396436663931323662
+35613433613739656530333862623533326237616633626438626163373137306539643366613863
+63313230616434623065396630383363666433336538646637623961653138316235373432363164
+39623436636336316430323661313335633963613736623862623663383837636363653833623866
+30346332303338633538393035653939333562336262323865313931323534356137396337323263
+64313464313664313234393866666534633538383031323564356432666233633363643539613034
+37653436323438356135396239366530623333613034323762326366663437303961653038653566
+31306332333331306233363663376661373635376662393337666365616563653132633662626138
+32343863623433356161663966326633666539663361663562313834353736313831393039333037
+37343564666531313836656162363235326566653561303330626664613461613039643964313331
+34383536663938366330383030343836373263643034396634633338396333383237346531326339
+63656233323139646165346633376266346630343039393534363233656466336264616632396362
+61303830323536326630326236643231353838396662653737393261393030343834613236623864
+64626434303739626463313838333734653963626639636433366236373563663462646139623933
+34386663316230626662383266623230666565353365326565616635386366653664626134623561
+33326630383663626361633761336533346239393435346637386566613632633931393537623138
+38373235663833396164656432373936363434366564633032323335393162323962373939626537
+65636263393965363863623663353739386564353964353965653231346233666536663032383935
+64323262373062646436666337663239386262626237663132376531303139303433353762393730
+39336433396433353262363137663231633032366637303139376234363332353931616338383264
+31353966663961623832343237336630366632353765343632363032623663393061306532663639
+61306231323236306436323435666534646633353739376138376335613333353638396139623936
+32303837633539626264383163613361313239383066333562363636663939303166333665366638
+62376230373635323932383265623838343762303734363235383233356465346430633338336134
+35303064376239663162353738353763323734653539346439346435646561306635633039346562
+37336631313561323533376563356234653465313235313734633530303234393131356261336338
+31666666306266323332643462326266616663386464386132333435326561646531313937626439
+65663562326639623133383030303032353038613436623765323436383337323165376139396130
+39663430363330663834306132616231646438643038656332313234323831383235323933303635
+63373064353434393366393139626431393838643239383730373365656235623039613530626134
+34613764363834373066646262363031633630376331363435363137323834313063656135376164
+33393433383937383762313331613934323031623339646631623430376162353734663933323830
+31396130373938613236373737313931336332326333333039306330343033343164303438663464
+36663233383263306664313837313037323033633430623037333536653065346264373132356261
+39373032663636323439623062616330373135383965363366623630376136376232396136353032
+37303363653535323835666561326463393934363831616133646130663933626333323236636437
+62666236633039633737633531373534343535646666353835663237636230346365353862333065
+39636234346665303864623439663136373937303136363339376137653566646566366538653262
+39316363623966626232303765363737343835303332393633313263333836636239356432343330
+38303038616135616531366264663634326465613164626531613361303839386233623861363738
+39306637303738323231653231363335363535396664646662396366643764376266373331633262
+35313366633033363731303839343766306335333831316334326334396430356431613536343835
+31616535313337396566333930316537376432396439626563616264613037383833383437636439
+32366236383637323231313130616333303164393064353239373664303636343266363039613530
+33343632323263653834656562613231313734313234393232313665383831366339633435646564
+32653863386439316435356164326138643732396635396235663762653362616665356632366237
+30643039393939633061643063366532386366623038373064393538643565653339666536303232
+33343462346532313937633236356532386634383561373335666535383035316261353263643639
+31303061363239383131313639323830653732393635623339303336363231353734313262313331
+39343366353137373034323933376566383165653234356461623561316264666130303566363837
+39663462363863643164663362383632343833356639396465343262303733306337366236333861
+31373933643036653961333235643065363064356365616231303739313762326536396434303738
+31326666316537396566316161343964346364633239653937663635373133356164376634363635
+34646634623963393335396239633661356132336433386163653361336366646538636661633765
+32323432623738306335396234633563313666636638316637313639636261333331373933316461
+32393339613138363765333166313935623131623164643933323935366439306338653663326238
+61353661623462643630313238623432653338393663303763613366396238396437326337363833
+32626133356439373865373038653934303933363430613163613031646537326236623539646339
+61633530303236306132306238366635363134353837323966343462373263356165383836623664
+39323234346538653261623038313535636431393262376130383863353866303263306138613565
+31376661613436356665653335623266373461336433316235356261313633663737363961626634
+64376637643165333666626561343137306562323935666632653439376664383461626331633162
+37636363353864356564363739366334373633663036613962323030333133626131616363316630
+32303135623934356231333036313163353666383731363337343061383563616164373339666131
+65386530316639376263396438643233613430313964373563343363306338313036306437613930
+35396334306263303739666232366261343333613536333634636631396636383838386431323436
+31643036643332353563303037633964343832326164353236323939343763363134313262623165
+39383030383261626133373062346332306634396137383638343339646130646362663735396238
+39376633363666346435343766626632303463666661303637343831393864626234326364386635
+38366539313331313463643237626239306666356465663131376361653830306239383933353364
+36663435306338633933636161343533336130633065313761353733323165326437343332663962
+38653631313538613334326234386434376561643433356336303837656236323335393235313435
+63323536333461666161626434663630646333363634346133393161386237653831333336653137
+39643137663731326630343962373837353665383832396164303037393634626436363238333637
+31623866333161633934633932363563396262613238653765363038383765626430353866343036
+63363335326462346266653134343031333463663332326134373234393362323161393937333939
+37333263303262626463336637363363306264663532646533303738393335643431623438383535
+37643632353661323063616166623739343333663061326566303531313362393333353262323438
+36656663653433373937613539663738313831653433633636626132326633353561663234333565
+39393735356561636438336165353438623231373333383432323933663063616336313533356435
+38383765636339666330333866373264326436663136356532363435653465336130313730383735
+38343039653730343632373430373437356163343761353535353037373033343132313630616265
+66373338343366323937616162333937326131646630613137316162333361633964356364376362
+61356665326264653036613832326663366566656231646338323730613439313036353136653338
+32653664623232306265643238353834303336383034376533633361323538316236306565646466
+37383638613337636566626131353363306133616336623832303337633366386361306132663464
+65636566393431326433306262663932633065303563303136303338663966633466373861656564
+31396336383635393464326531613631396230633261623636303563346332343065353438353537
+37316666623364386137356638386635323861613331643835643639353332656662363163306433
+34373134626466336566633162653761333736303565323430313736613439396634316430336261
+36313839313137343732656461633766316432613661346631613834346263393535383262653966
+65656366376436396264303830353130363533303263626537386530643166323666326534316634
+30353463666334336338633062353739643434343438336138363435633161613037323738346563
+39653130646462313331393061366332626263666266623261366137363337626530613136333539
+66343639666461623230653936396230613137666264373036613334646136323963323039313231
+39353131363235396234376537346539663235373862646263646463623033383837383834626661
+31386236313762303732343139663763616265393034306638326431373736613837343636316437
+64386139343239646337343263393933613734623239623633666332646463366261316232383633
+38363964313563616331306235373363653162393830326639366434666463336336656635353461
+64623537646633393536663739653439623564353064383334323166616435363532663362613532
+62643431653764323739343631656264363862323630633539366464366165626464373337343937
+32323938376461643165383630313832636530653562366232373661316132343237633364326437
+64353466373232363966666631663137643563396564623033366133393733663538623834346361
+39373238653434313335343263616565353939666536393865303734663464333535386161376432
+36623333383164393535386232373263393032376234656639613231356230663339613236346434
+39303161303531656332623630336562346164613834663430646432386236346364646337363365
+64316666353762323666646461353837303963623465333063326362313834616365313335353233
+33326464623435306231653263666261643335326262323261373030303133613036383834346634
+33383664373932366534663034323366653566613366636535326435363336303765383261393334
+35646366653838323832303434343933666662633134396136356432316136346461633539363636
+31326435396366373565353730623834383437343139316266626664373064653664316639623031
+32633362643966626166373937616561363366306535353762353463373733303939623462323134
+63663936643566303864663465633066323463396233396266643963383262343732373231366635
+39623138313430666536313031656631626431343034336438666464343037666133366364663437
+62616334383730323937386530366564353136313464323631363730313930383131333263383039
+66633737623738633233643838373934363030343065613362626634633565373565356433346665
+37306333666233633833653135313734313638646461316439303461633832663835326330616534
+64653635366266323532646462626438633536643662646631396363376263386433653666643036
+66323163623164343232376561343239333037316465666662666233366162383839656665393135
+37373230333762326362306132623433646361636135303862663636313033373765333037663363
+63316135313338346635303038613236326232306261643032323730613065356539646163633833
+35323961303461393535633632633233366538333261666237383438313365383063363361653736
+32306438663263323737643464663966373933643433353638396533323564633739633165643665
+64633233353166656466383637626462643463343462333332616631613364346334306435386164
+35666632396663306166386364346661353764373435616332663030393535623064356135353061
+37313638633530366339353362313434373731303331363164623737396438623435633635653537
+66383831353731363061306636623565353037313764613130636565653236376335613864363862
+62346166613734663131613663633234396532626438643035326333363166616634323432316334
+39356362363161343564653765393339333930343433343861633633633032363436366533373461
+64343036336664303834366165376166306137343732343665303765366465383834316263386561
+63626234393462336132383461343732393665343262323732303135326130656561353238376634
+34363534373366323633376262323036626537323939633561333836323736323032653862383963
+34383564376237656638653561393862366264613034623265323163343265333762363834333234
+64363965626363663265363062386137616263636461306466663663353231306532303064636538
+38303730393931386261333634303534613865343231363338333836373636373737356265336364
+31383033396532386335383265373735643765616136633964343266663431366133636662663235
+39336138613063643766613037333864383766306565373265396133356635343066393462313963
+31616436663366383134343236613265346363646137663732376234313135393864333762383934
+34623139306433333535313365356537643264386561343134383738666163643262643232333465
+33323662363032386235353631333238333265323161646438643732303562653435386133303438
+32383434356531393566343839663165396131646132383033663431363230376330623463636439
+38633966396162663838333632323063393762346530306266663166346635343166386238313137
+31366262626232333431323437616466626538386666623333643566356665393238366161376163
+63663338303065633238366661633666333839646231633038623636646265396566333630396362
+38653265313637316438653365306634663436613233366134656261376630396163626530386131
+66323934643637313230663139366363373839343533663337323065373238343761333563356131
+34303061626239643366393632303161323762656364653532323136303936316364626538626130
+62373331336261366636623034613836326637343838633135363138343965383838626362383962
+61303032323035383866333130333238613139643333393961376564366266353235643135336363
+38363663656433336463633437666262316237653637306331663563666438323361356433313238
+61336437643666396535323566643565323039303738653632326530303261653332356537383563
+33303232343236343362313161663363636662346265313639383265393664616335313435353439
+33393432663137353339613035633833626534613130323236323764393062303836656162346337
+61316264656234366262613738363730636336333862306532313730616635656536646463343363
+61333539373564303634363136323236306639383833656339646236623062623234366463336261
+61386434313065633466626339353466666437326536313633646333363833623339353930633065
+36396662646231333132316435333964383339313635316139343963633133343036333336343063
+64363661383633353938396539373332376236633964386133366362333161363461313739306631
+65353138663433616664303533643635326564353737353133653838636464306265316533383232
+62323862613666633562363936616362383163376438353963653930613961616666646263303939
+32363630396164326564613263396530356437343836336630616437363466396339363330313731
+62663034373733366337303838633762383430356564366333643364643165623761376237353834
+65343466353662363737376266333564373839613663656636376161613734323066306331646561
+65393365323537623963656663623766386130613262373639386265376136386465363634663938
+34666336633263663864326261376334613734623764343563316539653066356166356432633435
+61323164316361386630653636653337393866613462666637336630323161343139376261313164
+63363137363963383961623633623835346266623832643363386330323134653864386338303238
+66393135663662353238386136656632343933616263306266356434666435646165363063626431
+61633534623734636331333637323332396563303763303239313236623831343162646638303865
+61633765323135386564646132383732613937396534656333393961383563336337623163633538
+38633262643237366363636130353339356636363835396263343765663238303361383832636435
+31383833633134376561616663616361636263623366383365353238366336356233623233616531
+66326339353439343764326566393035396162616162353233653835393534666362643532656265
+36313038386135303364366165313636383537613736316162313965326638353236363338373061
+64373061646439623436626430326661636338343639623935356636633936656430656461633432
+65323635353030636466313035393866303032333339373262653933353930303463383132626234
+38343766356234333939393731663162346430343766636665393862373030646636346631363062
+36636165666135343762383436356363353134363731393566653365663466663966653665363864
+39643865373534623331636333663466336131633461616162623561633534303963316263633836
+30323639653439386335613935626131376133656265376365316433346336353636313664616263
+36663637303330316532626564633530383236346336336335356636653231656432336239363638
+66386163383539663032626434393264353330353332363939383032323165636236373231363437
+31613833313336636664353561366131613231353464343737373039393465356631343062643338
+31616533343066393466623036623230346538323638333038663164306465636439303864363565
+33313064616431363636373039393433383433396161636336336232396130366339313132393164
+39636534336164316663643364303165633732303131316664363139616339653263663161326366
+66663236613438643666663334303366653631383639646362633564646334353637386236633737
+38346439393564383564636164366630353462346635346230643135636134653432343861303764
+30396634653037373162373463323862333364323465376464343436343533626231656338303733
+30623864363234653631313033623937643133616137386633623361376631613038613837376462
+37663065633732393236666433323132343636353935653062303637656165356639653735383639
+61613933356335306165616531643135373831316362323138653532653633626362306365323636
+33306236636433313930636162343462303663663366643766336436383464613531336136663363
+32353330613733646531363336336565316461656631636636626666616432346534376465373861
+38363031653031366563363664663334396163656662303965333033626366363531306134323635
+30623662633331623939
diff --git a/.automation/test/ansible/ghe-initialize/handlers/main.yml b/.automation/test/ansible/ghe-initialize/handlers/main.yml
new file mode 100644
index 00000000..8556b297
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/handlers/main.yml
@@ -0,0 +1,14 @@
+---
+################################
+################################
+## GitHub Enterprise Handlers ##
+################################
+################################
+
+####################
+# GHE config apply #
+####################
+- name: ghe config apply
+ command: ghe-config-apply
+ poll: 0
+ async: 300
diff --git a/.automation/test/ansible/ghe-initialize/tasks/collectd-settings.yml b/.automation/test/ansible/ghe-initialize/tasks/collectd-settings.yml
new file mode 100644
index 00000000..f6f08485
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/tasks/collectd-settings.yml
@@ -0,0 +1,90 @@
+---
+- block:
+ ###############################
+ # Wait for admin port to open #
+ ###############################
+ - name: Wait for Admin port to come up (Port 8443)
+ ## Doc: http://docs.ansible.com/ansible/latest/modules/wait_for_module.html
+ ## Helpful Google: ansible wait_for
+ wait_for:
+ host: "{{ ansible_host }}"
+ port: 8443
+ delay: 5
+ timeout: 300
+ state: started
+ changed_when: false
+
+ #################################
+ # Wait for successful open port #
+ #################################
+ - name: Wait for http status 200
+ changed_when: false
+ uri:
+ url: "https://{{ ansible_host }}:8443"
+ validate_certs: "no"
+ register: http_result
+ # ignore_errors: true
+ until: http_result.status == 200
+ retries: 100
+ delay: 3
+
+ #######################################################
+ # Copy License file to GHE to decrypt file and upload #
+ #######################################################
+ # Copy of the file will allow for Ansible Vault to decrypt the file
+ # and place it on the new remote machine
+ - name: Copy collectd-settings.json File to GHE
+ become: true
+ template:
+ src: "collectd-settings.json.j2"
+ dest: /tmp/collectd-settings.json
+ owner: admin
+ group: admin
+ mode: 0644
+
+ #########################################################
+ # Set up Admin password, License, and Initial Setttings #
+ #########################################################
+ - name: Setup Grafana
+ # yamllint disable
+ shell: curl --fail -Lk \
+ -X PUT "https://api_key:{{ github_admin_password }}@{{ ansible_host }}:8443/setup/api/settings" \
+ --data-urlencode "settings=`cat /tmp/collectd-settings.json`"
+ # yamllint enable
+ retries: 10
+ delay: 5
+ register: http_collectd_config_result
+ until: http_collectd_config_result.rc == 0
+ notify: ghe config apply
+
+
+ #####################################
+ # Edit forwarding.conf with metrics #
+ #####################################
+ - name: Copy forwarding.conf File to GHE
+ become: true
+ template:
+ force: true
+ src: "forwarding.conf.j2"
+ dest: /etc/collectd/conf.d/forwarding.conf
+ owner: root
+ group: root
+ mode: 0644
+
+ ###########################################
+ # Restart Collectd service to take effect #
+ ###########################################
+ - name: Restart Collectd service
+ become: true
+ service:
+ name: collectd
+ state: restarted
+
+ ######################
+ # Set the tags block #
+ ######################
+ tags:
+ - metrics
+ - github
+ - ghe_primary
+ - initialize
diff --git a/.automation/test/ansible/ghe-initialize/tasks/ghe-api-config-apply.yml b/.automation/test/ansible/ghe-initialize/tasks/ghe-api-config-apply.yml
new file mode 100644
index 00000000..64e4be65
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/tasks/ghe-api-config-apply.yml
@@ -0,0 +1,68 @@
+---
+- block:
+ # ##################################
+ # # Run config to take in settings #
+ # ##################################
+ # - name: Run ghe-config-apply for Settings to Take Effect
+ # shell: "nohup ghe-config-apply /dev/null 2>&1 &"
+ # async: 45
+ # poll: 0
+ # args:
+ # executable: "/bin/bash"
+
+ ##################################
+ # Run config to take in settings #
+ ##################################
+ - name: Run Configure for Settings to Take Effect
+ uri:
+ url: "https://{{ ansible_host }}:8443/setup/api/configure"
+ method: POST
+ return_content: "yes"
+ user: "api_key"
+ password: "{{ github_admin_password }}"
+ force_basic_auth: "yes"
+ validate_certs: "no"
+ status_code: 202
+
+ #################################################################
+ # Wait for 'ghe-config-apply' to be completed before continuing #
+ #################################################################
+ - name: Ensure ghe-config-apply is completed
+ # https://docs.ansible.com/ansible/uri_module.html
+ # yamllint disable-line
+ # https://developer.github.com/enterprise/v3/enterprise-admin/management_console/#check-configuration-status
+ uri:
+ url: "https://{{ ansible_host }}:8443/setup/api/configcheck"
+ method: GET
+ return_content: "yes"
+ user: "api_key"
+ password: "{{ github_admin_password }}"
+ force_basic_auth: "yes"
+ validate_certs: "no"
+ register: configcheck
+ until: configcheck.status == 200 and configcheck.json.status == "success"
+ retries: 100
+ delay: 10
+
+ #####################################
+ # Remove the files from the machine #
+ #####################################
+ # Need to remove the license file and settings
+ # files that were copied to the ghe server
+ - name: Remove temp Files from GHE
+ become: true
+ file:
+ path: "{{ item }}"
+ state: absent
+ with_items:
+ - "/tmp/ghe-license.ghl"
+ - "/tmp/settings.json"
+ - "/tmp/ldap-settings.json"
+
+ ######################
+ # Set the tags block #
+ ######################
+ tags:
+ - github
+ - ghe_primary
+ - initialize
diff --git a/.automation/test/ansible/ghe-initialize/tasks/ghe-config-apply.yml b/.automation/test/ansible/ghe-initialize/tasks/ghe-config-apply.yml
new file mode 100644
index 00000000..9c8fabca
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/tasks/ghe-config-apply.yml
@@ -0,0 +1,32 @@
+---
+- block:
+ ########################################
+ # Copy the script to the local machine #
+ ########################################
+ - name: Copy the script to the GHE instance
+ become: true
+ template:
+ force: 'yes'
+ src: "ghe-config-apply.sh"
+ dest: /tmp/ghe-config-apply.sh
+ owner: admin
+ group: admin
+ mode: 0755
+
+ ##################################
+ # Run config to take in settings #
+ ##################################
+ - name: Run ghe-config-apply for Settings to Take Effect
+ shell: "nohup ./tmp/ghe-config-apply.sh /dev/null 2>&1 &"
+ async: 300
+ poll: 0
+ args:
+ executable: "/bin/bash"
+
+ ######################
+ # Set the tags block #
+ ######################
+ tags:
+ - github
+ - ghe_primary
+ - initialize
diff --git a/.automation/test/ansible/ghe-initialize/tasks/ghe-initial-configuration.yml b/.automation/test/ansible/ghe-initialize/tasks/ghe-initial-configuration.yml
new file mode 100644
index 00000000..d078873e
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/tasks/ghe-initial-configuration.yml
@@ -0,0 +1,87 @@
+---
+- block:
+ ###############################
+ # Wait for admin port to open #
+ ###############################
+ - name: Wait for Admin port to come up (Port 8443)
+ # yamllint disable-line
+ ## Documentation: http://docs.ansible.com/ansible/latest/modules/wait_for_module.html
+ ## Helpful Google: ansible wait_for
+ wait_for:
+ host: "{{ ansible_host }}"
+ port: 8443
+ delay: 5
+ timeout: 300
+ state: started
+ changed_when: false
+
+ #################################
+ # Wait for successful open port #
+ #################################
+ - name: Wait for http status 200
+ changed_when: false
+ uri:
+ url: "https://{{ ansible_host }}:8443"
+ validate_certs: "no"
+ register: http_result
+ # ignore_errors: true
+ until: http_result.status == 200
+ retries: 100
+ delay: 3
+
+ #######################################################
+ # Copy License file to GHE to decrypt file and upload #
+ #######################################################
+ # Copy of the file will allow for Ansible Vault to decrypt the file
+ # and place it on the new remote machine
+ - name: Copy License File to GHE
+ become: true
+ copy:
+ src: "{{ role_path }}/files/ghe-license.ghl"
+ dest: /tmp/ghe-license.ghl
+ owner: admin
+ group: admin
+ mode: 0600
+
+ #######################################################
+ # Copy License file to GHE to decrypt file and upload #
+ #######################################################
+ # Copy of the file will allow for Ansible Vault to decrypt the file
+ # and place it on the new remote machine
+ - name: Copy settings.json File to GHE
+ become: true
+ template:
+ src: "settings.json.j2"
+ dest: /tmp/settings.json
+ owner: admin
+ group: admin
+ mode: 0644
+
+ #########################################################
+ # Set up Admin password, License, and Initial Setttings #
+ #########################################################
+ - name: Setup License, Admin Password, and Initial Setttings
+ command: curl --fail -Lk \
+ -X POST "https://{{ ansible_host }}:8443/setup/api/start" \
+ -F license=@/tmp/ghe-license.ghl \
+ -F "password={{ github_admin_password }}" \
+ -F "settings=
+
+ ResolveInterval "300"
+
+
+
+
diff --git a/.automation/test/ansible/ghe-initialize/templates/ghe-config-apply.sh b/.automation/test/ansible/ghe-initialize/templates/ghe-config-apply.sh
new file mode 100644
index 00000000..06e2e712
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/templates/ghe-config-apply.sh
@@ -0,0 +1,211 @@
+#!/bin/bash
+
+################################################################################
+# Script to run ghe-config-apply on the primary GHES instance
+# and wait for any previous runs to complete
+################################################################################
+
+###########
+# Globals #
+###########
+GHE_CONFIG_PID='/var/run/ghe-config.pid' # PID file when a config is running
+GHE_APPLY_COMMAND='ghe-config-apply' # Command running when a config run
+SLEEP_SECONDS=20 # Seconds to sleep before next check
+PID_CHECK_LIMIT=15 # How many times to check the pid before moving on
+PID_CHECK=0 # Count of times to check the pid
+PROCESS_CHECK_LIMIT=15 # How many times to check the process before moving on
+PROCESS_CHECK=0 # Count of times to check the process
+
+################################################################################
+########################### SUB ROUTINES BELOW #################################
+################################################################################
+################################################################################
+#### Function CheckGHEPid ######################################################
+CheckGHEPid()
+{
+ ##################################
+ # Check to prevent infinite loop #
+ ##################################
+ if [ $PID_CHECK -gt $PID_CHECK_LIMIT ]; then
+ # Over the limit, move on
+ echo "We have checked the pid $PID_CHECK times, moving on..."
+ else
+ ################################################
+ # Check to see if the PID is alive and running #
+ ################################################
+ if [ ! -f "$GHE_CONFIG_PID" ]; then
+ # File not found
+ echo "Were good to move forward, no .pid file found at:[$GHE_CONFIG_PID]"
+ else
+ # Found the pid running, need to sleep
+ echo "Current PID found, sleeping $SLEEP_SECONDS seconds before next check..."
+ ################
+ # Sleep it off #
+ ################
+ SLEEP_CMD=$(sleep $SLEEP_SECONDS 2>&1)
+
+ #######################
+ # Load the error code #
+ #######################
+ ERROR_CODE=$?
+
+ ##############################
+ # Check the shell for errors #
+ ##############################
+ if [ $ERROR_CODE -ne 0 ]; then
+ echo "ERROR! Failed to sleep!"
+ echo "ERROR:[$SLEEP_CMD]"
+ echo "Will try to call apply as last effort..."
+ ####################################
+ # Call config apply as last effort #
+ ####################################
+ RunConfigApply
+ else
+ #####################
+ # Increment counter #
+ #####################
+ ((PID_CHECK++))
+ ##################################
+ # Try to check for the pid again #
+ ##################################
+ CheckGHEPid
+ fi
+ fi
+ fi
+}
+################################################################################
+#### Function CheckGHEProcess ##################################################
+CheckGHEProcess()
+{
+ ##################################
+ # Check to prevent infinite loop #
+ ##################################
+ if [ $PROCESS_CHECK -gt $PROCESS_CHECK_LIMIT ]; then
+ # Over the limit, move on
+ echo "We have checked the process $PROCESS_CHECK times, moving on..."
+ else
+ ####################################################
+ # Check to see if the process is alive and running #
+ ####################################################
+ # shellcheck disable=SC2009
+ CHECK_PROCESS_CMD=$(ps -aef |grep "$GHE_APPLY_COMMAND" |grep -v grep 2>&1)
+
+ #######################
+ # Load the error code #
+ #######################
+ ERROR_CODE=$?
+
+ ##############################
+ # Check the shell for errors #
+ ##############################
+ if [ $ERROR_CODE -ne 0 ]; then
+ # No process running on the system
+ echo "Were good to move forward, no process like:[$GHE_APPLY_COMMAND] running currently on the system"
+ else
+ # Found the process running, need to sleep
+ echo "Current process alive:[$CHECK_PROCESS_CMD], sleeping $SLEEP_SECONDS seconds before next check..."
+ ################
+ # Sleep it off #
+ ################
+ SLEEP_CMD=$(sleep $SLEEP_SECONDS 2>&1)
+
+ #######################
+ # Load the error code #
+ #######################
+ ERROR_CODE=$?
+
+ ##############################
+ # Check the shell for errors #
+ ##############################
+ if [ $ERROR_CODE -ne 0 ]; then
+ echo "ERROR! Failed to sleep!"
+ echo "ERROR:[$SLEEP_CMD]"
+ echo "Will try to call apply as last effort..."
+ ####################################
+ # Call config apply as last effort #
+ ####################################
+ RunConfigApply
+ else
+ #####################
+ # Increment counter #
+ #####################
+ ((PROCESS_CHECK++))
+ ######################################
+ # Try to check for the process again #
+ ######################################
+ CheckGHEProcess
+ fi
+ fi
+ fi
+}
+################################################################################
+#### Function RunConfigApply ###################################################
+RunConfigApply()
+{
+ ##########
+ # Header #
+ ##########
+ echo "Running $GHE_APPLY_COMMAND to the server..."
+
+ ##############################################
+ # Run the command to apply changes to server #
+ ##############################################
+ APPLY_CMD=$(ghe-config-apply 2>&1)
+
+ #######################
+ # Load the error code #
+ #######################
+ ERROR_CODE=$?
+
+ ##############################
+ # Check the shell for errors #
+ ##############################
+ if [ $ERROR_CODE -ne 0 ]; then
+ # Errors
+ echo "ERROR! Failed to run config apply command!"
+ echo "ERROR:[$APPLY_CMD]"
+ exit 1
+ else
+ # Success
+ echo "Successfully ran $GHE_APPLY_COMMAND"
+ fi
+}
+################################################################################
+################################## MAIN ########################################
+################################################################################
+
+######################
+# Check for pid file #
+######################
+CheckGHEPid
+
+#############################
+# Check for running process #
+#############################
+CheckGHEProcess
+
+####################
+# Run config apply #
+####################
+RunConfigApply
+
+##########################################
+# Were going to run it again after a nap #
+# to make sure there is no crazy actions #
+##########################################
+sleep 300s
+
+######################
+# Check for pid file #
+######################
+CheckGHEPid
+
+#############################
+# Check for running process #
+#############################
+CheckGHEProcess
+
+####################
+# Run config apply #
+####################
+RunConfigApply
diff --git a/.automation/test/ansible/ghe-initialize/templates/ldap-settings.json.j2 b/.automation/test/ansible/ghe-initialize/templates/ldap-settings.json.j2
new file mode 100644
index 00000000..4b692f95
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/templates/ldap-settings.json.j2
@@ -0,0 +1,35 @@
+{
+ "auth_mode": "ldap",
+ "ldap": {
+ "host": "{{ ldap_host }}",
+ "port": {{ ldap_port }},
+ "base": [
+ "{{ ldap_base_dn }}"
+ ],
+ "uid": null,
+ "bind_dn": "{{ ldap_bind_dn }}",
+ "password": "{{ ldap_password }}",
+ "method": "{{ ldap_method }}",
+ "search_strategy": "detect",
+ "user_groups": [],
+ "admin_group": "{{ ldap_admin_group }}",
+ "virtual_attribute_enabled": false,
+ "recursive_group_search": false,
+ "posix_support": true,
+ "user_sync_emails": {{ ldap_user_sync_emails }},
+ "user_sync_keys": {{ ldap_user_sync_keys }},
+ "user_sync_gpg_keys": {{ ldap_user_sync_gpg_keys }},
+ "user_sync_interval": {{ ldap_user_sync_interval }},
+ "team_sync_interval": {{ ldap_team_sync_interval }},
+ "sync_enabled": {{ ldap_sync_enabled }},
+ "external_auth_token_required": false,
+ "verify_certificate": false,
+ "reconciliation.user": null,
+ "reconciliation.org": null,
+ "profile.uid": "{{ ldap_profile_uid }}",
+ "profile.name": "{{ ldap_profile_name }}",
+ "profile.mail": "{{ ldap_profile_mail }}",
+ "profile.key": {{ ldap_profile_key }},
+ "profile.gpg_key": {{ ldap_profile_gpg_key }}
+ }
+}
diff --git a/.automation/test/ansible/ghe-initialize/templates/settings.json.j2 b/.automation/test/ansible/ghe-initialize/templates/settings.json.j2
new file mode 100644
index 00000000..a7878e41
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/templates/settings.json.j2
@@ -0,0 +1,112 @@
+{
+ "enterprise": {
+ "private_mode": {{ core_private_mode }},
+ "public_pages": {{ core_public_pages }},
+ "subdomain_isolation": {{ core_subdomain_isolation }},
+ "signup_enabled": {{ core_signup_enabled }},
+ "identicons_host": "dotcom",
+ "http_proxy": {{ core_http_proxy }},
+ "http_noproxy": {{ core_http_noproxy }},
+ "auth_mode": "default",
+ "builtin_auth_fallback": {{ core_builtin_auth_fallback }},
+ "expire_sessions": {{ core_expire_sessions }},
+ "avatar": null
+ },
+ "cas": {
+ "url": {{ cas_url }}
+ },
+ "saml": {
+ "sso_url": {{ saml_sso_url }},
+ "certificate": {{ saml_certificate }},
+ "certificate_path": "{{ saml_certificate_path }}",
+ "issuer": {{ saml_issuer }},
+ "name_id_format": "{{ saml_name_id_format }}",
+ "idp_initiated_sso": {{ saml_idp_initiated_sso }},
+ "disable_admin_demote": {{ saml_disable_admin_demote }},
+ "signature_method": "{{ saml_signature_method }}",
+ "digest_method": "{{ saml_digest_method }}",
+ "username_attribute": {{ saml_username_attribute }},
+ "full_name_attribute": "{{ saml_full_name_attribute }}",
+ "emails_attribute": "{{ saml_emails_attribute }}",
+ "ssh_keys_attribute": "{{ saml_ssh_keys_attribute }}",
+ "gpg_keys_attribute": "{{ saml_gpg_keys_attribute }}"
+ },
+ "github_oauth": null,
+ "smtp": {
+ "enabled": {{ smtp_enabled }},
+ "address": {{ smtp_address }},
+ "authentication": {{ smtp_authentication }},
+ "port": {{ smtp_port }},
+ "domain": {{ smtp_domain }},
+ "username": {{ smtp_username }},
+ "user_name": {{ smtp_user_name }},
+ "password": {{ smtp_password }},
+ "support_address": "{{ smtp_support_address }}",
+ "support_address_type": "{{ smtp_support_address_type }}",
+ "noreply_address": "{{ smtp_noreply_address }}",
+ "discard_to_noreply_address": {{ smtp_discard_to_noreply_address }}
+ },
+ "ntp": {
+ "primary_server": "{{ ntp_primary_server }}",
+ "secondary_server": "{{ ntp_secondary_server }}"
+ },
+ "timezone": null,
+ "snmp": {
+ "enabled": {{ snmp_enabled }},
+ "version": {{ snmp_version }},
+ "community": "{{ snmp_community }}",
+ "users": [
+
+ ]
+ },
+ "syslog": {
+ "enabled": {{ syslog_enabled }},
+ "server": "{{ syslog_server }}",
+ "protocol_name": "{{ syslog_protocol_name }}",
+ "tls_enabled": {{ syslog_tls_enabled }},
+ "cert": {{ syslog_cert }}
+ },
+ "assets": null,
+ "pages": {
+ "enabled": {{ pages_enabled }}
+ },
+ "collectd": {
+ "enabled": {{ collectd_enabled }},
+ "server": "{{ collectd_server }}",
+ "port": {{ collectd_port }},
+ "encryption": {{ collectd_encryption }},
+ "username": {{ collectd_username }},
+ "password": {{ collectd_password }}
+ },
+ "mapping": {
+ "enabled": {{ mapping_enabled }},
+ "tileserver": {{ mapping_tileserver }},
+ "token": {{ mapping_token }}
+ },
+ "load_balancer": {
+ "http_forward": {{ loadbalancer_http_forward }},
+ "proxy_protocol": {{ loadbalancer_proxy_protocol }}
+ },
+ "abuse_rate_limiting": {
+ "enabled": {{ abuse_rate_limiting_enabled }},
+ "requests_per_minute": {{ abuse_rate_limiting_requests_per_minute }},
+ "cpu_millis_per_minute": {{ abuse_rate_limiting_cpu_millis_per_minute }},
+ "search_cpu_millis_per_minute": {{ abuse_rate_limiting_search_cpu_millis_per_minute }}
+ },
+ "api_rate_limiting": {
+ "enabled": {{ api_rate_limiting_enabled }},
+ "unauthenticated_rate_limit": {{ api_rate_limiting_unauthenticated_rate_limit }},
+ "default_rate_limit": {{ api_rate_limiting_default_rate_limit }},
+ "search_unauthenticated_rate_limit": {{ api_rate_limiting_search_unauthenticated_rate_limit }},
+ "search_default_rate_limit": {{ api_rate_limiting_search_default_rate_limit }},
+ "lfs_unauthenticated_rate_limit": {{ api_rate_limiting_lfs_unauthenticated_rate_limit }},
+ "lfs_default_rate_limit": {{ api_rate_limiting_lfs_default_rate_limit }},
+ "graphql_unauthenticated_rate_limit": {{ api_rate_limiting_graphql_unauthenticated_rate_limit }},
+ "graphql_default_rate_limit": {{ api_rate_limiting_graphql_default_rate_limit }}
+ },
+ "governor": {
+ "quotas_enabled": {{ governor_quotas_enabled }},
+ "limit_user": {{ governor_limit_user }},
+ "limit_network": {{ governor_limit_network }}
+ }
+ }
diff --git a/.automation/test/ansible/ghe-initialize/templates/splunk-settings.json.j2 b/.automation/test/ansible/ghe-initialize/templates/splunk-settings.json.j2
new file mode 100644
index 00000000..5c716889
--- /dev/null
+++ b/.automation/test/ansible/ghe-initialize/templates/splunk-settings.json.j2
@@ -0,0 +1,9 @@
+{
+ "syslog": {
+ "enabled": true,
+ "server": "{{ splunk_host }}:{{ splunk_port }}",
+ "protocol_name": "udp",
+ "tls_enabled": false,
+ "cert": null
+ }
+}
diff --git a/.automation/test/ansible/github-playbook.yml b/.automation/test/ansible/github-playbook.yml
new file mode 100644
index 00000000..08edef72
--- /dev/null
+++ b/.automation/test/ansible/github-playbook.yml
@@ -0,0 +1,42 @@
+---
+###########################################
+###########################################
+#### GitHub Services-Engineering Stack ####
+#### ####
+#### GHE Primary HA backup-utils ONLY ####
+###########################################
+###########################################
+
+###############################
+# Description of the playbook #
+###############################
+# description: Builds GHE Primary, HA, and backup-utils.
+# detailed_description: Builds GHE Primary, HA, and backup-utils.
+
+######################
+## Configure GitHub ##
+######################
+- hosts: github_primary
+ vars:
+ demo_github_initial_user: "{{ hostvars['localhost'].local_user }}"
+ github_host: "{{ hostvars['github_primary'].ansible_host }}"
+ probot_server_ip: "{{ hostvars['backup-utils'].ansible_host }}"
+ roles:
+ - role: ghe-initialize
+
+##########################################
+## Run ghe-config-apply for all changes ##
+##########################################
+# Due to us hot loading some data into GHE, the final
+# run of ghe-config-apply hangs and leaves the system in an odd state
+# The simplist option is to run the process
+# 1 more time at the end to solve the issue
+- hosts: github_primary
+ tasks:
+ - block:
+ - name: GHE-Config-Apply
+ include_role:
+ name: ghe-initialize
+ tasks_from: ghe-config-apply.yml
+ tags:
+ - github
diff --git a/.automation/test/coffeescript/coffeescript_bad_1.coffee b/.automation/test/coffeescript/coffeescript_bad_1.coffee
new file mode 100644
index 00000000..c307948e
--- /dev/null
+++ b/.automation/test/coffeescript/coffeescript_bad_1.coffee
@@ -0,0 +1,82 @@
+# Description
+# silly hubot scripts
+# These were created to blow off steam
+#
+# Commands:
+# `mona echo *` - repeats what you say
+#
+# Author:
+# admiralAwkbar@github.com
+
+###############################
+# Drop Hammer array of images #
+###############################
+dropHammer = [
+ "https://s1.yimg.com/uu/api/res/1.2/.kFQAfQ6KQmlf5ip8.UzNA--/dz0xMjMwO2g9NjkyO2FwcGlkPXl0YWNoeW9u/http://media.zenfs.com/en-US/video/video.snl.com/SNL_1554_08_Update_03_Harry_Caray.png",
+ "http://media.tumblr.com/d12ea80b3a86dfc5fe36d3f306254fe4/tumblr_inline_mq1r0tbBCb1qz4rgp.jpg",
+ "http://the-artifice.com/wp-content/uploads/2014/01/94309-160x160.png",
+ "http://25.media.tumblr.com/35826348f2215069835c1733c75b29aa/tumblr_muuxmmBaOI1rw3gqyo2_250.gif",
+ "http://data2.whicdn.com/images/78766805/large.jpg",
+ "http://filmfisher.com/wp-content/uploads/2014/11/hunt_for_red_october.jpg",
+ "http://cdn.meme.am/instances/500x/57495736.jpg",
+]
+
+###################
+# Thank you array #
+###################
+thanks = [
+ "You're welcome! Piece of cake...",
+ "It was nothing..."
+ "De nada...",
+ 'Danke...'
+ "Bitte...",
+ "Prego..."
+]
+
+#################################
+# Start the robot for listening #
+#################################
+module.exports = (robot) ->
+
+ ##############################
+ # Show the adapter connected #
+ ##############################
+ robot.respond /ADAPTER$/i, (msg) ->
+ msg.send robot.adapterName
+
+ ##########################
+ # Echo back the response #
+ ##########################
+ robot.respond /ECHO (.*)$/i, (msg) ->
+ msg.send msg.match[2]
+
+ ##################
+ # Whats going on #
+ ##################
+ robot.respond /whats going on/i, (msg) ->
+ msg.send "not much... robot stuff..."
+
+ ###################
+ # Drop the hammer #
+ ###################
+ robot.respond /drop the hammer/i, (msg) ->
+ msg.send "Commmencing the hammer dropping..."
+ msg.send msg.random dropHammer
+
+ ###############
+ # Vape Nation #
+ ###############
+ robot.respond /lets roll/i, (msg) ->
+ msg.send "First Class! Vape Nation!!! @beardofedu"
+
+ ##############
+ # Hubot Ping #
+ ##############
+ robot.respond /PING$/i, (msg) ->
+ msg.sned "PONG"
+
+#######################
+#######################
+## END OF THE SCRIPT ##
+#######################
+#######################
diff --git a/.automation/test/coffeescript/coffeescript_good_1.coffee b/.automation/test/coffeescript/coffeescript_good_1.coffee
new file mode 100644
index 00000000..40bc1264
--- /dev/null
+++ b/.automation/test/coffeescript/coffeescript_good_1.coffee
@@ -0,0 +1,84 @@
+# Description
+# silly hubot scripts
+# These were created to blow off steam
+#
+# Commands:
+# `mona echo *` - repeats what you say
+#
+# Author:
+# admiralAwkbar@github.com
+
+###############################
+# Drop Hammer array of images #
+###############################
+dropHammer = [
+ "https://s1.yimg.com/uu/api/res/1.2/.kFQAfQ6KQmlf5ip8.UzNA--/dz0xMjMwO2g9NjkyO2FwcGlkPXl0YWNoeW9u/http://media.zenfs.com/en-US/video/video.snl.com/SNL_1554_08_Update_03_Harry_Caray.png",
+ "http://media.tumblr.com/d12ea80b3a86dfc5fe36d3f306254fe4/tumblr_inline_mq1r0tbBCb1qz4rgp.jpg",
+ "http://the-artifice.com/wp-content/uploads/2014/01/94309-160x160.png",
+ "http://25.media.tumblr.com/35826348f2215069835c1733c75b29aa/tumblr_muuxmmBaOI1rw3gqyo2_250.gif",
+ "http://data2.whicdn.com/images/78766805/large.jpg",
+ "http://filmfisher.com/wp-content/uploads/2014/11/hunt_for_red_october.jpg",
+ "http://cdn.meme.am/instances/500x/57495736.jpg",
+]
+
+###################
+# Thank you array #
+###################
+thanks = [
+ "You're welcome! Piece of cake...",
+ "It was nothing..."
+ "De nada...",
+ "Danke...",
+ "Merci...",
+ "Bitte...",
+ "De rien..."
+ "Prego..."
+]
+
+#################################
+# Start the robot for listening #
+#################################
+module.exports = (robot) ->
+
+ ##############################
+ # Show the adapter connected #
+ ##############################
+ robot.respond /ADAPTER$/i, (msg) ->
+ msg.send robot.adapterName
+
+ ##########################
+ # Echo back the response #
+ ##########################
+ robot.respond /ECHO (.*)$/i, (msg) ->
+ msg.send msg.match[1]
+
+ ##################
+ # Whats going on #
+ ##################
+ robot.respond /whats going on/i, (msg) ->
+ msg.send "not much... robot stuff..."
+
+ ###################
+ # Drop the hammer #
+ ###################
+ robot.respond /drop the hammer/i, (msg) ->
+ msg.send "Commmencing the hammer dropping..."
+ msg.send msg.random dropHammer
+
+ ###############
+ # Vape Nation #
+ ###############
+ robot.respond /lets roll/i, (msg) ->
+ msg.send "First Class! Vape Nation!!! @beardofedu"
+
+ ##############
+ # Hubot Ping #
+ ##############
+ robot.respond /PING$/i, (msg) ->
+ msg.send "PONG"
+
+#######################
+#######################
+## END OF THE SCRIPT ##
+#######################
+#######################
diff --git a/.automation/test/docker/docker_bad_1.DOCKERFILE b/.automation/test/docker/docker_bad_1.DOCKERFILE
new file mode 100644
index 00000000..4c9c4c72
--- /dev/null
+++ b/.automation/test/docker/docker_bad_1.DOCKERFILE
@@ -0,0 +1,14 @@
+from node:latest
+
+# Create app directory
+run mkdir -p /usr/src/app
+WORKDIR /usr/src/app
+
+# Install app dependencies
+copy package.json /usr/src/app/ /here/there
+RUN sudo npm install
+
+ADD server.js server.js
+EXPOSE 1
+CMD ["node", "server.js"]
+ENtrypoint /tmp/here.sh
diff --git a/.automation/test/docker/docker_good_1.DOCKERFILE b/.automation/test/docker/docker_good_1.DOCKERFILE
new file mode 100644
index 00000000..07cdfd47
--- /dev/null
+++ b/.automation/test/docker/docker_good_1.DOCKERFILE
@@ -0,0 +1,13 @@
+FROM node:latest
+
+# Create app directory
+RUN mkdir -p /usr/src/app
+WORKDIR /usr/src/app
+
+# Install app dependencies
+COPY package.json /usr/src/app/
+RUN npm install
+
+ADD server.js server.js
+EXPOSE 3000
+CMD ["node", "server.js"]
diff --git a/.automation/test/javascript/javascript_bad_1.js b/.automation/test/javascript/javascript_bad_1.js
new file mode 100644
index 00000000..c2c104bb
--- /dev/null
+++ b/.automation/test/javascript/javascript_bad_1.js
@@ -0,0 +1,220 @@
+var http = require('http')
+var createHandler = require('github-webhook-handler')
+var handler = createHandler({ path: '/webhook', secret: (process.env.SECRET) })
+
+var userArray = ['user1']
+
+var teamDescription = 'Team of Robots'
+var teamPrivacy = 'closed' // closed (visibile) / secret (hidden) are options here
+
+var teamName = process.env.GHES_TEAM_NAME
+var teamAccess = 'pull' // pull,push,admin options here
+var teamId = ''
+
+var orgRepos = []
+
+// var creator = ""
+
+http.createServer(function (req, res) {
+ handler(req, res, function (err) {
+ console.log(err)
+ res.statusCode = 404
+ res.end('no such location')
+ })
+}).listen(3000)
+
+handler.on('error', function (err) {
+ console.error('Error:', err.message)
+})
+
+handler.on('repository', function (event) {
+ if (event.payload.action === 'created') {
+ const repo = event.payload.repository.full_name
+ console.log(repo)
+ const org = event.payload.repository.owner.login
+ getTeamID(org)
+ setTimeout(checkTeamIDVariable, 1000)
+ }
+})
+
+handler.on('team', function (event) {
+// TODO user events such as being removed from team or org
+ if (event.payload.action === 'deleted') {
+ // const name = event.payload.team.name
+ const org = event.payload.organization.login
+ getRepositories(org)
+ setTimeout(checkReposVariable, 5000)
+ } else if (event.payload.action === 'removed_from_repository') {
+ const org = event.payload.organization.login
+ getTeamID(org)
+ // const repo = event.payload.repository.full_name
+ setTimeout(checkTeamIDVariable, 1000)
+ }
+})
+
+function getTeamID (org) {
+ const https = require('https')
+
+ const options = {
+ hostname: (process.env.GHE_HOST),
+ port: 443
+ path: '/api/v3/orgs/' + org + '/teams',
+ method: 'GET',
+ headers: {
+ Authorization: 'token ' + (process.env.GHE_TOKEN),
+ 'Content-Type': 'application/json'
+ }
+ }
+ let body = []
+ const req = https.request(options, (res) => {
+ res.on('data', (chunk) => {
+ body.push(chunk)
+ }).on('end', () => {
+ body = JSON.parse(Buffer.concat(body))
+ body.forEach(item => {
+ if (item.name === teamName) {
+ teamId = item.id
+ }
+ })
+ })
+ })
+
+ req.on('error, (error) => {
+ console.error(error)
+ })
+
+ req.end()
+}
+
+function checkTeamIDVariable (repo) {
+ if (typeof teamId != 'undefined') {
+ addTeamToRepo(repo, teamId)
+ }
+}
+
+function checkReposVariable (org) {
+ if (typeof orgRepos !== 'undefined') {
+ // for(var repo of orgRepos) {
+ // addTeamToRepo(repo, teamId)
+ // }
+ reCreateTeam(org)
+ }
+}
+
+function addTeamToRepo (repo, teamId) {
+ const https = require('https')
+ const data = JSON.stringify({
+ permission: teamAccess
+ })
+
+ const options = {
+ hostname: (process.env.GHE_HOST),
+ port: 443,
+ path: '/api/v3/teams/' + teamId + '/repos/' + repo,
+ method: 'PUT',
+ headers: {
+ Authorization: 'token ' + (process.env.GHE_TOKEN),
+ 'Content-Type': 'application/json',
+ 'Content-Length': data.length
+ }
+ }
+ let body = []
+
+ const req = https.request(options, (res) => {
+ res.on('data', (chunk) => {
+
+ body.push(chunk)
+
+ }).on('end', () => {
+
+ body = Buffer.concat(body).toString()
+ console.log(res.statusCode)
+ console.log('added team to ' + repo)
+ })
+ })
+
+ req.on('error', (error) => {
+ console.error(error)
+ })
+
+ req.write(data)
+ req.end()
+}
+
+function reCreateTeam (org) {
+ const https = require('https')
+ const data = JSON.stringify({
+ name: teamName,
+ description: teamDescription,
+ privacy: teamPrivacy
+ maintainers: userArray,
+ repo_names: orgRepos
+ })
+
+ const options = {
+ hostname: (process.env.GHE_HOST),
+ port: 443
+ path: '/api/v3/orgs/' + org + '/teams',
+ method: 'POST',
+ headers: {
+ Authorization: 'token ' + (process.env.GHE_TOKEN),
+ 'Content-Type': 'application/json',
+ 'Content-Length': data.length
+ }
+ }
+ // const body = []
+ const req = https.request(options, (res) => {
+ if (res.statusCode !== 201) {
+ console.log('Status code: ' + res.statusCode)
+ console.log('Added ' + teamName + ' to ' + org + ' Failed')
+ res.on('data', function (chunk) {
+ console.log('BODY: ' + chunk)
+ })
+ } else {
+ console.log('Added ' + teamName ' to ' + org)
+ }
+ })
+
+ req.on('error', (error) => {
+ console.error(error)
+ })
+
+ req.write(data)
+ req.end()
+}
+
+function getRepositories (org) {
+ orgRepos = []
+
+ const https = require('https')
+
+ const options = {
+ hostname: (process.env.GHE_HOST),
+ port: '443',
+ path: '/api/v3/orgs/' + org + "/repos",
+ method: 'GET',
+ headers: {
+ Authorization: 'token ' + (process.env.GHE_TOKEN),
+ 'Content-Type': 'application/json'
+ }
+ }
+ let body = []
+ const req = https.request(options, (res) => {
+ res.on('data', (chunk) => {
+ body.push(chunk)
+
+ }).on('end', () => {
+ body = JSON.parse(Buffer.concat(body))
+ body.forEach(item => {
+ orgRepos.push(item.full_name)
+
+ console.log(item.full_name)
+ })
+ })
+ })
+
+ req.on('error', (error) => {
+ console.error(error)
+ })
+ req.end()
+}
diff --git a/.automation/test/javascript/javascript_good_1.js b/.automation/test/javascript/javascript_good_1.js
new file mode 100644
index 00000000..09417a6b
--- /dev/null
+++ b/.automation/test/javascript/javascript_good_1.js
@@ -0,0 +1,215 @@
+var http = require('http')
+var createHandler = require('github-webhook-handler')
+var handler = createHandler({ path: '/webhook', secret: (process.env.SECRET) })
+
+var userArray = ['user1']
+
+var teamDescription = 'Team of Robots'
+var teamPrivacy = 'closed' // closed (visibile) / secret (hidden) are options here
+
+var teamName = process.env.GHES_TEAM_NAME
+var teamAccess = 'pull' // pull,push,admin options here
+var teamId = ''
+
+var orgRepos = []
+
+// var creator = ""
+
+http.createServer(function (req, res) {
+ handler(req, res, function (err) {
+ console.log(err)
+ res.statusCode = 404
+ res.end('no such location')
+ })
+}).listen(3000)
+
+handler.on('error', function (err) {
+ console.error('Error:', err.message)
+})
+
+handler.on('repository', function (event) {
+ if (event.payload.action === 'created') {
+ const repo = event.payload.repository.full_name
+ console.log(repo)
+ const org = event.payload.repository.owner.login
+ getTeamID(org)
+ setTimeout(checkTeamIDVariable, 1000)
+ }
+})
+
+handler.on('team', function (event) {
+// TODO user events such as being removed from team or org
+ if (event.payload.action === 'deleted') {
+ // const name = event.payload.team.name
+ const org = event.payload.organization.login
+ getRepositories(org)
+ setTimeout(checkReposVariable, 5000)
+ } else if (event.payload.action === 'removed_from_repository') {
+ const org = event.payload.organization.login
+ getTeamID(org)
+ // const repo = event.payload.repository.full_name
+ setTimeout(checkTeamIDVariable, 1000)
+ }
+})
+
+function getTeamID (org) {
+ const https = require('https')
+
+ const options = {
+ hostname: (process.env.GHE_HOST),
+ port: 443,
+ path: '/api/v3/orgs/' + org + '/teams',
+ method: 'GET',
+ headers: {
+ Authorization: 'token ' + (process.env.GHE_TOKEN),
+ 'Content-Type': 'application/json'
+ }
+ }
+ let body = []
+ const req = https.request(options, (res) => {
+ res.on('data', (chunk) => {
+ body.push(chunk)
+ }).on('end', () => {
+ body = JSON.parse(Buffer.concat(body))
+ body.forEach(item => {
+ if (item.name === teamName) {
+ teamId = item.id
+ }
+ })
+ })
+ })
+
+ req.on('error', (error) => {
+ console.error(error)
+ })
+
+ req.end()
+}
+
+function checkTeamIDVariable (repo) {
+ if (typeof teamId !== 'undefined') {
+ addTeamToRepo(repo, teamId)
+ }
+}
+
+function checkReposVariable (org) {
+ if (typeof orgRepos !== 'undefined') {
+ // for(var repo of orgRepos) {
+ // addTeamToRepo(repo, teamId)
+ // }
+ reCreateTeam(org)
+ }
+}
+
+function addTeamToRepo (repo, teamId) {
+ const https = require('https')
+ const data = JSON.stringify({
+ permission: teamAccess
+ })
+
+ const options = {
+ hostname: (process.env.GHE_HOST),
+ port: 443,
+ path: '/api/v3/teams/' + teamId + '/repos/' + repo,
+ method: 'PUT',
+ headers: {
+ Authorization: 'token ' + (process.env.GHE_TOKEN),
+ 'Content-Type': 'application/json',
+ 'Content-Length': data.length
+ }
+ }
+ let body = []
+ const req = https.request(options, (res) => {
+ res.on('data', (chunk) => {
+ body.push(chunk)
+ }).on('end', () => {
+ body = Buffer.concat(body).toString()
+ console.log(res.statusCode)
+ console.log('added team to ' + repo)
+ })
+ })
+
+ req.on('error', (error) => {
+ console.error(error)
+ })
+
+ req.write(data)
+ req.end()
+}
+
+function reCreateTeam (org) {
+ const https = require('https')
+ const data = JSON.stringify({
+ name: teamName,
+ description: teamDescription,
+ privacy: teamPrivacy,
+ maintainers: userArray,
+ repo_names: orgRepos
+ })
+
+ const options = {
+ hostname: (process.env.GHE_HOST),
+ port: 443,
+ path: '/api/v3/orgs/' + org + '/teams',
+ method: 'POST',
+ headers: {
+ Authorization: 'token ' + (process.env.GHE_TOKEN),
+ 'Content-Type': 'application/json',
+ 'Content-Length': data.length
+ }
+ }
+ // const body = []
+ const req = https.request(options, (res) => {
+ if (res.statusCode !== 201) {
+ console.log('Status code: ' + res.statusCode)
+ console.log('Added ' + teamName + ' to ' + org + ' Failed')
+ res.on('data', function (chunk) {
+ console.log('BODY: ' + chunk)
+ })
+ } else {
+ console.log('Added ' + teamName + ' to ' + org)
+ }
+ })
+
+ req.on('error', (error) => {
+ console.error(error)
+ })
+
+ req.write(data)
+ req.end()
+}
+
+function getRepositories (org) {
+ orgRepos = []
+
+ const https = require('https')
+
+ const options = {
+ hostname: (process.env.GHE_HOST),
+ port: 443,
+ path: '/api/v3/orgs/' + org + '/repos',
+ method: 'GET',
+ headers: {
+ Authorization: 'token ' + (process.env.GHE_TOKEN),
+ 'Content-Type': 'application/json'
+ }
+ }
+ let body = []
+ const req = https.request(options, (res) => {
+ res.on('data', (chunk) => {
+ body.push(chunk)
+ }).on('end', () => {
+ body = JSON.parse(Buffer.concat(body))
+ body.forEach(item => {
+ orgRepos.push(item.full_name)
+ console.log(item.full_name)
+ })
+ })
+ })
+
+ req.on('error', (error) => {
+ console.error(error)
+ })
+
+ req.end()
+}
diff --git a/.automation/test/json/json_bad_1.json b/.automation/test/json/json_bad_1.json
new file mode 100644
index 00000000..6546aa8a
--- /dev/null
+++ b/.automation/test/json/json_bad_1.json
@@ -0,0 +1,10 @@
+{
+ "arrow_spacing": {
+ "level": ["ignore"]
+ },
+ "braces_spacing": {
+ "level": 'ignore',
+ "spaces": 0
+ "empty_object_spaces": 0
+ }
+}
diff --git a/.automation/test/json/json_good_1.json b/.automation/test/json/json_good_1.json
new file mode 100644
index 00000000..de60584a
--- /dev/null
+++ b/.automation/test/json/json_good_1.json
@@ -0,0 +1,10 @@
+{
+ "arrow_spacing": {
+ "level": "ignore"
+ },
+ "braces_spacing": {
+ "level": "ignore",
+ "spaces": 0,
+ "empty_object_spaces": 0
+ }
+}
diff --git a/.automation/test/markdown/markdown_bad_1.md b/.automation/test/markdown/markdown_bad_1.md
new file mode 100644
index 00000000..47aa18af
--- /dev/null
+++ b/.automation/test/markdown/markdown_bad_1.md
@@ -0,0 +1,20 @@
+## Bad Markdown
+
+This is just standard good markdown.
+
+###### Second level header
+
+This header does **NOT** follow the step down from `level 1`.
+
+- Here it *is*
+ - Some more indention
+ - why so much?
+
+```
+ls -la
+```
+
+# Walk away
+
+Were all done **here**.
+- [Link Action]https://github.com
diff --git a/.automation/test/markdown/markdown_good_1.md b/.automation/test/markdown/markdown_good_1.md
new file mode 100644
index 00000000..5634a455
--- /dev/null
+++ b/.automation/test/markdown/markdown_good_1.md
@@ -0,0 +1,20 @@
+# Good Markdown
+
+This is just standard good markdown.
+
+## Second level header
+
+This header follows the step down from `level 1`.
+
+- Here it *is*
+ - Some more **indention**
+ - why so much?
+
+```bash
+ls -la
+```
+
+### Walk away
+
+Were all done **here**.
+- [Link Action](https://github.com)
diff --git a/.automation/test/perl/perl_bad_1.pl b/.automation/test/perl/perl_bad_1.pl
new file mode 100644
index 00000000..e3626f88
--- /dev/null
+++ b/.automation/test/perl/perl_bad_1.pl
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+################################################################################
+################################################################################
+######### Script action @admiralAwkbar #########################################
+################################################################################
+
+#############
+# Load Libs #
+#############
+use strict;
+
+##################
+#### GLOBALS: ####
+##################
+my $state = undef; # State to return to GHE
+my $exitCode = undef # Code to exit with
+my $description = "Here it is"; # Description of the build
+
+###############
+#### MAIN: ####
+###############
+Header(); # Basic print statements
+AnotherOne();
+Again();
+
+#######################################################################
+#################### SUB ROUTINES BELOW ONLY ##########################
+#######################################################################
+#######################################################################
+#### SUB ROUTINE Header ###############################################
+sub Header
+{
+ print "-------------------------------------------------------------------\n";
+ print "State:\[$state\]\n";
+ print "ExitCode:\[$exitCode\]\n";
+ print "Description:\[$description\]\n";
+ print "What:[$here]\n";
+ print "-------------------------------------------------------------------\n";
+}
diff --git a/.automation/test/perl/perl_good_1.pl b/.automation/test/perl/perl_good_1.pl
new file mode 100644
index 00000000..f35c1409
--- /dev/null
+++ b/.automation/test/perl/perl_good_1.pl
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+################################################################################
+################################################################################
+######### Script action @admiralAwkbar #########################################
+################################################################################
+
+#############
+# Load Libs #
+#############
+use strict;
+
+$|=1;
+
+##################
+#### GLOBALS: ####
+##################
+my $state = undef; # State to return to GHE
+my $exitCode = 0; # Code to exit with
+my $description = "Here it is"; # Description of the build
+
+###############
+#### MAIN: ####
+###############
+Header(); # Basic print statements
+
+#######################################################################
+#################### SUB ROUTINES BELOW ONLY ##########################
+#######################################################################
+#######################################################################
+#### SUB ROUTINE Header ###############################################
+sub Header
+{
+ print "-------------------------------------------------------------------\n";
+ print "State:\[$state\]\n";
+ print "ExitCode:\[$exitCode\]\n";
+ print "Description:\[$description\]\n";
+ print "-------------------------------------------------------------------\n";
+}
diff --git a/.automation/test/python/python_bad_1.py b/.automation/test/python/python_bad_1.py
new file mode 100644
index 00000000..24d3ea83
--- /dev/null
+++ b/.automation/test/python/python_bad_1.py
@@ -0,0 +1,178 @@
+#!/usr/bin/python
+########################################################
+#### Jenkins Launch Job @LukasG ########################
+########################################################
+
+###########
+# Imports #
+###########
+import json
+import string
+import os
+import subprocess
+import requests
+
+###########
+# GLOBALS #
+###########
+jenkinsJob = # Job passed from command line to run
+triggerJobUrl = "" # Url of the created trigger job
+parameters = "" # parameters string passed from command line
+
+#####################
+# Jenkins Variables #
+#####################
+user = os.environ.get('HUBOT_JENKINS_AUTH_USER') # User to connect to Jenkins
+key = os.environ.get('HUBOT_JENKINS_AUTH_PASSWD') # API key to connect with
+jenkinsUrl = os.environ.get('HUBOT_JENKINS_SHORT_URL') # jenkins url
+token = os.environ.get('HUBOT_JENKINS_SECRET') # Special key
+
+##########################################################
+################### SUB ROUTINES BELOW ###################
+##########################################################
+##########################################################
+#### SUB ROUTINE StartJob ################################
+def StartJob():
+
+ # Build the master Url
+ url = ""
+
+ if (parameters = 'NONE' or parameters == "null"):
+ url = "http://%s:%s@%s/job/%s/build?token=%s" % (user,key,jenkinsUrl,jenkinsJob,token)
+ else:
+ url = "http://%s:%s@%s/job/%s/buildWithParameters?%s&token=%s" % (user,key,jenkinsUrl,jenkinsJob,parameters,token)
+
+ # Print url for debug
+ #print "Url:[%s]" %(url)
+
+ # build the header
+ headers = {"Content-Type": "application/json"}
+
+ # Send the request
+ response = requests.post(url, headers=headers)
+
+ # Check the response
+ #print "Response:[%s]" % (response)
+ if (response.status_code !== 201):
+ print "Failed to Launch Jenkins job:[%s]!" % (jenkinsJobs)
+ exit(1)
+
+ #print response.status_code
+ #print response.json()
+ #print response.headers['content-type']
+
+ # Need to get Location from headers
+ #print response.headers['location']
+ location = response.headers['location']
+
+ # Allow jenkins to queue
+ AllowQueue()
+ AllowQueue1()
+
+ # Need to get the jobid
+ GetJobId(location)
+
+ # Closing prints
+ print "Jenkins Job Link:"
+
+ # Removing http:// to shorten the length
+ cleanedUrl = triggerJobUrl[7:]
+
+ # Print the goods
+ print "http://%s" % (cleanedUrls)
+
+##########################################################
+#### SUB ROUTINE AllowQueue ##############################
+def AllowQueue():
+
+ # Need to sleep for some time to allow jenkins to set the job
+ # Jenkins is a dumb bastard who queues shit up, then waits for it to get a real job
+ # So we must wait for it...
+ cmd = "sleep 13s 2>&1"
+ #print "Waiting for few secods to allow jenkins to queue job"
+ status, output = commands.getstatusoutput(cmd)
+ #print "Status:[%s]" % (status)
+ #print "Output:[%s]" % (output)
+ # We have a success
+ #if (status == 0):
+
+##########################################################
+#### SUB ROUTINE GetJobId ################################
+def GetJobId(location):
+
+ # Load Globals
+ global triggerJobUrl
+
+ # Need to get the number out of the location string
+ # example: http://internal-jenkins-elb-340832960.us-east-1.elb.amazonaws.com/queue/item/29529/
+
+ # Remove any space chars
+ location.replace(" ","")
+
+ # Remove the trailing "/" char
+ location = location[:-1]
+
+ # Split the string on the last "/"
+ var1,var2 = location.rsplit('/',1)
+ location = var2
+
+ # Need to call jenkins with the queued location to get back job
+ url = "http://%s:%s@%s/queue/item/%s/api/json" % (user,key,jenkinsUrl,location)
+
+ # Build the header
+ headers = {"Content-Type": "application/json"}
+
+ # Call to jenkins
+ response = requests.post(url, headers=headers)
+
+ # check the response back from Jenkins
+ if (response.status_code != 200):
+ genericLink = "%s/job/%s" % (jenkinsUrl,jenkinsJob)
+ print "Failed to get specific Jenkins job Url!"
+ print "Generic Link:"
+ print "%s" % (genericLink)
+ exit(1)
+
+ #print response.json()
+ #print response.status_code
+
+ # Need to convert to json for parsing
+ response = response.json()
+
+ # Try to pull out the ProjectID
+ try:
+ triggerJobUrl = response['executable']['url']
+ #print "New Url:[%s]" % (triggerJobUrl)
+ except:
+ genericLink = "%s/job/%s" % (jenkinsUrl,jenkinsJob)
+ print "Failed to get specific jenkinsJob job Url!"
+ print "Generic Link:"
+ print "%s" % (genericLink)
+ exit(1)
+
+##########################################################
+##########################################################
+##########################################################
+########################## MAIN ##########################
+##########################################################
+
+# Need to split if there passed as a single var
+if len(sys.argv) == 2:
+
+ # Need to see if we have job and parameters
+ if "," in sys.argv[1]:
+ jenkinsJob,parameters=sys.argv[1].split(",",1)
+
+ else:
+ jenkinsJob=sys.argv[1]
+ parameters="NONE"
+
+ #print "DEBUG --- JenkinsJob:[%s]" % (jenkinsJob)
+ #print "DEBUG --- Paramaters:[%s]" % (parameters)
+
+else:
+ print "usage: python {0} <,OptionalParametersString>]".format(sys.argv[0])
+ sys.exit(2)
+
+# Start the orphan Job
+StartJob()
diff --git a/.automation/test/python/python_good_1.py b/.automation/test/python/python_good_1.py
new file mode 100644
index 00000000..75a6eeb8
--- /dev/null
+++ b/.automation/test/python/python_good_1.py
@@ -0,0 +1,181 @@
+#!/usr/bin/python
+########################################################
+#### Jenkins Launch Job @LukasG ########################
+########################################################
+
+###########
+# Imports #
+###########
+import json
+import string
+import os
+import subprocess
+import requests
+import os.path
+import commands
+import sys
+
+
+###########
+# GLOBALS #
+###########
+jenkinsJob = "" # Job passed from command line to run
+triggerJobUrl = "" # Url of the created trigger job
+parameters = "" # parameters string passed from command line
+
+#####################
+# Jenkins Variables #
+#####################
+user = os.environ.get('HUBOT_JENKINS_AUTH_USER') # User to connect to Jenkins
+key = os.environ.get('HUBOT_JENKINS_AUTH_PASSWD') # API key to connect with
+jenkinsUrl = os.environ.get('HUBOT_JENKINS_SHORT_URL') # jenkins url
+token = os.environ.get('HUBOT_JENKINS_SECRET') # Special key
+
+##########################################################
+################### SUB ROUTINES BELOW ###################
+##########################################################
+##########################################################
+#### SUB ROUTINE StartJob ################################
+def StartJob():
+
+ # Build the master Url
+ url = ""
+
+ if (parameters == "NONE" or parameters =="null"):
+ url = "http://%s:%s@%s/job/%s/build?token=%s" % (user,key,jenkinsUrl,jenkinsJob,token)
+ else:
+ url = "http://%s:%s@%s/job/%s/buildWithParameters?%s&token=%s" % (user,key,jenkinsUrl,jenkinsJob,parameters,token)
+
+ # Print url for debug
+ #print "Url:[%s]" %(url)
+
+ # build the header
+ headers = {"Content-Type": "application/json"}
+
+ # Send the request
+ response = requests.post(url, headers=headers)
+
+ # Check the response
+ #print "Response:[%s]" % (response)
+ if (response.status_code != 201):
+ print "Failed to Launch Jenkins job:[%s]!" % (jenkinsJob)
+ exit(1)
+
+ #print response.status_code
+ #print response.json()
+ #print response.headers['content-type']
+
+ # Need to get Location from headers
+ #print response.headers['location']
+ location = response.headers['location']
+
+ # Allow jenkins to queue
+ AllowQueue()
+
+ # Need to get the jobid
+ GetJobId(location)
+
+ # Closing prints
+ print "Jenkins Job Link:"
+
+ # Removing http:// to shorten the length
+ cleanedUrl = triggerJobUrl[7:]
+
+ # Print the goods
+ print "http://%s" % (cleanedUrl)
+
+##########################################################
+#### SUB ROUTINE AllowQueue ##############################
+def AllowQueue():
+
+ # Need to sleep for some time to allow jenkins to set the job
+ # Jenkins is a dumb bastard who queues shit up, then waits for it to get a real job
+ # So we must wait for it...
+ cmd = "sleep 13s 2>&1"
+ #print "Waiting for few secods to allow jenkins to queue job"
+ status, output = commands.getstatusoutput(cmd)
+ #print "Status:[%s]" % (status)
+ #print "Output:[%s]" % (output)
+ # We have a success
+ #if (status == 0):
+
+##########################################################
+#### SUB ROUTINE GetJobId ################################
+def GetJobId(location):
+
+ # Load Globals
+ global triggerJobUrl
+
+ # Need to get the number out of the location string
+ # example: http://internal-jenkins-elb-340832960.us-east-1.elb.amazonaws.com/queue/item/29529/
+
+ # Remove any space chars
+ location.replace(" ","")
+
+ # Remove the trailing "/" char
+ location = location[:-1]
+
+ # Split the string on the last "/"
+ var1,var2 = location.rsplit('/',1)
+ location = var2
+
+ # Need to call jenkins with the queued location to get back job
+ url = "http://%s:%s@%s/queue/item/%s/api/json" % (user,key,jenkinsUrl,location)
+
+ # Build the header
+ headers = {"Content-Type": "application/json"}
+
+ # Call to jenkins
+ response = requests.post(url, headers=headers)
+
+ # check the response back from Jenkins
+ if (response.status_code != 200):
+ genericLink = "%s/job/%s" % (jenkinsUrl,jenkinsJob)
+ print "Failed to get specific Jenkins job Url!"
+ print "Generic Link:"
+ print "%s" % (genericLink)
+ exit(1)
+
+ #print response.json()
+ #print response.status_code
+
+ # Need to convert to json for parsing
+ response = response.json()
+
+ # Try to pull out the ProjectID
+ try:
+ triggerJobUrl = response['executable']['url']
+ #print "New Url:[%s]" % (triggerJobUrl)
+ except:
+ genericLink = "%s/job/%s" % (jenkinsUrl,jenkinsJob)
+ print "Failed to get specific jenkinsJob job Url!"
+ print "Generic Link:"
+ print "%s" % (genericLink)
+ exit(1)
+
+##########################################################
+##########################################################
+##########################################################
+########################## MAIN ##########################
+##########################################################
+
+# Need to split if there passed as a single var
+if len(sys.argv) == 2:
+
+ # Need to see if we have job and parameters
+ if "," in sys.argv[1]:
+ jenkinsJob,parameters=sys.argv[1].split(",",1)
+
+ else:
+ jenkinsJob=sys.argv[1]
+ parameters="NONE"
+
+ #print "DEBUG --- JenkinsJob:[%s]" % (jenkinsJob)
+ #print "DEBUG --- Paramaters:[%s]" % (parameters)
+
+else:
+ print "usage: python {0} <,OptionalParametersString>]".format(sys.argv[0])
+ sys.exit(2)
+
+# Start the orphan Job
+StartJob()
diff --git a/.automation/test/ruby/ruby_bad_1.rb b/.automation/test/ruby/ruby_bad_1.rb
new file mode 100644
index 00000000..a80dffa3
--- /dev/null
+++ b/.automation/test/ruby/ruby_bad_1.rb
@@ -0,0 +1,28 @@
+
+# Rails Console only
+# This script will output all active webhooks currently being processed by an instance.
+# Replace ARRAY_OF_URLS_CALLING_INSTANCE and GHES_URL with the appropriate values before running
+
+# Prior to running this script, compile a list of the top URLs containing the phrase webhook
+# This should be ran prior to entering the Rails Console with the command:
+# grep -B1 --no-group-separator 'Faraday::TimeoutError' hookshot-logs/resqued.log | sed -n 1~2p |
+# \ grep -v 'Faraday::TimeoutError: request timed out' | sort | uniq -c |sort -rn | head -n 20
+
+File.open('/tmp/urls.txt', " w" ) do | file|
+ Hook.active.map do |h |
+ urls = [ ARRAY_OF_URLS_CALLING_INSTANCE]
+
+ next if urls.include? h.url
+
+
+ begin
+ file.puts "https://GHES_URL/api/v3/repos/#{h.installation_target.full_name}/hooks/#{h.id}"
+
+ rescue StandardError => e
+ puts e.message
+
+ end
+
+ end
+
+end
diff --git a/.automation/test/ruby/ruby_good_1.rb b/.automation/test/ruby/ruby_good_1.rb
new file mode 100644
index 00000000..0971f071
--- /dev/null
+++ b/.automation/test/ruby/ruby_good_1.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+# Rails Console only
+# This script will output all active webhooks currently being processed by an instance.
+# Replace ARRAY_OF_URLS_CALLING_INSTANCE and GHES_URL with the appropriate values before running
+
+# Prior to running this script, compile a list of the top URLs containing the phrase webhook
+# This should be ran prior to entering the Rails Console with the command:
+# grep -B1 --no-group-separator 'Faraday::TimeoutError' hookshot-logs/resqued.log | sed -n 1~2p |
+# \ grep -v 'Faraday::TimeoutError: request timed out' | sort | uniq -c |sort -rn | head -n 20
+
+File.open("/tmp/urls.txt", "w") do |file|
+ Hook.active.map do |h|
+ urls = [ARRAY_OF_URLS_CALLING_INSTANCE]
+ next if urls.include? h.url
+
+ begin
+ file.puts "https://GHES_URL/api/v3/repos/#{h.installation_target.full_name}/hooks/#{h.id}"
+ rescue StandardError => e
+ puts e.message
+ end
+ end
+end
diff --git a/.automation/test/shell/shell_bad_1.sh b/.automation/test/shell/shell_bad_1.sh
new file mode 100644
index 00000000..041c57ae
--- /dev/null
+++ b/.automation/test/shell/shell_bad_1.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# CMD
+HELLO_WORLD=($(echo "Hello World" | cut -f1 -d' ' 2>&1))
+
+# Load the error code
+ERROR_CODE=$?
+
+# Check the shell
+if [ $ERROR_CODE -ne 0]; then
+ echo "We did it!"
+ exit 0
+else
+ echo "We done goofed it..."
+ echo $HELLO_WORLD
+ exit 1
+fi
diff --git a/.automation/test/shell/shell_good_1.sh b/.automation/test/shell/shell_good_1.sh
new file mode 100644
index 00000000..66430423
--- /dev/null
+++ b/.automation/test/shell/shell_good_1.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# CMD
+HELLO_WORLD=$(echo "Hello World" | cut -f1 -d' ' 2>&1)
+
+# Load the error code
+ERROR_CODE=$?
+
+# Check the shell
+if [ $ERROR_CODE -ne 0 ]; then
+ echo "We did it!"
+ exit 0
+else
+ echo "We done goofed it..."
+ echo "$HELLO_WORLD"
+ exit 1
+fi
diff --git a/.automation/test/xml/xml_bad_1.xml b/.automation/test/xml/xml_bad_1.xml
new file mode 100644
index 00000000..73c85fa9
--- /dev/null
+++ b/.automation/test/xml/xml_bad_1.xml
@@ -0,0 +1,6 @@
+
+ Tove
+ Jani
+ Reminder
+ Don't forget me this weekend!
+
diff --git a/.automation/test/xml/xml_good_1.xml b/.automation/test/xml/xml_good_1.xml
new file mode 100644
index 00000000..97de6219
--- /dev/null
+++ b/.automation/test/xml/xml_good_1.xml
@@ -0,0 +1,6 @@
+
+ Tove
+ Jani
+ Reminder
+ Don't forget me this weekend!
+
diff --git a/.automation/test/yml/yml_bad_1.yml b/.automation/test/yml/yml_bad_1.yml
new file mode 100644
index 00000000..11e35c04
--- /dev/null
+++ b/.automation/test/yml/yml_bad_1.yml
@@ -0,0 +1,17 @@
+#####################
+#####################
+## Heres some vars ##
+#####################
+#####################
+
+############
+# Env Vars #
+############
+env:
+ browser: here: there : again "yep"
+ es6: 0
+ jest: yes
+
+Here: there 'is' something going on
+
+something: "For 'Nothing'" 123
diff --git a/.automation/test/yml/yml_good_1.yml b/.automation/test/yml/yml_good_1.yml
new file mode 100644
index 00000000..81221f0f
--- /dev/null
+++ b/.automation/test/yml/yml_good_1.yml
@@ -0,0 +1,19 @@
+---
+
+#####################
+#####################
+## Heres some vars ##
+#####################
+#####################
+
+############
+# Env Vars #
+############
+env:
+ browser: true
+ es6: true
+ jest: true
+
+Here: there
+
+something: "For Nothing"
diff --git a/lib/linter.sh b/lib/linter.sh
index 7db36da6..ef629732 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -82,6 +82,7 @@ DEFAULT_RUN_LOCAL='false' # Default value for debugg
DEFAULT_VERBOSE_OUTPUT='false' # Default value for debugging output
RAW_FILE_ARRAY=() # Array of all files that were changed
READ_ONLY_CHANGE_FLAG=0 # Flag set to 1 if files changed are not txt or md
+TEST_CASE_FOLDER='.automation/test' # Folder for test cases we should always ignore
##########################
# Array of changed files #
@@ -1164,12 +1165,15 @@ LintCodebase()
#####################
FILE_NAME=$(basename "$FILE" 2>&1)
- #######################################
- # Make sure we dont lint node modules #
- #######################################
+ #####################################################
+ # Make sure we dont lint node modules or test cases #
+ #####################################################
if [[ $FILE == *"node_modules"* ]]; then
# This is a node modules file
continue
+ elif [[ $FILE == *".automation/test" ]]; then
+ # This is the test cases, we should always skip
+ continue
fi
##############
From fc9d45e49d7761b7e3695c441d3a50f5261e51c4 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 08:56:53 -0600
Subject: [PATCH 02/28] fixing bad cases
---
.automation/test/coffeescript/coffeescript_bad_1.coffee | 8 ++++----
.automation/test/javascript/javascript_bad_1.js | 9 +++++----
.automation/test/python/python_good_1.py | 2 --
lib/linter.sh | 2 +-
4 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/.automation/test/coffeescript/coffeescript_bad_1.coffee b/.automation/test/coffeescript/coffeescript_bad_1.coffee
index c307948e..624cb3cd 100644
--- a/.automation/test/coffeescript/coffeescript_bad_1.coffee
+++ b/.automation/test/coffeescript/coffeescript_bad_1.coffee
@@ -26,7 +26,7 @@ dropHammer = [
###################
thanks = [
"You're welcome! Piece of cake...",
- "It was nothing..."
+ It was nothing...
"De nada...",
'Danke...'
"Bitte...",
@@ -36,13 +36,13 @@ thanks = [
#################################
# Start the robot for listening #
#################################
-module.exports = (robot) ->
+module.exports = (robot) -> )
##############################
# Show the adapter connected #
##############################
robot.respond /ADAPTER$/i, (msg) ->
- msg.send robot.adapterName
+ msg.send robot.adapterNameS
##########################
# Echo back the response #
@@ -73,7 +73,7 @@ module.exports = (robot) ->
# Hubot Ping #
##############
robot.respond /PING$/i, (msg) ->
- msg.sned "PONG"
+ msg.sned PONG
#######################
#######################
diff --git a/.automation/test/javascript/javascript_bad_1.js b/.automation/test/javascript/javascript_bad_1.js
index c2c104bb..9f2fae8d 100644
--- a/.automation/test/javascript/javascript_bad_1.js
+++ b/.automation/test/javascript/javascript_bad_1.js
@@ -1,10 +1,11 @@
var http = require('http')
-var createHandler = require('github-webhook-handler')
-var handler = createHandler({ path: '/webhook', secret: (process.env.SECRET) })
+var createHandler = require( 'github-webhook-handler')
-var userArray = ['user1']
+var handler = createHandler( { path : /webhook, secret : (process.env.SECRET) })
-var teamDescription = 'Team of Robots'
+var userArray = [ 'user1' ]
+
+var teamDescription = Team of Robots
var teamPrivacy = 'closed' // closed (visibile) / secret (hidden) are options here
var teamName = process.env.GHES_TEAM_NAME
diff --git a/.automation/test/python/python_good_1.py b/.automation/test/python/python_good_1.py
index 75a6eeb8..a679ffa2 100644
--- a/.automation/test/python/python_good_1.py
+++ b/.automation/test/python/python_good_1.py
@@ -15,7 +15,6 @@ import os.path
import commands
import sys
-
###########
# GLOBALS #
###########
@@ -59,7 +58,6 @@ def StartJob():
#print "Response:[%s]" % (response)
if (response.status_code != 201):
print "Failed to Launch Jenkins job:[%s]!" % (jenkinsJob)
- exit(1)
#print response.status_code
#print response.json()
diff --git a/lib/linter.sh b/lib/linter.sh
index ef629732..d6380423 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -1171,7 +1171,7 @@ LintCodebase()
if [[ $FILE == *"node_modules"* ]]; then
# This is a node modules file
continue
- elif [[ $FILE == *".automation/test" ]]; then
+ elif [[ $FILE == *"$TEST_CASE_FOLDER" ]]; then
# This is the test cases, we should always skip
continue
fi
From edc665d55011581a5ae6bec0b615e641c903f398 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 09:03:29 -0600
Subject: [PATCH 03/28] more bad code
---
.../test/javascript/javascript_bad_1.js | 3 +
.automation/test/python/python_bad_1.py | 292 ++++++++----------
.automation/test/python/python_good_1.py | 290 ++++++++---------
3 files changed, 271 insertions(+), 314 deletions(-)
diff --git a/.automation/test/javascript/javascript_bad_1.js b/.automation/test/javascript/javascript_bad_1.js
index 9f2fae8d..d79300ed 100644
--- a/.automation/test/javascript/javascript_bad_1.js
+++ b/.automation/test/javascript/javascript_bad_1.js
@@ -16,6 +16,9 @@ var orgRepos = []
// var creator = ""
+var foo = someFunction();
+var bar = a + 1;
+
http.createServer(function (req, res) {
handler(req, res, function (err) {
console.log(err)
diff --git a/.automation/test/python/python_bad_1.py b/.automation/test/python/python_bad_1.py
index 24d3ea83..843aad50 100644
--- a/.automation/test/python/python_bad_1.py
+++ b/.automation/test/python/python_bad_1.py
@@ -1,178 +1,156 @@
-#!/usr/bin/python
-########################################################
-#### Jenkins Launch Job @LukasG ########################
-########################################################
-
-###########
-# Imports #
-###########
import json
-import string
-import os
-import subprocess
-import requests
+from os import getenv, path
+from pprint import pprint
+import sys
-###########
-# GLOBALS #
-###########
-jenkinsJob = # Job passed from command line to run
-triggerJobUrl = "" # Url of the created trigger job
-parameters = "" # parameters string passed from command line
+import click # pylint: disable=import-error
+from dotenv import load_dotenv # pylint: disable=import-error
+import requests # pylint: disable=import-error
-#####################
-# Jenkins Variables #
-#####################
-user = os.environ.get('HUBOT_JENKINS_AUTH_USER') # User to connect to Jenkins
-key = os.environ.get('HUBOT_JENKINS_AUTH_PASSWD') # API key to connect with
-jenkinsUrl = os.environ.get('HUBOT_JENKINS_SHORT_URL') # jenkins url
-token = os.environ.get('HUBOT_JENKINS_SECRET') # Special key
+env = load_dotenv()
+api_url = getenv(API_URL, default='https://api.github.com/graphql' )
+github_token = getenv("GITHUB_TOKEN",
+default=None)
-##########################################################
-################### SUB ROUTINES BELOW ###################
-##########################################################
-##########################################################
-#### SUB ROUTINE StartJob ################################
-def StartJob():
+if github_token is None
+ sys.exit("GitHub Token is not set." +
+ "Please set the GITHUB_TOKEN env variable in your system or " +
+ "the .env file of your project.")
- # Build the master Url
- url = ""
+client_id = getenv(CLIENT_ID, default='copy_labels.py')
+headers = {
+ 'Authorization': 'bearer {github_token}'.format(github_token=github_token),
+ 'Accept': 'application/vnd.github.bane-preview+json'
+ 'Content-Type': 'application/json'
+}
- if (parameters = 'NONE' or parameters == "null"):
- url = "http://%s:%s@%s/job/%s/build?token=%s" % (user,key,jenkinsUrl,jenkinsJob,token)
+def create_label(repo_id, label):
+ """
+ Create label in the supplied repo.
+
+ :param repo_id: Unique ID that represents the repo in GitHub
+ :type repo_id: str
+ :param label: Object with label information.
+ :type label: dict
+ :return: GitHub API request response
+ """
+
+ query_variables = {
+ "createLabelInput": {
+ "color": label["color"],
+ "description": label["description"],
+ "name": label["name"],
+ "repositoryId": repo_id
+ }
+ }
+
+ with open(path.join(path.dirname(__file__), 'queries/create_label.gql'), 'r') as query_file:
+ query = "".join(query_file.readlines())
+
+ payload = {"query": query, "variables": query_variables}
+ response = requests.post(api_url, data=json.dumps(payload), headers=headers).json()
+ print('Created label {label}'.format(label=label["name"]))
+
+ return response
+
+def get_labels(owner, repo):
+ """
+ Gets a list of labels from the supplied repo.
+ :param owner: Repo owner GitHub login.
+ :type owner: str
+ :param repo: Repository name.
+ :type repo: str
+ :return: A tuple with the GitHub id for the repository and a list of labels defined in the repository
+ """
+
+ query_variables = { "owner": owner, "name": repo, }
+
+ with open(path.join(path.dirname(__file__), 'queries/get_repo_data.gql'), 'r') as query_file:
+ query = "".join(query_file.readlines())
+
+ payload = {"query": query, "variables": query_variables}
+ response = requests.post(api_url, data=json.dumps(payload), headers=headers)
+
+ status_code = response.status_code
+ result = response.json()
+
+ if status_code >= 200 and status_code <= 300:
+ repo_id = result["data"]["repository"]["id"]
+ labels = result["data"]["repository"]["labels"]["nodes"]
+
+ return repo_id, labels
else:
- url = "http://%s:%s@%s/job/%s/buildWithParameters?%s&token=%s" % (user,key,jenkinsUrl,jenkinsJob,parameters,token)
+ raise Exception(
+ '[ERROR] getting issue labels. Status Code: {status_code} - Message: {result}'.format(
+ status_code=status_code, result=result["message"]))
- # Print url for debug
- #print "Url:[%s]" %(url)
+def delete_label(label_id):
+ """
+ Delete the specified label
+ :param label_id: Label's node id.
+ :type label_id: str
+ :return: Github API request response.
+ """
- # build the header
- headers = {"Content-Type": "application/json"}
+ query_variables = {
+ "deleteLabelInput": {
+ "clientMutationId": client_id,
+ "id": label_id,
+ }
+ }
- # Send the request
- response = requests.post(url, headers=headers)
+ with open(path.join(path.dirname(__file__), 'queries/delete_label.gql'), 'r') as query_file:
+ query = "".join(query_file.readlines())
- # Check the response
- #print "Response:[%s]" % (response)
- if (response.status_code !== 201):
- print "Failed to Launch Jenkins job:[%s]!" % (jenkinsJobs)
- exit(1)
+ payload = {"query": query, "variables": query_variables}
+ result = requests.post(api_url, data=json.dumps(payload), headers=headers).json()
- #print response.status_code
- #print response.json()
- #print response.headers['content-type']
+ return result
- # Need to get Location from headers
- #print response.headers['location']
- location = response.headers['location']
+@click.command()
+@click.option('--dry', is_flag=True)
+@click.argument('source_repo')
+@click.argument('target_repo')
+def copy_labels(source_repo, target_repo, dry):
+ """
+ Copy labels from the source repository to the target repository.
+ \f
+ :param source: The full name of a GitHub repo from where the labels will be copied from. Eg. github/opensourcefriday
+ :type source: str
+ :param target: The full name of a GitHub repo to where the labels will be copied. Eg. github/opensourcefriday
+ :type target: str
+ :return:
+ """
+ source_owner, source_repo_name = source_repo.split("/")
+ target_owner, target_repo_name = target_repo.split("/")
- # Allow jenkins to queue
- AllowQueue()
- AllowQueue1()
-
- # Need to get the jobid
- GetJobId(location)
-
- # Closing prints
- print "Jenkins Job Link:"
-
- # Removing http:// to shorten the length
- cleanedUrl = triggerJobUrl[7:]
-
- # Print the goods
- print "http://%s" % (cleanedUrls)
-
-##########################################################
-#### SUB ROUTINE AllowQueue ##############################
-def AllowQueue():
-
- # Need to sleep for some time to allow jenkins to set the job
- # Jenkins is a dumb bastard who queues shit up, then waits for it to get a real job
- # So we must wait for it...
- cmd = "sleep 13s 2>&1"
- #print "Waiting for few secods to allow jenkins to queue job"
- status, output = commands.getstatusoutput(cmd)
- #print "Status:[%s]" % (status)
- #print "Output:[%s]" % (output)
- # We have a success
- #if (status == 0):
-
-##########################################################
-#### SUB ROUTINE GetJobId ################################
-def GetJobId(location):
-
- # Load Globals
- global triggerJobUrl
-
- # Need to get the number out of the location string
- # example: http://internal-jenkins-elb-340832960.us-east-1.elb.amazonaws.com/queue/item/29529/
-
- # Remove any space chars
- location.replace(" ","")
-
- # Remove the trailing "/" char
- location = location[:-1]
-
- # Split the string on the last "/"
- var1,var2 = location.rsplit('/',1)
- location = var2
-
- # Need to call jenkins with the queued location to get back job
- url = "http://%s:%s@%s/queue/item/%s/api/json" % (user,key,jenkinsUrl,location)
-
- # Build the header
- headers = {"Content-Type": "application/json"}
-
- # Call to jenkins
- response = requests.post(url, headers=headers)
-
- # check the response back from Jenkins
- if (response.status_code != 200):
- genericLink = "%s/job/%s" % (jenkinsUrl,jenkinsJob)
- print "Failed to get specific Jenkins job Url!"
- print "Generic Link:"
- print "%s" % (genericLink)
- exit(1)
-
- #print response.json()
- #print response.status_code
-
- # Need to convert to json for parsing
- response = response.json()
-
- # Try to pull out the ProjectID
try:
- triggerJobUrl = response['executable']['url']
- #print "New Url:[%s]" % (triggerJobUrl)
- except:
- genericLink = "%s/job/%s" % (jenkinsUrl,jenkinsJob)
- print "Failed to get specific jenkinsJob job Url!"
- print "Generic Link:"
- print "%s" % (genericLink)
- exit(1)
+ print('Fetching labels for {source_repo_name} repo.'.format(source_repo_name=source_repo_name))
+ _, source_repo_labels = get_labels(source_owner, source_repo_name)
+ print('Fetched labels for {source_repo_name}'.format(source_repo_name=source_repo_name))
-##########################################################
-##########################################################
-##########################################################
-########################## MAIN ##########################
-##########################################################
+ print('Fetching labels for {target_repo_name} repo.'.format(target_repo_name=target_repo_name))
+ target_repo_id, target_repo_labels = get_labels(target_owner, target_repo_name)
+ print('Fetched labels for {target_repo_name}'.format(target_repo_name=target_repo_name))
-# Need to split if there passed as a single var
-if len(sys.argv) == 2:
+ filtered_labels = list(filter(lambda x: x not in target_repo_labels, source_repo_labels))
- # Need to see if we have job and parameters
- if "," in sys.argv[1]:
- jenkinsJob,parameters=sys.argv[1].split(",",1)
+ if dry:
+ print('This is just a dry run. No labels will be copied/created.')
+ print('{label_count} labels would have been created.'.format(label_count=len(filtered_labels)))
+ pprint(filtered_labels, indent=4)
+ else:
+ print('Preparing to created {label_count} labels in {target_repo}'.format(
+ label_count=len(filtered_labels), target_repo=target_repo))
- else:
- jenkinsJob=sys.argv[1]
- parameters="NONE"
+ for label in filtered_labels:
+ create_label(target_repo_id, label)
+ except Exception as error:
+ sys.exit(error)
- #print "DEBUG --- JenkinsJob:[%s]" % (jenkinsJob)
- #print "DEBUG --- Paramaters:[%s]" % (parameters)
+ print('Done')
-else:
- print "usage: python {0} <,OptionalParametersString>]".format(sys.argv[0])
- sys.exit(2)
-
-# Start the orphan Job
-StartJob()
+if __name__ == "__main__":
+ # Pylint doesn't know that @click.command takes care of injecting the
+ # function parameters. Disabling Pylint error.
+ copy_labels() # pylint: disable=no-value-for-parameter
diff --git a/.automation/test/python/python_good_1.py b/.automation/test/python/python_good_1.py
index a679ffa2..f808c297 100644
--- a/.automation/test/python/python_good_1.py
+++ b/.automation/test/python/python_good_1.py
@@ -1,179 +1,155 @@
-#!/usr/bin/python
-########################################################
-#### Jenkins Launch Job @LukasG ########################
-########################################################
-
-###########
-# Imports #
-###########
import json
-import string
-import os
-import subprocess
-import requests
-import os.path
-import commands
+from os import getenv, path
+from pprint import pprint
import sys
-###########
-# GLOBALS #
-###########
-jenkinsJob = "" # Job passed from command line to run
-triggerJobUrl = "" # Url of the created trigger job
-parameters = "" # parameters string passed from command line
+import click # pylint: disable=import-error
+from dotenv import load_dotenv # pylint: disable=import-error
+import requests # pylint: disable=import-error
-#####################
-# Jenkins Variables #
-#####################
-user = os.environ.get('HUBOT_JENKINS_AUTH_USER') # User to connect to Jenkins
-key = os.environ.get('HUBOT_JENKINS_AUTH_PASSWD') # API key to connect with
-jenkinsUrl = os.environ.get('HUBOT_JENKINS_SHORT_URL') # jenkins url
-token = os.environ.get('HUBOT_JENKINS_SECRET') # Special key
+env = load_dotenv()
+api_url = getenv('API_URL', default='https://api.github.com/graphql')
+github_token = getenv("GITHUB_TOKEN", default=None)
-##########################################################
-################### SUB ROUTINES BELOW ###################
-##########################################################
-##########################################################
-#### SUB ROUTINE StartJob ################################
-def StartJob():
+if github_token is None:
+ sys.exit("GitHub Token is not set." +
+ "Please set the GITHUB_TOKEN env variable in your system or " +
+ "the .env file of your project.")
- # Build the master Url
- url = ""
+client_id = getenv('CLIENT_ID', default='copy_labels.py')
+headers = {
+ 'Authorization': 'bearer {github_token}'.format(github_token=github_token),
+ 'Accept': 'application/vnd.github.bane-preview+json',
+ 'Content-Type': 'application/json'
+}
- if (parameters == "NONE" or parameters =="null"):
- url = "http://%s:%s@%s/job/%s/build?token=%s" % (user,key,jenkinsUrl,jenkinsJob,token)
+def create_label(repo_id, label):
+ """
+ Create label in the supplied repo.
+
+ :param repo_id: Unique ID that represents the repo in GitHub
+ :type repo_id: str
+ :param label: Object with label information.
+ :type label: dict
+ :return: GitHub API request response
+ """
+
+ query_variables = {
+ "createLabelInput": {
+ "color": label["color"],
+ "description": label["description"],
+ "name": label["name"],
+ "repositoryId": repo_id
+ }
+ }
+
+ with open(path.join(path.dirname(__file__), 'queries/create_label.gql'), 'r') as query_file:
+ query = "".join(query_file.readlines())
+
+ payload = {"query": query, "variables": query_variables}
+ response = requests.post(api_url, data=json.dumps(payload), headers=headers).json()
+ print('Created label {label}'.format(label=label["name"]))
+
+ return response
+
+def get_labels(owner, repo):
+ """
+ Gets a list of labels from the supplied repo.
+ :param owner: Repo owner GitHub login.
+ :type owner: str
+ :param repo: Repository name.
+ :type repo: str
+ :return: A tuple with the GitHub id for the repository and a list of labels defined in the repository
+ """
+
+ query_variables = { "owner": owner, "name": repo, }
+
+ with open(path.join(path.dirname(__file__), 'queries/get_repo_data.gql'), 'r') as query_file:
+ query = "".join(query_file.readlines())
+
+ payload = {"query": query, "variables": query_variables}
+ response = requests.post(api_url, data=json.dumps(payload), headers=headers)
+
+ status_code = response.status_code
+ result = response.json()
+
+ if status_code >= 200 and status_code <= 300:
+ repo_id = result["data"]["repository"]["id"]
+ labels = result["data"]["repository"]["labels"]["nodes"]
+
+ return repo_id, labels
else:
- url = "http://%s:%s@%s/job/%s/buildWithParameters?%s&token=%s" % (user,key,jenkinsUrl,jenkinsJob,parameters,token)
+ raise Exception(
+ '[ERROR] getting issue labels. Status Code: {status_code} - Message: {result}'.format(
+ status_code=status_code, result=result["message"]))
- # Print url for debug
- #print "Url:[%s]" %(url)
+def delete_label(label_id):
+ """
+ Delete the specified label
+ :param label_id: Label's node id.
+ :type label_id: str
+ :return: Github API request response.
+ """
- # build the header
- headers = {"Content-Type": "application/json"}
+ query_variables = {
+ "deleteLabelInput": {
+ "clientMutationId": client_id,
+ "id": label_id,
+ }
+ }
- # Send the request
- response = requests.post(url, headers=headers)
+ with open(path.join(path.dirname(__file__), 'queries/delete_label.gql'), 'r') as query_file:
+ query = "".join(query_file.readlines())
- # Check the response
- #print "Response:[%s]" % (response)
- if (response.status_code != 201):
- print "Failed to Launch Jenkins job:[%s]!" % (jenkinsJob)
+ payload = {"query": query, "variables": query_variables}
+ result = requests.post(api_url, data=json.dumps(payload), headers=headers).json()
- #print response.status_code
- #print response.json()
- #print response.headers['content-type']
+ return result
- # Need to get Location from headers
- #print response.headers['location']
- location = response.headers['location']
+@click.command()
+@click.option('--dry', is_flag=True)
+@click.argument('source_repo')
+@click.argument('target_repo')
+def copy_labels(source_repo, target_repo, dry):
+ """
+ Copy labels from the source repository to the target repository.
+ \f
+ :param source: The full name of a GitHub repo from where the labels will be copied from. Eg. github/opensourcefriday
+ :type source: str
+ :param target: The full name of a GitHub repo to where the labels will be copied. Eg. github/opensourcefriday
+ :type target: str
+ :return:
+ """
+ source_owner, source_repo_name = source_repo.split("/")
+ target_owner, target_repo_name = target_repo.split("/")
- # Allow jenkins to queue
- AllowQueue()
-
- # Need to get the jobid
- GetJobId(location)
-
- # Closing prints
- print "Jenkins Job Link:"
-
- # Removing http:// to shorten the length
- cleanedUrl = triggerJobUrl[7:]
-
- # Print the goods
- print "http://%s" % (cleanedUrl)
-
-##########################################################
-#### SUB ROUTINE AllowQueue ##############################
-def AllowQueue():
-
- # Need to sleep for some time to allow jenkins to set the job
- # Jenkins is a dumb bastard who queues shit up, then waits for it to get a real job
- # So we must wait for it...
- cmd = "sleep 13s 2>&1"
- #print "Waiting for few secods to allow jenkins to queue job"
- status, output = commands.getstatusoutput(cmd)
- #print "Status:[%s]" % (status)
- #print "Output:[%s]" % (output)
- # We have a success
- #if (status == 0):
-
-##########################################################
-#### SUB ROUTINE GetJobId ################################
-def GetJobId(location):
-
- # Load Globals
- global triggerJobUrl
-
- # Need to get the number out of the location string
- # example: http://internal-jenkins-elb-340832960.us-east-1.elb.amazonaws.com/queue/item/29529/
-
- # Remove any space chars
- location.replace(" ","")
-
- # Remove the trailing "/" char
- location = location[:-1]
-
- # Split the string on the last "/"
- var1,var2 = location.rsplit('/',1)
- location = var2
-
- # Need to call jenkins with the queued location to get back job
- url = "http://%s:%s@%s/queue/item/%s/api/json" % (user,key,jenkinsUrl,location)
-
- # Build the header
- headers = {"Content-Type": "application/json"}
-
- # Call to jenkins
- response = requests.post(url, headers=headers)
-
- # check the response back from Jenkins
- if (response.status_code != 200):
- genericLink = "%s/job/%s" % (jenkinsUrl,jenkinsJob)
- print "Failed to get specific Jenkins job Url!"
- print "Generic Link:"
- print "%s" % (genericLink)
- exit(1)
-
- #print response.json()
- #print response.status_code
-
- # Need to convert to json for parsing
- response = response.json()
-
- # Try to pull out the ProjectID
try:
- triggerJobUrl = response['executable']['url']
- #print "New Url:[%s]" % (triggerJobUrl)
- except:
- genericLink = "%s/job/%s" % (jenkinsUrl,jenkinsJob)
- print "Failed to get specific jenkinsJob job Url!"
- print "Generic Link:"
- print "%s" % (genericLink)
- exit(1)
+ print('Fetching labels for {source_repo_name} repo.'.format(source_repo_name=source_repo_name))
+ _, source_repo_labels = get_labels(source_owner, source_repo_name)
+ print('Fetched labels for {source_repo_name}'.format(source_repo_name=source_repo_name))
-##########################################################
-##########################################################
-##########################################################
-########################## MAIN ##########################
-##########################################################
+ print('Fetching labels for {target_repo_name} repo.'.format(target_repo_name=target_repo_name))
+ target_repo_id, target_repo_labels = get_labels(target_owner, target_repo_name)
+ print('Fetched labels for {target_repo_name}'.format(target_repo_name=target_repo_name))
-# Need to split if there passed as a single var
-if len(sys.argv) == 2:
+ filtered_labels = list(filter(lambda x: x not in target_repo_labels, source_repo_labels))
- # Need to see if we have job and parameters
- if "," in sys.argv[1]:
- jenkinsJob,parameters=sys.argv[1].split(",",1)
+ if dry:
+ print('This is just a dry run. No labels will be copied/created.')
+ print('{label_count} labels would have been created.'.format(label_count=len(filtered_labels)))
+ pprint(filtered_labels, indent=4)
+ else:
+ print('Preparing to created {label_count} labels in {target_repo}'.format(
+ label_count=len(filtered_labels), target_repo=target_repo))
- else:
- jenkinsJob=sys.argv[1]
- parameters="NONE"
+ for label in filtered_labels:
+ create_label(target_repo_id, label)
+ except Exception as error:
+ sys.exit(error)
- #print "DEBUG --- JenkinsJob:[%s]" % (jenkinsJob)
- #print "DEBUG --- Paramaters:[%s]" % (parameters)
+ print('Done')
-else:
- print "usage: python {0} <,OptionalParametersString>]".format(sys.argv[0])
- sys.exit(2)
-
-# Start the orphan Job
-StartJob()
+if __name__ == "__main__":
+ # Pylint doesn't know that @click.command takes care of injecting the
+ # function parameters. Disabling Pylint error.
+ copy_labels() # pylint: disable=no-value-for-parameter
From 2d93ca41f45133f873a48847882ae1963dfc36c9 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 09:04:43 -0600
Subject: [PATCH 04/28] fixed that
---
lib/linter.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/linter.sh b/lib/linter.sh
index d6380423..0308dbd4 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -1171,7 +1171,7 @@ LintCodebase()
if [[ $FILE == *"node_modules"* ]]; then
# This is a node modules file
continue
- elif [[ $FILE == *"$TEST_CASE_FOLDER" ]]; then
+ elif [[ $FILE == *"$TEST_CASE_FOLDER"* ]]; then
# This is the test cases, we should always skip
continue
fi
From 7c194ba87a390f14fd9d57ca412b2563be9dcad5 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 09:11:31 -0600
Subject: [PATCH 05/28] fix language
---
.automation/test/README.md | 3 ++-
.../test/docker/{docker_bad_1.DOCKERFILE => bad/Dockerfile} | 0
.../test/docker/{docker_good_1.DOCKERFILE => good/Dockerfile} | 0
3 files changed, 2 insertions(+), 1 deletion(-)
rename .automation/test/docker/{docker_bad_1.DOCKERFILE => bad/Dockerfile} (100%)
rename .automation/test/docker/{docker_good_1.DOCKERFILE => good/Dockerfile} (100%)
diff --git a/.automation/test/README.md b/.automation/test/README.md
index 3b56fe42..53bccba2 100644
--- a/.automation/test/README.md
+++ b/.automation/test/README.md
@@ -1,7 +1,8 @@
# Test Cases
This folder holds `template test cases` that are used to validate the sanity of the **Super-Linter**.
The format:
-- Folder(s) containing test cases for each language supported
+- Each **Super-Linter** language should have its own folder
+ - Folder(s) containing test cases for each language supported
- Passing test case(s) per language denoted in naming scheme
- Failing test case(s) per language denoted in naming scheme
- Script to run test cases and validate the sanity of **Super-Linter**
diff --git a/.automation/test/docker/docker_bad_1.DOCKERFILE b/.automation/test/docker/bad/Dockerfile
similarity index 100%
rename from .automation/test/docker/docker_bad_1.DOCKERFILE
rename to .automation/test/docker/bad/Dockerfile
diff --git a/.automation/test/docker/docker_good_1.DOCKERFILE b/.automation/test/docker/good/Dockerfile
similarity index 100%
rename from .automation/test/docker/docker_good_1.DOCKERFILE
rename to .automation/test/docker/good/Dockerfile
From bc42254fd595a904cb0973239967cfa12021a521 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 11:49:07 -0600
Subject: [PATCH 06/28] adding test cases and run
---
.github/workflows/deploy-DEV.yml | 8 +
Dockerfile | 3 +-
lib/linter.sh | 246 +++++++++++++++++++++++++++++++
3 files changed, 256 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 5aac725d..972aa96b 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -52,3 +52,11 @@ jobs:
DOCKERFILE_PATH: Dockerfile
shell: bash
run: .automation/upload-docker.sh
+
+ ################################
+ # Run Linter against code base #
+ ################################
+ - name: Run Test Cases
+ uses: docker://admiralawkbar/super-linter
+ env:
+ TEST_CASE_RUN: true
diff --git a/Dockerfile b/Dockerfile
index 0768e571..40e79a19 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -98,7 +98,8 @@ ENV GITHUB_SHA=${GITHUB_SHA} \
VALIDATE_DOCKER=${VALIDATE_DOCKER} \
VALIDATE_JAVASCRIPT=${VALIDATE_JAVASCRIPT} \
ANSIBLE_DIRECTORY=${ANSIBLE_DIRECTORY} \
- RUN_LOCAL=${RUN_LOCAL}
+ RUN_LOCAL=${RUN_LOCAL} \
+ TEST_CASE_RUN=${TEST_CASE_RUN}
#############################
# Copy scripts to container #
diff --git a/lib/linter.sh b/lib/linter.sh
index 0308dbd4..b2b3f7e7 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -64,6 +64,7 @@ VALIDATE_COFFEE="${VALIDATE_COFFEE}" # Boolean to validate language
VALIDATE_ANSIBLE="${VALIDATE_ANSIBLE}" # Boolean to validate language
VALIDATE_JAVASCRIPT="${VALIDATE_JAVASCRIPT}" # Boolean to validate language
VALIDATE_DOCKER="${VALIDATE_DOCKER}" # Boolean to validate language
+TEST_CASE_RUN=="${TEST_CASE_RUN}" # Boolean to validate only test cases
##############
# Debug Vars #
@@ -79,11 +80,13 @@ DEFAULT_VALIDATE_LANGUAGE='true' # Default to validate lang
DEFAULT_WORKSPACE='/tmp/lint' # Default workspace if running locally
DEFAULT_ANSIBLE_DIRECTORY="$GITHUB_WORKSPACE/ansible" # Default Ansible Directory
DEFAULT_RUN_LOCAL='false' # Default value for debugging locally
+DEFAULT_TEST_CASE_RUN='false' # Flag to tell code to run only test cases
DEFAULT_VERBOSE_OUTPUT='false' # Default value for debugging output
RAW_FILE_ARRAY=() # Array of all files that were changed
READ_ONLY_CHANGE_FLAG=0 # Flag set to 1 if files changed are not txt or md
TEST_CASE_FOLDER='.automation/test' # Folder for test cases we should always ignore
+
##########################
# Array of changed files #
##########################
@@ -454,6 +457,21 @@ GetGitHubVars()
echo "--------------------------------------------"
echo "Gathering GitHub information..."
+ ###############################
+ # Get the Run test cases flag #
+ ###############################
+ if [ -z "$TEST_CASE_RUN" ]; then
+ ##################################
+ # No flag passed, set to default #
+ ##################################
+ TEST_CASE_RUN="$DEFAULT_TEST_CASE_RUN"
+ fi
+
+ ###############################
+ # Convert string to lowercase #
+ ###############################
+ TEST_CASE_RUN=$(echo "$TEST_CASE_RUN" | awk '{print tolower($0)}')
+
##########################
# Get the run local flag #
##########################
@@ -468,6 +486,7 @@ GetGitHubVars()
# Convert string to lowercase #
###############################
RUN_LOCAL=$(echo "$RUN_LOCAL" | awk '{print tolower($0)}')
+
#################################
# Check if were running locally #
#################################
@@ -1212,6 +1231,177 @@ LintCodebase()
done
}
################################################################################
+#### Function TestCodebase #####################################################
+TestCodebase()
+{
+ ####################
+ # Pull in the vars #
+ ####################
+ FILE_TYPE="$1" # Pull the variable and remove from array path (Example: JSON)
+ LINTER_NAME="$2" # Pull the variable and remove from array path (Example: jsonlint)
+ LINTER_COMMAND="$3" # Pull the variable and remove from array path (Example: jsonlint -c ConfigFile /path/to/file)
+ FILE_EXTENSIONS="$4" # Pull the variable and remove from array path (Example: *.json)
+
+ ################
+ # print header #
+ ################
+ echo ""
+ echo "----------------------------------------------"
+ echo "----------------------------------------------"
+ echo "Testing Codebase [$FILE_TYPE] files..."
+ echo "----------------------------------------------"
+ echo "----------------------------------------------"
+ echo ""
+
+ #####################################
+ # Validate we have linter installed #
+ #####################################
+ # shellcheck disable=SC2230
+ VALIDATE_INSTALL_CMD=$(command -v "$LINTER_NAME" 2>&1)
+
+ #######################
+ # Load the error code #
+ #######################
+ ERROR_CODE=$?
+
+ ##############################
+ # Check the shell for errors #
+ ##############################
+ if [ $ERROR_CODE -ne 0 ]; then
+ # Failed
+ echo "ERROR! Failed to find [$LINTER_NAME] in system!"
+ echo "ERROR:[$VALIDATE_INSTALL_CMD]"
+ exit 1
+ else
+ # Success
+ echo "Successfully found binary in system"
+ echo "Location:[$VALIDATE_INSTALL_CMD]"
+ fi
+
+ ##########################
+ # Initialize empty Array #
+ ##########################
+ LIST_FILES=()
+
+ ############################################
+ # Check if its ansible, as its the outlier #
+ ############################################
+ if [[ "$FILE_TYPE" == "ANSIBLE" ]]; then
+ #################################
+ # Get list of all files to lint #
+ #################################
+ # shellcheck disable=SC2207,SC2086
+ LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; ls ansible/ | grep ".yml" 2>&1))
+ else
+ #################################
+ # Get list of all files to lint #
+ #################################
+ # shellcheck disable=SC2207,SC2086
+ LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; find . -type f -regex "$FILE_EXTENSIONS" ! -path "*./ansible*" 2>&1))
+ fi
+
+ ##################
+ # Lint the files #
+ ##################
+ for FILE in "${LIST_FILES[@]}"
+ do
+ #####################
+ # Get the file name #
+ #####################
+ FILE_NAME=$(basename "$FILE" 2>&1)
+
+ ############################
+ # Get the file pass status #
+ ############################
+ # Example: markdown_good_1.md -> good
+ FILE_STATUS=$(echo "$FILE_NAME" |cut -f2 -d'_')
+
+ ##############
+ # File print #
+ ##############
+ echo "---------------------------"
+ echo "File:[$FILE]"
+
+ ########################
+ # Set the lint command #
+ ########################
+ LINT_CMD=''
+
+ #####################
+ # Check for ansible #
+ #####################
+ if [[ "$FILE_TYPE" == "ANSIBLE" ]]; then
+ ########################################
+ # Make sure we dont lint certain files #
+ ########################################
+ if [[ $FILE == *"vault.yml"* ]] || [[ $FILE == *"galaxy.yml"* ]]; then
+ # This is a file we dont look at
+ continue
+ fi
+
+ ################################
+ # Lint the file with the rules #
+ ################################
+ LINT_CMD=$(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER/ansible" || exit; $LINTER_COMMAND "$FILE" 2>&1)
+ else
+ ################################
+ # Lint the file with the rules #
+ ################################
+ LINT_CMD=$(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; $LINTER_COMMAND "$FILE" 2>&1)
+ fi
+
+ #######################
+ # Load the error code #
+ #######################
+ ERROR_CODE=$?
+
+ ########################################
+ # Check for if it was supposed to pass #
+ ########################################
+ if [[ "$FILE_STATUS" == "good" ]]; then
+ ##############################
+ # Check the shell for errors #
+ ##############################
+ if [ $ERROR_CODE -ne 0 ]; then
+ #########
+ # Error #
+ #########
+ echo "ERROR! Found errors in [$LINTER_NAME] linter!"
+ echo "ERROR:[$LINT_CMD]"
+ # Increment the error count
+ (("ERRORS_FOUND_$FILE_TYPE++"))
+ else
+ ###########
+ # Success #
+ ###########
+ echo " - File:[$FILE_NAME] was linted with [$LINTER_NAME] successfully"
+ fi
+ else
+ #######################################
+ # File status = bad, this should fail #
+ #######################################
+ ##############################
+ # Check the shell for errors #
+ ##############################
+ if [ $ERROR_CODE -eq 0 ]; then
+ #########
+ # Error #
+ #########
+ echo "ERROR! Found errors in [$LINTER_NAME] linter!"
+ echo "ERROR! This file should have failed test case!"
+ echo "ERROR:[$LINT_CMD]"
+ # Increment the error count
+ (("ERRORS_FOUND_$FILE_TYPE++"))
+ else
+ ###########
+ # Success #
+ ###########
+ echo " - File:[$FILE_NAME] failed test case with [$LINTER_NAME] successfully"
+ fi
+ fi
+ done
+}
+################################################################################
#### Function Footer ###########################################################
Footer()
{
@@ -1262,6 +1452,51 @@ Footer()
fi
}
################################################################################
+#### Function RunTestCases #####################################################
+RunTestCases()
+{
+ # This loop will run the test cases and exclude user code
+ # This is called from the automation process to validate new code
+ # When a PR is opened, the new code is validated with the master branch
+ # version of linter.sh, and a new container is built with the latest codebase
+ # for testing. That container is spun up, and ran,
+ # with the flag: TEST_CASE_RUN=true
+ # So that the new code can be validated againt the test cases
+
+ #################
+ # Header prints #
+ #################
+ echo ""
+ echo "----------------------------------------------"
+ echo "-------------- TEST CASE RUN -----------------"
+ echo "----------------------------------------------"
+ echo ""
+
+ #######################
+ # Test case languages #
+ #######################
+ TestCodebase "YML" "yamllint" "yamllint -c $YAML_LINTER_RULES" ".*\.\(yml\|yaml\)\$"
+ TestCodebase "JSON" "jsonlint" "jsonlint" ".*\.\(json\)\$"
+ TestCodebase "XML" "xmllint" "xmllint" ".*\.\(xml\)\$"
+ TestCodebase "MARKDOWN" "markdownlint" "markdownlint -c $MD_LINTER_RULES" ".*\.\(md\)\$"
+ TestCodebase "BASH" "shellcheck" "shellcheck" ".*\.\(sh\)\$"
+ TestCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES -E" ".*\.\(py\)\$"
+ TestCodebase "PERL" "perl" "perl -Mstrict -cw" ".*\.\(pl\)\$"
+ TestCodebase "RUBY" "rubocop" "rubocop -c $RUBY_LINTER_RULES" ".*\.\(rb\)\$"
+ TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEE_LINTER_RULES" ".*\.\(coffee\)\$"
+ TestCodebase "ESLINT" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$"
+ TestCodebase "STANDARD" "standard" "standard $STANDARD_LINTER_RULES" ".*\.\(js\)\$"
+ TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint" ".*\(Dockerfile\)\$"
+ TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" "ansible-lint"
+
+ #################
+ # Footer prints #
+ #################
+ # Call the footer to display run information
+ # and exit with error code
+ Footer
+}
+################################################################################
############################### MAIN ###########################################
################################################################################
@@ -1307,6 +1542,17 @@ if [[ "$VERBOSE_OUTPUT" != "false" ]]; then
GetLinterVersions
fi
+###########################################
+# Check to see if this is a test case run #
+###########################################
+if [[ "$TEST_CASE_RUN" != "false" ]]; then
+ ###########################
+ # Run only the test cases #
+ ###########################
+ # Code will exit from inside this loop
+ RunTestCases
+fi
+
#############################################
# check flag for validation of all codebase #
#############################################
From 3b4ce6f2345c055f3d75478c449852a74082527a Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 11:56:02 -0600
Subject: [PATCH 07/28] fixed it
---
.automation/test/docker/good/Dockerfile | 2 +-
lib/linter.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.automation/test/docker/good/Dockerfile b/.automation/test/docker/good/Dockerfile
index 07cdfd47..9b15c22e 100644
--- a/.automation/test/docker/good/Dockerfile
+++ b/.automation/test/docker/good/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:latest
+FROM node:10
# Create app directory
RUN mkdir -p /usr/src/app
diff --git a/lib/linter.sh b/lib/linter.sh
index b2b3f7e7..b7323ef4 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -1290,7 +1290,7 @@ TestCodebase()
#################################
# Get list of all files to lint #
#################################
- # shellcheck disable=SC2207,SC2086
+ # shellcheck disable=SC2207,SC2086,SC2010
LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; ls ansible/ | grep ".yml" 2>&1))
else
#################################
From b16ac2ad6e0157e26cf0ed1e3e1c5d41a0edc891 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:01:36 -0600
Subject: [PATCH 08/28] adding fixes
---
.automation/test/javascript/javascript_bad_1.js | 3 ++-
lib/linter.sh | 8 ++++----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/.automation/test/javascript/javascript_bad_1.js b/.automation/test/javascript/javascript_bad_1.js
index d79300ed..0ed075fc 100644
--- a/.automation/test/javascript/javascript_bad_1.js
+++ b/.automation/test/javascript/javascript_bad_1.js
@@ -4,6 +4,7 @@ var createHandler = require( 'github-webhook-handler')
var handler = createHandler( { path : /webhook, secret : (process.env.SECRET) })
var userArray = [ 'user1' ]
+here is some garbage = that
var teamDescription = Team of Robots
var teamPrivacy = 'closed' // closed (visibile) / secret (hidden) are options here
@@ -28,7 +29,7 @@ http.createServer(function (req, res) {
}).listen(3000)
handler.on('error', function (err) {
- console.error('Error:', err.message)
+ console.await.error('Error:', err.message)
})
handler.on('repository', function (event) {
diff --git a/lib/linter.sh b/lib/linter.sh
index b7323ef4..d48b741f 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -64,7 +64,7 @@ VALIDATE_COFFEE="${VALIDATE_COFFEE}" # Boolean to validate language
VALIDATE_ANSIBLE="${VALIDATE_ANSIBLE}" # Boolean to validate language
VALIDATE_JAVASCRIPT="${VALIDATE_JAVASCRIPT}" # Boolean to validate language
VALIDATE_DOCKER="${VALIDATE_DOCKER}" # Boolean to validate language
-TEST_CASE_RUN=="${TEST_CASE_RUN}" # Boolean to validate only test cases
+TEST_CASE_RUN="${TEST_CASE_RUN}" # Boolean to validate only test cases
##############
# Debug Vars #
@@ -113,7 +113,7 @@ ERRORS_FOUND_BASH=0 # Count of errors found
ERRORS_FOUND_PERL=0 # Count of errors found
ERRORS_FOUND_RUBY=0 # Count of errors found
ERRORS_FOUND_PYTHON=0 # Count of errors found
-ERRORS_FOUND_COFFEE=0 # Count of errors found
+ERRORS_FOUND_COFFEESCRIPT=0 # Count of errors found
ERRORS_FOUND_ANSIBLE=0 # Count of errors found
ERRORS_FOUND_STANDARD=0 # Count of errors found
ERRORS_FOUND_ESLINT=0 # Count of errors found
@@ -1418,7 +1418,7 @@ Footer()
echo "ERRORS FOUND in BASH:[$ERRORS_FOUND_BASH]"
echo "ERRORS FOUND in PERL:[$ERRORS_FOUND_PERL]"
echo "ERRORS FOUND in PYTHON:[$ERRORS_FOUND_PYTHON]"
- echo "ERRORS FOUND in COFFEE:[$ERRORS_FOUND_COFFEE]"
+ echo "ERRORS FOUND in COFFEESCRIPT:[$ERRORS_FOUND_COFFEESCRIPT]"
echo "ERRORS FOUND in RUBY:[$ERRORS_FOUND_RUBY]"
echo "ERRORS FOUND in ANSIBLE:[$ERRORS_FOUND_ANSIBLE]"
echo "ERRORS FOUND in JAVASCRIPT(eslint):[$ERRORS_FOUND_ESLINT]"
@@ -1437,7 +1437,7 @@ Footer()
[ $ERRORS_FOUND_BASH -ne 0 ] || \
[ $ERRORS_FOUND_PERL -ne 0 ] || \
[ $ERRORS_FOUND_PYTHON -ne 0 ] || \
- [ $ERRORS_FOUND_COFFEE -ne 0 ] || \
+ [ $ERRORS_FOUND_COFFEESCRIPT -ne 0 ] || \
[ $ERRORS_FOUND_ANSIBLE -ne 0 ] || \
[ $ERRORS_FOUND_ESLINT -ne 0 ] || \
[ $ERRORS_FOUND_STANDARD -ne 0 ] || \
From fd3c1eed1362d6164ecf92ec3c7b335557543c7d Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:20:22 -0600
Subject: [PATCH 09/28] fix arrays
---
.github/linters/.ansible-lint.yml | 51 ---
.github/linters/.coffee-lint.json | 135 -------
.github/linters/.eslintrc.yml | 40 ---
.github/linters/.markdown-lint.yml | 35 --
.github/linters/.python-lint | 542 -----------------------------
.github/linters/.ruby-lint.yml | 184 ----------
.github/linters/.yaml-lint.yml | 59 ----
.github/workflows/deploy-DEV.yml | 2 +-
lib/linter.sh | 39 ++-
9 files changed, 21 insertions(+), 1066 deletions(-)
delete mode 100644 .github/linters/.ansible-lint.yml
delete mode 100644 .github/linters/.coffee-lint.json
delete mode 100644 .github/linters/.eslintrc.yml
delete mode 100644 .github/linters/.markdown-lint.yml
delete mode 100644 .github/linters/.python-lint
delete mode 100644 .github/linters/.ruby-lint.yml
delete mode 100644 .github/linters/.yaml-lint.yml
diff --git a/.github/linters/.ansible-lint.yml b/.github/linters/.ansible-lint.yml
deleted file mode 100644
index 0007c68d..00000000
--- a/.github/linters/.ansible-lint.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-##########################
-##########################
-## Ansible Linter rules ##
-##########################
-##########################
-
-#############################
-# Exclude paths from linter #
-#############################
-#exclude_paths:
-
-########################
-# Make output parsable #
-########################
-parseable: true
-
-#######################
-# Set output to quiet #
-#######################
-quiet: true
-
-#####################
-# Path to rules dir #
-#####################
-#rulesdir:
-
-################
-# Tags to skip #
-################
-skip_list:
- - '602' # Allow compare to empty string
- - '204' # Allow string length greater that 160 chars
- - '301' # False positives for running command shells
- - '303' # Allow git commands for push add, etc...
- - '305' # Allow use of shell when you want
- - '503' # Allow step to run like handler
-
-##################
-# Tags to follow #
-##################
-#tags:
-
-#############
-# Use rules #
-#############
-use_default_rules: true
-
-#################
-# Set verbosity #
-#################
-verbosity: 1
diff --git a/.github/linters/.coffee-lint.json b/.github/linters/.coffee-lint.json
deleted file mode 100644
index 053b20dc..00000000
--- a/.github/linters/.coffee-lint.json
+++ /dev/null
@@ -1,135 +0,0 @@
-{
- "arrow_spacing": {
- "level": "ignore"
- },
- "braces_spacing": {
- "level": "ignore",
- "spaces": 0,
- "empty_object_spaces": 0
- },
- "camel_case_classes": {
- "level": "error"
- },
- "coffeescript_error": {
- "level": "error"
- },
- "colon_assignment_spacing": {
- "level": "ignore",
- "spacing": {
- "left": 0,
- "right": 0
- }
- },
- "cyclomatic_complexity": {
- "level": "ignore",
- "value": 10
- },
- "duplicate_key": {
- "level": "error"
- },
- "empty_constructor_needs_parens": {
- "level": "ignore"
- },
- "ensure_comprehensions": {
- "level": "warn"
- },
- "eol_last": {
- "level": "ignore"
- },
- "indentation": {
- "value": 2,
- "level": "warn"
- },
- "line_endings": {
- "level": "ignore",
- "value": "unix"
- },
- "max_line_length": {
- "value": 80,
- "level": "ignore",
- "limitComments": true
- },
- "missing_fat_arrows": {
- "level": "ignore",
- "is_strict": false
- },
- "newlines_after_classes": {
- "value": 3,
- "level": "ignore"
- },
- "no_backticks": {
- "level": "error"
- },
- "no_debugger": {
- "level": "warn",
- "console": false
- },
- "no_empty_functions": {
- "level": "ignore"
- },
- "no_empty_param_list": {
- "level": "ignore"
- },
- "no_implicit_braces": {
- "level": "ignore",
- "strict": true
- },
- "no_implicit_parens": {
- "level": "ignore",
- "strict": true
- },
- "no_interpolation_in_single_quotes": {
- "level": "ignore"
- },
- "no_nested_string_interpolation": {
- "level": "warn"
- },
- "no_plusplus": {
- "level": "ignore"
- },
- "no_private_function_fat_arrows": {
- "level": "warn"
- },
- "no_stand_alone_at": {
- "level": "ignore"
- },
- "no_tabs": {
- "level": "error"
- },
- "no_this": {
- "level": "ignore"
- },
- "no_throwing_strings": {
- "level": "error"
- },
- "no_trailing_semicolons": {
- "level": "error"
- },
- "no_trailing_whitespace": {
- "level": "ignore",
- "allowed_in_comments": false,
- "allowed_in_empty_lines": true
- },
- "no_unnecessary_double_quotes": {
- "level": "ignore"
- },
- "no_unnecessary_fat_arrows": {
- "level": "warn"
- },
- "non_empty_constructor_needs_parens": {
- "level": "ignore"
- },
- "prefer_english_operator": {
- "level": "ignore",
- "doubleNotLevel": "ignore"
- },
- "space_operators": {
- "level": "ignore"
- },
- "spacing_after_comma": {
- "level": "ignore"
- },
- "transform_messes_up_line_numbers": {
- "level": "warn"
- }
-}
diff --git a/.github/linters/.eslintrc.yml b/.github/linters/.eslintrc.yml
deleted file mode 100644
index 2bc8d6ee..00000000
--- a/.github/linters/.eslintrc.yml
+++ /dev/null
@@ -1,40 +0,0 @@
----
-
-#############################
-#############################
-## JavaScript Linter rules ##
-#############################
-#############################
-
-############
-# Env Vars #
-############
-env:
- browser: true
- es6: true
- jest: true
-
-###############
-# Global Vars #
-###############
-globals:
- Atomics: readonly
- SharedArrayBuffer: readonly
-
-###############
-# Parser vars #
-###############
-parser: '@typescript-eslint/parser'
-parserOptions:
- ecmaVersion: 2018
-
-###########
-# Plugins #
-###########
-plugins:
- - '@typescript-eslint'
-
-#########
-# Rules #
-#########
-rules: {}
diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml
deleted file mode 100644
index f2dec62f..00000000
--- a/.github/linters/.markdown-lint.yml
+++ /dev/null
@@ -1,35 +0,0 @@
----
-###########################
-###########################
-## Markdown Linter rules ##
-###########################
-###########################
-
-# Linter rules doc:
-# - https://github.com/DavidAnson/markdownlint
-#
-# Note:
-# To comment out a single error:
-#
-# any violations you want
-#
-#
-
-###############
-# Rules by id #
-###############
-MD004: false # Unordered list style
-MD007:
- indent: 2 # Unordered list indentation
-MD013:
- line_length: 808 # Line length
-MD026:
- punctuation: ".,;:!。,;:" # List of not allowed
-MD029: false # Ordered list item prefix
-MD033: false # Allow inline HTML
-MD036: false # Emphasis used instead of a heading
-
-#################
-# Rules by tags #
-#################
-blank_lines: false # Error on blank lines
diff --git a/.github/linters/.python-lint b/.github/linters/.python-lint
deleted file mode 100644
index 8e9cc00e..00000000
--- a/.github/linters/.python-lint
+++ /dev/null
@@ -1,542 +0,0 @@
-[MASTER]
-
-# A comma-separated list of package or module names from where C extensions may
-# be loaded. Extensions are loading into the active Python interpreter and may
-# run arbitrary code
-extension-pkg-whitelist=
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=CVS
-
-# Add files or directories matching the regex patterns to the blacklist. The
-# regex matches against base names, not paths.
-ignore-patterns=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Use multiple processes to speed up Pylint.
-jobs=1
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-# Pickle collected data for later comparisons.
-persistent=yes
-
-# Specify a configuration file.
-#rcfile=
-
-# When enabled, pylint would attempt to guess common misconfiguration and emit
-# user-friendly hints instead of false-positive error messages
-suggestion-mode=yes
-
-# Allow loading of arbitrary C extensions. Extensions are imported into the
-# active Python interpreter and may run arbitrary code.
-unsafe-load-any-extension=no
-
-
-[MESSAGES CONTROL]
-
-# Only show warnings with the listed confidence levels. Leave empty to show
-# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
-confidence=
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifiers separated by comma (,) or put this
-# option multiple times (only on the command line, not in the configuration
-# file where it should appear only once).You can also use "--disable=all" to
-# disable everything first and then reenable specific checks. For example, if
-# you want to run only the similarities checker, you can use "--disable=all
-# --enable=similarities". If you want to run only the classes checker, but have
-# no Warning level messages displayed, use"--disable=all --enable=classes
-# --disable=W"
-disable=print-statement,
- parameter-unpacking,
- unpacking-in-except,
- old-raise-syntax,
- backtick,
- long-suffix,
- old-ne-operator,
- old-octal-literal,
- import-star-module-level,
- non-ascii-bytes-literal,
- raw-checker-failed,
- bad-inline-option,
- locally-disabled,
- locally-enabled,
- file-ignored,
- suppressed-message,
- useless-suppression,
- deprecated-pragma,
- apply-builtin,
- basestring-builtin,
- buffer-builtin,
- cmp-builtin,
- coerce-builtin,
- execfile-builtin,
- file-builtin,
- long-builtin,
- raw_input-builtin,
- reduce-builtin,
- standarderror-builtin,
- unicode-builtin,
- xrange-builtin,
- coerce-method,
- delslice-method,
- getslice-method,
- setslice-method,
- no-absolute-import,
- old-division,
- dict-iter-method,
- dict-view-method,
- next-method-called,
- metaclass-assignment,
- indexing-exception,
- raising-string,
- reload-builtin,
- oct-method,
- hex-method,
- nonzero-method,
- cmp-method,
- input-builtin,
- round-builtin,
- intern-builtin,
- unichr-builtin,
- map-builtin-not-iterating,
- zip-builtin-not-iterating,
- range-builtin-not-iterating,
- filter-builtin-not-iterating,
- using-cmp-argument,
- eq-without-hash,
- div-method,
- idiv-method,
- rdiv-method,
- exception-message-attribute,
- invalid-str-codec,
- sys-max-int,
- bad-python3-import,
- deprecated-string-function,
- deprecated-str-translate-call,
- deprecated-itertools-function,
- deprecated-types-field,
- next-method-defined,
- dict-items-not-iterating,
- dict-keys-not-iterating,
- dict-values-not-iterating
-
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time (only on the command line, not in the configuration file where
-# it should appear only once). See also the "--disable" option for examples.
-enable=c-extension-no-member
-
-
-[REPORTS]
-
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Template used to display messages. This is a python new-style format string
-# used to format the message information. See doc for all details
-#msg-template=
-
-# Set the output format. Available formats are text, parseable, colorized, json
-# and msvs (visual studio).You can also give a reporter class, eg
-# mypackage.mymodule.MyReporterClass.
-output-format=text
-
-# Tells whether to display a full report or only the messages
-reports=no
-
-# Activate the evaluation score.
-score=yes
-
-
-[REFACTORING]
-
-# Maximum number of nested blocks for function / method body
-max-nested-blocks=5
-
-# Complete name of functions that never returns. When checking for
-# inconsistent-return-statements if a never returning function is called then
-# it will be considered as an explicit return statement and no message will be
-# printed.
-never-returning-functions=optparse.Values,sys.exit
-
-
-[VARIABLES]
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-# Tells whether unused global variables should be treated as a violation.
-allow-global-unused-variables=yes
-
-# List of strings which can identify a callback function by name. A callback
-# name must start or end with one of those strings.
-callbacks=cb_,
- _cb
-
-# A regular expression matching the name of dummy variables (i.e. expectedly
-# not used).
-dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore
-ignored-argument-names=_.*|^ignored_|^unused_
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# List of qualified module names which can have objects that can redefine
-# builtins.
-redefining-builtins-modules=six.moves,past.builtins,future.builtins
-
-
-[LOGGING]
-
-# Logging modules to check that the string format arguments are in logging
-# function parameter format
-logging-modules=logging
-
-
-[TYPECHECK]
-
-# List of decorators that produce context managers, such as
-# contextlib.contextmanager. Add to this list to register other decorators that
-# produce valid context managers.
-contextmanager-decorators=contextlib.contextmanager
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E1101 when accessed. Python regular
-# expressions are accepted.
-generated-members=
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# This flag controls whether pylint should warn about no-member and similar
-# checks whenever an opaque object is returned when inferring. The inference
-# can return multiple potential results while evaluating a Python object, but
-# some branches might not be evaluated, which results in partial inference. In
-# that case, it might be useful to still emit no-member and other checks for
-# the rest of the inferred objects.
-ignore-on-opaque-inference=yes
-
-# List of class names for which member attributes should not be checked (useful
-# for classes with dynamically set attributes). This supports the use of
-# qualified names.
-ignored-classes=optparse.Values,thread._local,_thread._local
-
-# List of module names for which member attributes should not be checked
-# (useful for modules/projects where namespaces are manipulated during runtime
-# and thus existing member attributes cannot be deduced by static analysis. It
-# supports qualified module names, as well as Unix pattern matching.
-ignored-modules=
-
-# Show a hint with possible names when a member name was not found. The aspect
-# of finding the hint is based on edit distance.
-missing-member-hint=yes
-
-# The minimum edit distance a name should have in order to be considered a
-# similar match for a missing member name.
-missing-member-hint-distance=1
-
-# The total number of similar names that should be taken in consideration when
-# showing a hint for a missing member.
-missing-member-max-choices=1
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,
- XXX,
- TODO
-
-
-[BASIC]
-
-# Naming style matching correct argument names
-argument-naming-style=snake_case
-
-# Regular expression matching correct argument names. Overrides argument-
-# naming-style
-#argument-rgx=
-
-# Naming style matching correct attribute names
-attr-naming-style=snake_case
-
-# Regular expression matching correct attribute names. Overrides attr-naming-
-# style
-#attr-rgx=
-
-# Bad variable names which should always be refused, separated by a comma
-bad-names=foo,
- bar,
- baz,
- toto,
- tutu,
- tata
-
-# Naming style matching correct class attribute names
-class-attribute-naming-style=any
-
-# Regular expression matching correct class attribute names. Overrides class-
-# attribute-naming-style
-#class-attribute-rgx=
-
-# Naming style matching correct class names
-class-naming-style=PascalCase
-
-# Regular expression matching correct class names. Overrides class-naming-style
-#class-rgx=
-
-# Naming style matching correct constant names
-const-naming-style=UPPER_CASE
-
-# Regular expression matching correct constant names. Overrides const-naming-
-# style
-#const-rgx=
-
-# Minimum line length for functions/classes that require docstrings, shorter
-# ones are exempt.
-docstring-min-length=-1
-
-# Naming style matching correct function names
-function-naming-style=snake_case
-
-# Regular expression matching correct function names. Overrides function-
-# naming-style
-#function-rgx=
-
-# Good variable names which should always be accepted, separated by a comma
-good-names=i,
- j,
- k,
- ex,
- Run,
- _
-
-# Include a hint for the correct naming format with invalid-name
-include-naming-hint=no
-
-# Naming style matching correct inline iteration names
-inlinevar-naming-style=any
-
-# Regular expression matching correct inline iteration names. Overrides
-# inlinevar-naming-style
-#inlinevar-rgx=
-
-# Naming style matching correct method names
-method-naming-style=snake_case
-
-# Regular expression matching correct method names. Overrides method-naming-
-# style
-#method-rgx=
-
-# Naming style matching correct module names
-module-naming-style=snake_case
-
-# Regular expression matching correct module names. Overrides module-naming-
-# style
-#module-rgx=
-
-# Colon-delimited sets of names that determine each other's naming style when
-# the name regexes allow several styles.
-name-group=
-
-# Regular expression which should only match function or class names that do
-# not require a docstring.
-no-docstring-rgx=^_
-
-# List of decorators that produce properties, such as abc.abstractproperty. Add
-# to this list to register other decorators that produce valid properties.
-property-classes=abc.abstractproperty
-
-# Naming style matching correct variable names
-variable-naming-style=snake_case
-
-# Regular expression matching correct variable names. Overrides variable-
-# naming-style
-#variable-rgx=
-
-
-[SPELLING]
-
-# Limits count of emitted suggestions for spelling mistakes
-max-spelling-suggestions=4
-
-# Spelling dictionary name. Available dictionaries: none. To make it working
-# install python-enchant package.
-spelling-dict=
-
-# List of comma separated words that should not be checked.
-spelling-ignore-words=
-
-# A path to a file that contains private dictionary; one word per line.
-spelling-private-dict-file=
-
-# Tells whether to store unknown words to indicated private dictionary in
-# --spelling-private-dict-file option instead of raising a message.
-spelling-store-unknown-words=no
-
-
-[FORMAT]
-
-# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
-expected-line-ending-format=
-
-# Regexp for a line that is allowed to be longer than the limit.
-ignore-long-lines=^\s*(# )??$
-
-# Number of spaces of indent required inside a hanging or continued line.
-indent-after-paren=4
-
-# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
-# tab).
-indent-string=' '
-
-# Maximum number of characters on a single line.
-max-line-length=100
-
-# Maximum number of lines in a module
-max-module-lines=1000
-
-# List of optional constructs for which whitespace checking is disabled. `dict-
-# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
-# `trailing-comma` allows a space between comma and closing bracket: (a, ).
-# `empty-line` allows space-only lines.
-no-space-check=trailing-comma,
- dict-separator
-
-# Allow the body of a class to be on the same line as the declaration if body
-# contains single statement.
-single-line-class-stmt=no
-
-# Allow the body of an if to be on the same line as the test if there is no
-# else.
-single-line-if-stmt=no
-
-
-[SIMILARITIES]
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-# Ignore imports when computing similarities.
-ignore-imports=no
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-
-[DESIGN]
-
-# Maximum number of arguments for function / method
-max-args=5
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=7
-
-# Maximum number of boolean expressions in a if statement
-max-bool-expr=5
-
-# Maximum number of branch for function / method body
-max-branches=12
-
-# Maximum number of locals for function / method body
-max-locals=15
-
-# Maximum number of parents for a class (see R0901).
-max-parents=7
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=20
-
-# Maximum number of return / yield for function / method body
-max-returns=6
-
-# Maximum number of statements in function / method body
-max-statements=50
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=2
-
-
-[IMPORTS]
-
-# Allow wildcard imports from modules that define __all__.
-allow-wildcard-with-all=no
-
-# Analyse import fallback blocks. This can be used to support both Python 2 and
-# 3 compatible code, which means that the block might have code that exists
-# only in one or another interpreter, leading to false positives when analysed.
-analyse-fallback-blocks=no
-
-# Deprecated modules which should not be used, separated by a comma
-deprecated-modules=regsub,
- TERMIOS,
- Bastion,
- rexec
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled)
-ext-import-graph=
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled)
-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled)
-int-import-graph=
-
-# Force import order to recognize a module as part of the standard
-# compatibility libraries.
-known-standard-library=
-
-# Force import order to recognize a module as part of a third party library.
-known-third-party=enchant
-
-
-[CLASSES]
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,
- __new__,
- setUp
-
-# List of member names, which should be excluded from the protected access
-# warning.
-exclude-protected=_asdict,
- _fields,
- _replace,
- _source,
- _make
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-# List of valid names for the first argument in a metaclass class method.
-valid-metaclass-classmethod-first-arg=mcs
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception"
-overgeneral-exceptions=Exception
diff --git a/.github/linters/.ruby-lint.yml b/.github/linters/.ruby-lint.yml
deleted file mode 100644
index c70ad84d..00000000
--- a/.github/linters/.ruby-lint.yml
+++ /dev/null
@@ -1,184 +0,0 @@
----
-#######################
-# Rubocop Config file #
-#######################
-
-################################################################################
-############################## Rails Rules #####################################
-################################################################################
-
-# Set the linter to enable rails rules
-Rails:
- Enabled: true
-
-################################################################################
-############################# Security Rules ###################################
-################################################################################
-
-# Security rules
-Security/Open:
- Enabled: false
-################################################################################
-############################# Metrics Rules ####################################
-################################################################################
-
-# Commonly used screens these days easily fit more than 80 characters.
-Metrics/LineLength:
- Max: 120
-
-# Too short methods lead to extraction of single-use methods, which can make
-# the code easier to read (by naming things), but can also clutter the class
-Metrics/MethodLength:
- Max: 30
-
-# The guiding principle of classes is SRP,
-# SRP can't be accurately measured by LoC
-Metrics/ClassLength:
- Max: 1500
-
-# Turn off the Assignment Branch Condition size for the case of these scripts
-Metrics/AbcSize:
- Enabled: false
-
-# Set the complexity of the metrics
-Metrics/PerceivedComplexity:
- Max: 10
-
-# Set the complexity of the cyle
-Metrics/CyclomaticComplexity:
- Max: 10
-
-################################################################################
-########################## Layout Rules ########################################
-################################################################################
-
-# No space makes the method definition shorter and differentiates
-# from a regular assignment.
-Layout/SpaceAroundEqualsInParameterDefault:
- EnforcedStyle: no_space
-
-# Indenting the chained dots beneath each other is not supported by this cop,
-# see https://github.com/bbatsov/rubocop/issues/1633
-Layout/MultilineOperationIndentation:
- Enabled: false
-
-Layout/SpaceInsideBlockBraces:
- # The space here provides no real gain in readability while consuming
- # horizontal space that could be used for a better parameter name.
- # Also {| differentiates better from a hash than { | does.
- SpaceBeforeBlockParameters: false
-
-# No trailing space differentiates better from the block:
-# foo} means hash, foo } means block.
-Layout/SpaceInsideHashLiteralBraces:
- EnforcedStyle: no_space
-
-################################################################################
-########################### Style Rules ########################################
-################################################################################
-
-# Single quotes being faster is hardly measurable and only affects parse time.
-# Enforcing double quotes reduces the times where you need to change them
-# when introducing an interpolation. Use single quotes only if their semantics
-# are needed.
-Style/StringLiterals:
- EnforcedStyle: double_quotes
-
-# We do not need to support Ruby 1.9, so this is good to use.
-Style/SymbolArray:
- Enabled: true
-
-# Mixing the styles looks just silly.
-Style/HashSyntax:
- EnforcedStyle: ruby19_no_mixed_keys
-
-# has_key? and has_value? are far more readable than key? and value?
-Style/PreferredHashMethods:
- Enabled: false
-
-# String#% is by far the least verbose and only object oriented variant.
-Style/FormatString:
- EnforcedStyle: percent
-
-Style/CollectionMethods:
- Enabled: true
- PreferredMethods:
- # inject seems more common in the community.
- reduce: "inject"
-
-# Either allow this style or don't. Marking it as safe with parenthesis
-# is silly. Let's try to live without them for now.
-Style/ParenthesesAroundCondition:
- AllowSafeAssignment: false
-
-# A specialized exception class will take one or more arguments
-# and construct the message from it. So both variants make sense.
-Style/RaiseArgs:
- Enabled: false
-
-# Fail is an alias of raise. Avoid aliases,
-# it's more cognitive load for no gain. The argument that fail
-# should be used to abort the program is wrong too,
-# there's Kernel#abort for that.
-Style/SignalException:
- EnforcedStyle: only_raise
-
-# { ... } for multi-line blocks is okay, follow Weirichs rule instead:
-# https://web.archive.org/web/20140221124509/http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc
-Style/BlockDelimiters:
- Enabled: false
-
-# do / end blocks should be used for side effects,
-# methods that run a block for side effects and have
-# a useful return value are rare, assign the return
-# value to a local variable for those cases.
-Style/MethodCalledOnDoEndBlock:
- Enabled: true
-
-# Enforcing the names of variables? To single letter ones? Just no.
-Style/SingleLineBlockParams:
- Enabled: false
-
-# Check with yard instead.
-Style/Documentation:
- Enabled: false
-
-# Style preference
-Style/MethodDefParentheses:
- Enabled: false
-
-################################################################################
-########################### Linter Rules #######################################
-################################################################################
-
-# There are valid cases, for example debugging Cucumber steps,
-# also they'll fail CI anyway
-Lint/Debugger:
- Enabled: false
-
-# Shadowing outer local variables with block parameters is often useful
-# to not reinvent a new name for the same thing, it highlights the relation
-# between the outer variable and the parameter. The cases where it's actually
-# confusing are rare, and usually bad for other reasons already, for example
-# because the method is too long.
-Lint/ShadowingOuterLocalVariable:
- Enabled: false
-
-# Suppressing exceptions can be perfectly fine, and be it to avoid to
-# explicitly type nil into the rescue since that's what you want to return,
-# or suppressing LoadError for optional dependencies
-Lint/HandleExceptions:
- Enabled: false
-
-Lint/AssignmentInCondition:
- AllowSafeAssignment: false
-
-################################################################################
-############################ Naming Rules ######################################
-################################################################################
-
-# This is just silly. Calling the argument `other` in all cases makes no sense.
-Naming/BinaryOperatorParameterName:
- Enabled: false
-
-################################################################################
diff --git a/.github/linters/.yaml-lint.yml b/.github/linters/.yaml-lint.yml
deleted file mode 100644
index faccea80..00000000
--- a/.github/linters/.yaml-lint.yml
+++ /dev/null
@@ -1,59 +0,0 @@
----
-###########################################
-# These are the rules used for #
-# linting all the yaml files in the stack #
-# NOTE: #
-# You can disble line with: #
-# # yamllint disable-line #
-###########################################
-rules:
- braces:
- level: warning
- min-spaces-inside: 0
- max-spaces-inside: 0
- min-spaces-inside-empty: 1
- max-spaces-inside-empty: 5
- brackets:
- level: warning
- min-spaces-inside: 0
- max-spaces-inside: 0
- min-spaces-inside-empty: 1
- max-spaces-inside-empty: 5
- colons:
- level: warning
- max-spaces-before: 0
- max-spaces-after: 1
- commas:
- level: warning
- max-spaces-before: 0
- min-spaces-after: 1
- max-spaces-after: 1
- comments: disable
- comments-indentation: disable
- document-end: disable
- document-start:
- level: warning
- present: true
- empty-lines:
- level: warning
- max: 2
- max-start: 0
- max-end: 0
- hyphens:
- level: warning
- max-spaces-after: 1
- indentation:
- level: warning
- spaces: consistent
- indent-sequences: true
- check-multi-line-strings: false
- key-duplicates: enable
- line-length:
- level: warning
- max: 80
- allow-non-breakable-words: true
- allow-non-breakable-inline-mappings: true
- new-line-at-end-of-file: disable
- new-lines:
- type: unix
- trailing-spaces: disable
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 972aa96b..9df7eaa9 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -57,6 +57,6 @@ jobs:
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter
+ uses: docker://admiralawkbar/super-linter:${{ github.ref }}
env:
TEST_CASE_RUN: true
diff --git a/lib/linter.sh b/lib/linter.sh
index d48b741f..af14800a 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -24,8 +24,8 @@ PYTHON_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PYTHON_FILE_NAME" # Path to th
RUBY_FILE_NAME='.ruby-lint.yml' # Name of the file
RUBY_LINTER_RULES="$DEFAULT_RULES_LOCATION/$RUBY_FILE_NAME" # Path to the ruby lint rules
# Coffee Vars
-COFFEE_FILE_NAME='.coffee-lint.json' # Name of the file
-COFFEE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$COFFEE_FILE_NAME" # Path to the coffescript lint rules
+COFFEE_FILE_NAME='.coffee-lint.json' # Name of the file
+COFFEESCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$COFFEE_FILE_NAME" # Path to the coffescript lint rules
# Javascript Vars
JAVASCRIPT_FILE_NAME='.eslintrc.yml' # Name of the file
JAVASCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$JAVASCRIPT_FILE_NAME" # Path to the Javascript lint rules
@@ -90,17 +90,18 @@ TEST_CASE_FOLDER='.automation/test' # Folder for test cases we
##########################
# Array of changed files #
##########################
-FILE_ARRAY_YML=() # Array of files to check
-FILE_ARRAY_JSON=() # Array of files to check
-FILE_ARRAY_XML=() # Array of files to check
-FILE_ARRAY_MD=() # Array of files to check
-FILE_ARRAY_BASH=() # Array of files to check
-FILE_ARRAY_PERL=() # Array of files to check
-FILE_ARRAY_RUBY=() # Array of files to check
-FILE_ARRAY_PYTHON=() # Array of files to check
-FILE_ARRAY_COFFEE=() # Array of files to check
-FILE_ARRAY_JAVASCRIPT=() # Array of files to check
-FILE_ARRAY_DOCKER=() # Array of files to check
+FILE_ARRAY_YML=() # Array of files to check
+FILE_ARRAY_JSON=() # Array of files to check
+FILE_ARRAY_XML=() # Array of files to check
+FILE_ARRAY_MD=() # Array of files to check
+FILE_ARRAY_BASH=() # Array of files to check
+FILE_ARRAY_PERL=() # Array of files to check
+FILE_ARRAY_RUBY=() # Array of files to check
+FILE_ARRAY_PYTHON=() # Array of files to check
+FILE_ARRAY_COFFEESCRIPT=() # Array of files to check
+FILE_ARRAY_ESLINT=() # Array of files to check
+FILE_ARRAY_STANDARD=() # Array of files to check
+FILE_ARRAY_DOCKER=() # Array of files to check
############
# Counters #
@@ -1038,7 +1039,7 @@ BuildFileList()
################################
# Append the file to the array #
################################
- FILE_ARRAY_COFFEE+=("$FILE")
+ FILE_ARRAY_COFFEESCRIPT+=("$FILE")
##########################################################
# Set the READ_ONLY_CHANGE_FLAG since this could be exec #
##########################################################
@@ -1483,7 +1484,7 @@ RunTestCases()
TestCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES -E" ".*\.\(py\)\$"
TestCodebase "PERL" "perl" "perl -Mstrict -cw" ".*\.\(pl\)\$"
TestCodebase "RUBY" "rubocop" "rubocop -c $RUBY_LINTER_RULES" ".*\.\(rb\)\$"
- TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEE_LINTER_RULES" ".*\.\(coffee\)\$"
+ TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEESCRIPT_LINTER_RULES" ".*\.\(coffee\)\$"
TestCodebase "ESLINT" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$"
TestCodebase "STANDARD" "standard" "standard $STANDARD_LINTER_RULES" ".*\.\(js\)\$"
TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint" ".*\(Dockerfile\)\$"
@@ -1524,7 +1525,7 @@ GetLinterRules "$PYTHON_FILE_NAME" "$PYTHON_LINTER_RULES"
# Get ruby rules
GetLinterRules "$RUBY_FILE_NAME" "$RUBY_LINTER_RULES"
# Get coffeescript rules
-GetLinterRules "$COFFEE_FILE_NAME" "$COFFEE_LINTER_RULES"
+GetLinterRules "$COFFEE_FILE_NAME" "$COFFEESCRIPT_LINTER_RULES"
# Get ansible rules
GetLinterRules "$ANSIBLE_FILE_NAME" "$ANSIBLE_LINTER_RULES"
# Get javascript rules
@@ -1659,7 +1660,7 @@ if [ "$VALIDATE_COFFEE" == "true" ]; then
# Lint the coffee files #
#########################
# LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY"
- LintCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEE_LINTER_RULES" ".*\.\(coffee\)\$" "${FILE_ARRAY_COFFEE[@]}"
+ LintCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEESCRIPT_LINTER_RULES" ".*\.\(coffee\)\$" "${FILE_ARRAY_COFFEESCRIPT[@]}"
fi
###################
@@ -1688,8 +1689,8 @@ if [ "$VALIDATE_JAVASCRIPT" == "true" ]; then
# Lint the Javascript files #
#############################
# LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY"
- LintCodebase "ESLINT" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$" "${FILE_ARRAY_JAVASCRIPT[@]}"
- LintCodebase "STANDARD" "standard" "standard $STANDARD_LINTER_RULES" ".*\.\(js\)\$" "${FILE_ARRAY_JAVASCRIPT[@]}"
+ LintCodebase "ESLINT" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$" "${FILE_ARRAY_ESLINT[@]}"
+ LintCodebase "STANDARD" "standard" "standard $STANDARD_LINTER_RULES" ".*\.\(js\)\$" "${FILE_ARRAY_STANDARD[@]}"
fi
##################
From dfd96949f4d614893a95549f69e5e9a968fb0edd Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:23:01 -0600
Subject: [PATCH 10/28] putting them back
---
.github/linters/.ansible-lint.yml | 51 +++
.github/linters/.coffee-lint.json | 135 +++++++
.github/linters/.eslintrc.yml | 40 +++
.github/linters/.markdown-lint.yml | 35 ++
.github/linters/.python-lint | 542 +++++++++++++++++++++++++++++
.github/linters/.ruby-lint.yml | 184 ++++++++++
.github/linters/.yaml-lint.yml | 59 ++++
7 files changed, 1046 insertions(+)
create mode 100644 .github/linters/.ansible-lint.yml
create mode 100644 .github/linters/.coffee-lint.json
create mode 100644 .github/linters/.eslintrc.yml
create mode 100644 .github/linters/.markdown-lint.yml
create mode 100644 .github/linters/.python-lint
create mode 100644 .github/linters/.ruby-lint.yml
create mode 100644 .github/linters/.yaml-lint.yml
diff --git a/.github/linters/.ansible-lint.yml b/.github/linters/.ansible-lint.yml
new file mode 100644
index 00000000..0007c68d
--- /dev/null
+++ b/.github/linters/.ansible-lint.yml
@@ -0,0 +1,51 @@
+##########################
+##########################
+## Ansible Linter rules ##
+##########################
+##########################
+
+#############################
+# Exclude paths from linter #
+#############################
+#exclude_paths:
+
+########################
+# Make output parsable #
+########################
+parseable: true
+
+#######################
+# Set output to quiet #
+#######################
+quiet: true
+
+#####################
+# Path to rules dir #
+#####################
+#rulesdir:
+
+################
+# Tags to skip #
+################
+skip_list:
+ - '602' # Allow compare to empty string
+ - '204' # Allow string length greater that 160 chars
+ - '301' # False positives for running command shells
+ - '303' # Allow git commands for push add, etc...
+ - '305' # Allow use of shell when you want
+ - '503' # Allow step to run like handler
+
+##################
+# Tags to follow #
+##################
+#tags:
+
+#############
+# Use rules #
+#############
+use_default_rules: true
+
+#################
+# Set verbosity #
+#################
+verbosity: 1
diff --git a/.github/linters/.coffee-lint.json b/.github/linters/.coffee-lint.json
new file mode 100644
index 00000000..053b20dc
--- /dev/null
+++ b/.github/linters/.coffee-lint.json
@@ -0,0 +1,135 @@
+{
+ "arrow_spacing": {
+ "level": "ignore"
+ },
+ "braces_spacing": {
+ "level": "ignore",
+ "spaces": 0,
+ "empty_object_spaces": 0
+ },
+ "camel_case_classes": {
+ "level": "error"
+ },
+ "coffeescript_error": {
+ "level": "error"
+ },
+ "colon_assignment_spacing": {
+ "level": "ignore",
+ "spacing": {
+ "left": 0,
+ "right": 0
+ }
+ },
+ "cyclomatic_complexity": {
+ "level": "ignore",
+ "value": 10
+ },
+ "duplicate_key": {
+ "level": "error"
+ },
+ "empty_constructor_needs_parens": {
+ "level": "ignore"
+ },
+ "ensure_comprehensions": {
+ "level": "warn"
+ },
+ "eol_last": {
+ "level": "ignore"
+ },
+ "indentation": {
+ "value": 2,
+ "level": "warn"
+ },
+ "line_endings": {
+ "level": "ignore",
+ "value": "unix"
+ },
+ "max_line_length": {
+ "value": 80,
+ "level": "ignore",
+ "limitComments": true
+ },
+ "missing_fat_arrows": {
+ "level": "ignore",
+ "is_strict": false
+ },
+ "newlines_after_classes": {
+ "value": 3,
+ "level": "ignore"
+ },
+ "no_backticks": {
+ "level": "error"
+ },
+ "no_debugger": {
+ "level": "warn",
+ "console": false
+ },
+ "no_empty_functions": {
+ "level": "ignore"
+ },
+ "no_empty_param_list": {
+ "level": "ignore"
+ },
+ "no_implicit_braces": {
+ "level": "ignore",
+ "strict": true
+ },
+ "no_implicit_parens": {
+ "level": "ignore",
+ "strict": true
+ },
+ "no_interpolation_in_single_quotes": {
+ "level": "ignore"
+ },
+ "no_nested_string_interpolation": {
+ "level": "warn"
+ },
+ "no_plusplus": {
+ "level": "ignore"
+ },
+ "no_private_function_fat_arrows": {
+ "level": "warn"
+ },
+ "no_stand_alone_at": {
+ "level": "ignore"
+ },
+ "no_tabs": {
+ "level": "error"
+ },
+ "no_this": {
+ "level": "ignore"
+ },
+ "no_throwing_strings": {
+ "level": "error"
+ },
+ "no_trailing_semicolons": {
+ "level": "error"
+ },
+ "no_trailing_whitespace": {
+ "level": "ignore",
+ "allowed_in_comments": false,
+ "allowed_in_empty_lines": true
+ },
+ "no_unnecessary_double_quotes": {
+ "level": "ignore"
+ },
+ "no_unnecessary_fat_arrows": {
+ "level": "warn"
+ },
+ "non_empty_constructor_needs_parens": {
+ "level": "ignore"
+ },
+ "prefer_english_operator": {
+ "level": "ignore",
+ "doubleNotLevel": "ignore"
+ },
+ "space_operators": {
+ "level": "ignore"
+ },
+ "spacing_after_comma": {
+ "level": "ignore"
+ },
+ "transform_messes_up_line_numbers": {
+ "level": "warn"
+ }
+}
diff --git a/.github/linters/.eslintrc.yml b/.github/linters/.eslintrc.yml
new file mode 100644
index 00000000..2bc8d6ee
--- /dev/null
+++ b/.github/linters/.eslintrc.yml
@@ -0,0 +1,40 @@
+---
+
+#############################
+#############################
+## JavaScript Linter rules ##
+#############################
+#############################
+
+############
+# Env Vars #
+############
+env:
+ browser: true
+ es6: true
+ jest: true
+
+###############
+# Global Vars #
+###############
+globals:
+ Atomics: readonly
+ SharedArrayBuffer: readonly
+
+###############
+# Parser vars #
+###############
+parser: '@typescript-eslint/parser'
+parserOptions:
+ ecmaVersion: 2018
+
+###########
+# Plugins #
+###########
+plugins:
+ - '@typescript-eslint'
+
+#########
+# Rules #
+#########
+rules: {}
diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml
new file mode 100644
index 00000000..f2dec62f
--- /dev/null
+++ b/.github/linters/.markdown-lint.yml
@@ -0,0 +1,35 @@
+---
+###########################
+###########################
+## Markdown Linter rules ##
+###########################
+###########################
+
+# Linter rules doc:
+# - https://github.com/DavidAnson/markdownlint
+#
+# Note:
+# To comment out a single error:
+#
+# any violations you want
+#
+#
+
+###############
+# Rules by id #
+###############
+MD004: false # Unordered list style
+MD007:
+ indent: 2 # Unordered list indentation
+MD013:
+ line_length: 808 # Line length
+MD026:
+ punctuation: ".,;:!。,;:" # List of not allowed
+MD029: false # Ordered list item prefix
+MD033: false # Allow inline HTML
+MD036: false # Emphasis used instead of a heading
+
+#################
+# Rules by tags #
+#################
+blank_lines: false # Error on blank lines
diff --git a/.github/linters/.python-lint b/.github/linters/.python-lint
new file mode 100644
index 00000000..8e9cc00e
--- /dev/null
+++ b/.github/linters/.python-lint
@@ -0,0 +1,542 @@
+[MASTER]
+
+# A comma-separated list of package or module names from where C extensions may
+# be loaded. Extensions are loading into the active Python interpreter and may
+# run arbitrary code
+extension-pkg-whitelist=
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=CVS
+
+# Add files or directories matching the regex patterns to the blacklist. The
+# regex matches against base names, not paths.
+ignore-patterns=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Use multiple processes to speed up Pylint.
+jobs=1
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# Specify a configuration file.
+#rcfile=
+
+# When enabled, pylint would attempt to guess common misconfiguration and emit
+# user-friendly hints instead of false-positive error messages
+suggestion-mode=yes
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=no
+
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
+confidence=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+disable=print-statement,
+ parameter-unpacking,
+ unpacking-in-except,
+ old-raise-syntax,
+ backtick,
+ long-suffix,
+ old-ne-operator,
+ old-octal-literal,
+ import-star-module-level,
+ non-ascii-bytes-literal,
+ raw-checker-failed,
+ bad-inline-option,
+ locally-disabled,
+ locally-enabled,
+ file-ignored,
+ suppressed-message,
+ useless-suppression,
+ deprecated-pragma,
+ apply-builtin,
+ basestring-builtin,
+ buffer-builtin,
+ cmp-builtin,
+ coerce-builtin,
+ execfile-builtin,
+ file-builtin,
+ long-builtin,
+ raw_input-builtin,
+ reduce-builtin,
+ standarderror-builtin,
+ unicode-builtin,
+ xrange-builtin,
+ coerce-method,
+ delslice-method,
+ getslice-method,
+ setslice-method,
+ no-absolute-import,
+ old-division,
+ dict-iter-method,
+ dict-view-method,
+ next-method-called,
+ metaclass-assignment,
+ indexing-exception,
+ raising-string,
+ reload-builtin,
+ oct-method,
+ hex-method,
+ nonzero-method,
+ cmp-method,
+ input-builtin,
+ round-builtin,
+ intern-builtin,
+ unichr-builtin,
+ map-builtin-not-iterating,
+ zip-builtin-not-iterating,
+ range-builtin-not-iterating,
+ filter-builtin-not-iterating,
+ using-cmp-argument,
+ eq-without-hash,
+ div-method,
+ idiv-method,
+ rdiv-method,
+ exception-message-attribute,
+ invalid-str-codec,
+ sys-max-int,
+ bad-python3-import,
+ deprecated-string-function,
+ deprecated-str-translate-call,
+ deprecated-itertools-function,
+ deprecated-types-field,
+ next-method-defined,
+ dict-items-not-iterating,
+ dict-keys-not-iterating,
+ dict-values-not-iterating
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once). See also the "--disable" option for examples.
+enable=c-extension-no-member
+
+
+[REPORTS]
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details
+#msg-template=
+
+# Set the output format. Available formats are text, parseable, colorized, json
+# and msvs (visual studio).You can also give a reporter class, eg
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+# Activate the evaluation score.
+score=yes
+
+
+[REFACTORING]
+
+# Maximum number of nested blocks for function / method body
+max-nested-blocks=5
+
+# Complete name of functions that never returns. When checking for
+# inconsistent-return-statements if a never returning function is called then
+# it will be considered as an explicit return statement and no message will be
+# printed.
+never-returning-functions=optparse.Values,sys.exit
+
+
+[VARIABLES]
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+# Tells whether unused global variables should be treated as a violation.
+allow-global-unused-variables=yes
+
+# List of strings which can identify a callback function by name. A callback
+# name must start or end with one of those strings.
+callbacks=cb_,
+ _cb
+
+# A regular expression matching the name of dummy variables (i.e. expectedly
+# not used).
+dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*|^ignored_|^unused_
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# List of qualified module names which can have objects that can redefine
+# builtins.
+redefining-builtins-modules=six.moves,past.builtins,future.builtins
+
+
+[LOGGING]
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format
+logging-modules=logging
+
+
+[TYPECHECK]
+
+# List of decorators that produce context managers, such as
+# contextlib.contextmanager. Add to this list to register other decorators that
+# produce valid context managers.
+contextmanager-decorators=contextlib.contextmanager
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E1101 when accessed. Python regular
+# expressions are accepted.
+generated-members=
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# This flag controls whether pylint should warn about no-member and similar
+# checks whenever an opaque object is returned when inferring. The inference
+# can return multiple potential results while evaluating a Python object, but
+# some branches might not be evaluated, which results in partial inference. In
+# that case, it might be useful to still emit no-member and other checks for
+# the rest of the inferred objects.
+ignore-on-opaque-inference=yes
+
+# List of class names for which member attributes should not be checked (useful
+# for classes with dynamically set attributes). This supports the use of
+# qualified names.
+ignored-classes=optparse.Values,thread._local,_thread._local
+
+# List of module names for which member attributes should not be checked
+# (useful for modules/projects where namespaces are manipulated during runtime
+# and thus existing member attributes cannot be deduced by static analysis. It
+# supports qualified module names, as well as Unix pattern matching.
+ignored-modules=
+
+# Show a hint with possible names when a member name was not found. The aspect
+# of finding the hint is based on edit distance.
+missing-member-hint=yes
+
+# The minimum edit distance a name should have in order to be considered a
+# similar match for a missing member name.
+missing-member-hint-distance=1
+
+# The total number of similar names that should be taken in consideration when
+# showing a hint for a missing member.
+missing-member-max-choices=1
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,
+ XXX,
+ TODO
+
+
+[BASIC]
+
+# Naming style matching correct argument names
+argument-naming-style=snake_case
+
+# Regular expression matching correct argument names. Overrides argument-
+# naming-style
+#argument-rgx=
+
+# Naming style matching correct attribute names
+attr-naming-style=snake_case
+
+# Regular expression matching correct attribute names. Overrides attr-naming-
+# style
+#attr-rgx=
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,
+ bar,
+ baz,
+ toto,
+ tutu,
+ tata
+
+# Naming style matching correct class attribute names
+class-attribute-naming-style=any
+
+# Regular expression matching correct class attribute names. Overrides class-
+# attribute-naming-style
+#class-attribute-rgx=
+
+# Naming style matching correct class names
+class-naming-style=PascalCase
+
+# Regular expression matching correct class names. Overrides class-naming-style
+#class-rgx=
+
+# Naming style matching correct constant names
+const-naming-style=UPPER_CASE
+
+# Regular expression matching correct constant names. Overrides const-naming-
+# style
+#const-rgx=
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=-1
+
+# Naming style matching correct function names
+function-naming-style=snake_case
+
+# Regular expression matching correct function names. Overrides function-
+# naming-style
+#function-rgx=
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,
+ j,
+ k,
+ ex,
+ Run,
+ _
+
+# Include a hint for the correct naming format with invalid-name
+include-naming-hint=no
+
+# Naming style matching correct inline iteration names
+inlinevar-naming-style=any
+
+# Regular expression matching correct inline iteration names. Overrides
+# inlinevar-naming-style
+#inlinevar-rgx=
+
+# Naming style matching correct method names
+method-naming-style=snake_case
+
+# Regular expression matching correct method names. Overrides method-naming-
+# style
+#method-rgx=
+
+# Naming style matching correct module names
+module-naming-style=snake_case
+
+# Regular expression matching correct module names. Overrides module-naming-
+# style
+#module-rgx=
+
+# Colon-delimited sets of names that determine each other's naming style when
+# the name regexes allow several styles.
+name-group=
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=^_
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties.
+property-classes=abc.abstractproperty
+
+# Naming style matching correct variable names
+variable-naming-style=snake_case
+
+# Regular expression matching correct variable names. Overrides variable-
+# naming-style
+#variable-rgx=
+
+
+[SPELLING]
+
+# Limits count of emitted suggestions for spelling mistakes
+max-spelling-suggestions=4
+
+# Spelling dictionary name. Available dictionaries: none. To make it working
+# install python-enchant package.
+spelling-dict=
+
+# List of comma separated words that should not be checked.
+spelling-ignore-words=
+
+# A path to a file that contains private dictionary; one word per line.
+spelling-private-dict-file=
+
+# Tells whether to store unknown words to indicated private dictionary in
+# --spelling-private-dict-file option instead of raising a message.
+spelling-store-unknown-words=no
+
+
+[FORMAT]
+
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
+expected-line-ending-format=
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )??$
+
+# Number of spaces of indent required inside a hanging or continued line.
+indent-after-paren=4
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string=' '
+
+# Maximum number of characters on a single line.
+max-line-length=100
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# List of optional constructs for which whitespace checking is disabled. `dict-
+# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
+# `trailing-comma` allows a space between comma and closing bracket: (a, ).
+# `empty-line` allows space-only lines.
+no-space-check=trailing-comma,
+ dict-separator
+
+# Allow the body of a class to be on the same line as the declaration if body
+# contains single statement.
+single-line-class-stmt=no
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=no
+
+
+[SIMILARITIES]
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method
+max-args=5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Maximum number of boolean expressions in a if statement
+max-bool-expr=5
+
+# Maximum number of branch for function / method body
+max-branches=12
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+
+[IMPORTS]
+
+# Allow wildcard imports from modules that define __all__.
+allow-wildcard-with-all=no
+
+# Analyse import fallback blocks. This can be used to support both Python 2 and
+# 3 compatible code, which means that the block might have code that exists
+# only in one or another interpreter, leading to false positives when analysed.
+analyse-fallback-blocks=no
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,
+ TERMIOS,
+ Bastion,
+ rexec
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+# Force import order to recognize a module as part of the standard
+# compatibility libraries.
+known-standard-library=
+
+# Force import order to recognize a module as part of a third party library.
+known-third-party=enchant
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,
+ __new__,
+ setUp
+
+# List of member names, which should be excluded from the protected access
+# warning.
+exclude-protected=_asdict,
+ _fields,
+ _replace,
+ _source,
+ _make
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=mcs
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=Exception
diff --git a/.github/linters/.ruby-lint.yml b/.github/linters/.ruby-lint.yml
new file mode 100644
index 00000000..c70ad84d
--- /dev/null
+++ b/.github/linters/.ruby-lint.yml
@@ -0,0 +1,184 @@
+---
+#######################
+# Rubocop Config file #
+#######################
+
+################################################################################
+############################## Rails Rules #####################################
+################################################################################
+
+# Set the linter to enable rails rules
+Rails:
+ Enabled: true
+
+################################################################################
+############################# Security Rules ###################################
+################################################################################
+
+# Security rules
+Security/Open:
+ Enabled: false
+################################################################################
+############################# Metrics Rules ####################################
+################################################################################
+
+# Commonly used screens these days easily fit more than 80 characters.
+Metrics/LineLength:
+ Max: 120
+
+# Too short methods lead to extraction of single-use methods, which can make
+# the code easier to read (by naming things), but can also clutter the class
+Metrics/MethodLength:
+ Max: 30
+
+# The guiding principle of classes is SRP,
+# SRP can't be accurately measured by LoC
+Metrics/ClassLength:
+ Max: 1500
+
+# Turn off the Assignment Branch Condition size for the case of these scripts
+Metrics/AbcSize:
+ Enabled: false
+
+# Set the complexity of the metrics
+Metrics/PerceivedComplexity:
+ Max: 10
+
+# Set the complexity of the cyle
+Metrics/CyclomaticComplexity:
+ Max: 10
+
+################################################################################
+########################## Layout Rules ########################################
+################################################################################
+
+# No space makes the method definition shorter and differentiates
+# from a regular assignment.
+Layout/SpaceAroundEqualsInParameterDefault:
+ EnforcedStyle: no_space
+
+# Indenting the chained dots beneath each other is not supported by this cop,
+# see https://github.com/bbatsov/rubocop/issues/1633
+Layout/MultilineOperationIndentation:
+ Enabled: false
+
+Layout/SpaceInsideBlockBraces:
+ # The space here provides no real gain in readability while consuming
+ # horizontal space that could be used for a better parameter name.
+ # Also {| differentiates better from a hash than { | does.
+ SpaceBeforeBlockParameters: false
+
+# No trailing space differentiates better from the block:
+# foo} means hash, foo } means block.
+Layout/SpaceInsideHashLiteralBraces:
+ EnforcedStyle: no_space
+
+################################################################################
+########################### Style Rules ########################################
+################################################################################
+
+# Single quotes being faster is hardly measurable and only affects parse time.
+# Enforcing double quotes reduces the times where you need to change them
+# when introducing an interpolation. Use single quotes only if their semantics
+# are needed.
+Style/StringLiterals:
+ EnforcedStyle: double_quotes
+
+# We do not need to support Ruby 1.9, so this is good to use.
+Style/SymbolArray:
+ Enabled: true
+
+# Mixing the styles looks just silly.
+Style/HashSyntax:
+ EnforcedStyle: ruby19_no_mixed_keys
+
+# has_key? and has_value? are far more readable than key? and value?
+Style/PreferredHashMethods:
+ Enabled: false
+
+# String#% is by far the least verbose and only object oriented variant.
+Style/FormatString:
+ EnforcedStyle: percent
+
+Style/CollectionMethods:
+ Enabled: true
+ PreferredMethods:
+ # inject seems more common in the community.
+ reduce: "inject"
+
+# Either allow this style or don't. Marking it as safe with parenthesis
+# is silly. Let's try to live without them for now.
+Style/ParenthesesAroundCondition:
+ AllowSafeAssignment: false
+
+# A specialized exception class will take one or more arguments
+# and construct the message from it. So both variants make sense.
+Style/RaiseArgs:
+ Enabled: false
+
+# Fail is an alias of raise. Avoid aliases,
+# it's more cognitive load for no gain. The argument that fail
+# should be used to abort the program is wrong too,
+# there's Kernel#abort for that.
+Style/SignalException:
+ EnforcedStyle: only_raise
+
+# { ... } for multi-line blocks is okay, follow Weirichs rule instead:
+# https://web.archive.org/web/20140221124509/http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc
+Style/BlockDelimiters:
+ Enabled: false
+
+# do / end blocks should be used for side effects,
+# methods that run a block for side effects and have
+# a useful return value are rare, assign the return
+# value to a local variable for those cases.
+Style/MethodCalledOnDoEndBlock:
+ Enabled: true
+
+# Enforcing the names of variables? To single letter ones? Just no.
+Style/SingleLineBlockParams:
+ Enabled: false
+
+# Check with yard instead.
+Style/Documentation:
+ Enabled: false
+
+# Style preference
+Style/MethodDefParentheses:
+ Enabled: false
+
+################################################################################
+########################### Linter Rules #######################################
+################################################################################
+
+# There are valid cases, for example debugging Cucumber steps,
+# also they'll fail CI anyway
+Lint/Debugger:
+ Enabled: false
+
+# Shadowing outer local variables with block parameters is often useful
+# to not reinvent a new name for the same thing, it highlights the relation
+# between the outer variable and the parameter. The cases where it's actually
+# confusing are rare, and usually bad for other reasons already, for example
+# because the method is too long.
+Lint/ShadowingOuterLocalVariable:
+ Enabled: false
+
+# Suppressing exceptions can be perfectly fine, and be it to avoid to
+# explicitly type nil into the rescue since that's what you want to return,
+# or suppressing LoadError for optional dependencies
+Lint/HandleExceptions:
+ Enabled: false
+
+Lint/AssignmentInCondition:
+ AllowSafeAssignment: false
+
+################################################################################
+############################ Naming Rules ######################################
+################################################################################
+
+# This is just silly. Calling the argument `other` in all cases makes no sense.
+Naming/BinaryOperatorParameterName:
+ Enabled: false
+
+################################################################################
diff --git a/.github/linters/.yaml-lint.yml b/.github/linters/.yaml-lint.yml
new file mode 100644
index 00000000..faccea80
--- /dev/null
+++ b/.github/linters/.yaml-lint.yml
@@ -0,0 +1,59 @@
+---
+###########################################
+# These are the rules used for #
+# linting all the yaml files in the stack #
+# NOTE: #
+# You can disble line with: #
+# # yamllint disable-line #
+###########################################
+rules:
+ braces:
+ level: warning
+ min-spaces-inside: 0
+ max-spaces-inside: 0
+ min-spaces-inside-empty: 1
+ max-spaces-inside-empty: 5
+ brackets:
+ level: warning
+ min-spaces-inside: 0
+ max-spaces-inside: 0
+ min-spaces-inside-empty: 1
+ max-spaces-inside-empty: 5
+ colons:
+ level: warning
+ max-spaces-before: 0
+ max-spaces-after: 1
+ commas:
+ level: warning
+ max-spaces-before: 0
+ min-spaces-after: 1
+ max-spaces-after: 1
+ comments: disable
+ comments-indentation: disable
+ document-end: disable
+ document-start:
+ level: warning
+ present: true
+ empty-lines:
+ level: warning
+ max: 2
+ max-start: 0
+ max-end: 0
+ hyphens:
+ level: warning
+ max-spaces-after: 1
+ indentation:
+ level: warning
+ spaces: consistent
+ indent-sequences: true
+ check-multi-line-strings: false
+ key-duplicates: enable
+ line-length:
+ level: warning
+ max: 80
+ allow-non-breakable-words: true
+ allow-non-breakable-inline-mappings: true
+ new-line-at-end-of-file: disable
+ new-lines:
+ type: unix
+ trailing-spaces: disable
From b7d5091903d5f3699f5eeb356df47a435cd2f5bc Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:24:04 -0600
Subject: [PATCH 11/28] fix it?
---
.github/workflows/deploy-DEV.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 9df7eaa9..e6a8d08b 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -57,6 +57,6 @@ jobs:
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:${{ github.ref }}
+ uses: docker://admiralawkbar/super-linter:{{ github.ref }}
env:
TEST_CASE_RUN: true
From 8867343a0cc6e73a7b8628cfc63142bcac00b049 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:28:37 -0600
Subject: [PATCH 12/28] maybe
---
.github/workflows/deploy-DEV.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index e6a8d08b..31de8b80 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -57,6 +57,6 @@ jobs:
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:{{ github.ref }}
+ uses: docker://admiralawkbar/super-linter:${ GITHUB_REF##*/ }
env:
TEST_CASE_RUN: true
From e42905148c702f1177fbd668ce9f77a43041f6cc Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:29:39 -0600
Subject: [PATCH 13/28] here
---
.github/workflows/deploy-DEV.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 31de8b80..cbcfc2d7 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -57,6 +57,6 @@ jobs:
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:${ GITHUB_REF##*/ }
+ uses: docker://admiralawkbar/super-linter:${{ GITHUB_REF##*/ }}
env:
TEST_CASE_RUN: true
From bb4c2bc9f8f3dad2b9cbf4b96e48d89864757417 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:33:37 -0600
Subject: [PATCH 14/28] try thid
---
.github/workflows/deploy-DEV.yml | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index cbcfc2d7..013864cc 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -53,10 +53,17 @@ jobs:
shell: bash
run: .automation/upload-docker.sh
+ #######################
+ # Get the branch name #
+ #######################
+ - name: get the branch name
+ shell: bash
+ run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
+
################################
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:${{ GITHUB_REF##*/ }}
+ uses: docker://admiralawkbar/super-linter:${{ BRANCH_NAME }}
env:
TEST_CASE_RUN: true
From 97fb492f2ad93e4ce2c9f378ae242fb3c9dc5dba Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:34:17 -0600
Subject: [PATCH 15/28] fix spaces
---
.github/workflows/deploy-DEV.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 013864cc..813d1cf0 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -57,8 +57,8 @@ jobs:
# Get the branch name #
#######################
- name: get the branch name
- shell: bash
- run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
+ shell: bash
+ run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
################################
# Run Linter against code base #
From 6f39c5e7db99aeac016f5354c87a6659ffc9d23f Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:40:11 -0600
Subject: [PATCH 16/28] again
---
.github/workflows/deploy-DEV.yml | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 813d1cf0..cd03e34d 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -53,17 +53,10 @@ jobs:
shell: bash
run: .automation/upload-docker.sh
- #######################
- # Get the branch name #
- #######################
- - name: get the branch name
- shell: bash
- run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
-
################################
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:${{ BRANCH_NAME }}
+ uses: docker://admiralawkbar/super-linter:${ GITHUB_REF##*/}
env:
TEST_CASE_RUN: true
From 4c0830a0ea5f1c88fb4e0583775c3e5923aad75a Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:41:15 -0600
Subject: [PATCH 17/28] again
---
.github/workflows/deploy-DEV.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index cd03e34d..71b5bf34 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -57,6 +57,6 @@ jobs:
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:${ GITHUB_REF##*/}
+ uses: docker://admiralawkbar/super-linter:${{ github.ref##*/}}
env:
TEST_CASE_RUN: true
From ed6ca2786708f3809e12742c81becca2f670bb75 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:51:21 -0600
Subject: [PATCH 18/28] fix spaces
---
.github/workflows/deploy-DEV.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 71b5bf34..638d2e36 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -57,6 +57,6 @@ jobs:
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:${{ github.ref##*/}}
+ uses: docker://admiralawkbar/super-linter:${GITHUB_REF##*/}
env:
TEST_CASE_RUN: true
From 82a0142f38edb84de36fc3b660c3e05a476abb86 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:52:55 -0600
Subject: [PATCH 19/28] adding it
---
.github/workflows/deploy-DEV.yml | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 638d2e36..cfb15d4c 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -53,10 +53,14 @@ jobs:
shell: bash
run: .automation/upload-docker.sh
+ - name: debug
+ run: printenv
+ shell: bash
+
################################
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:${GITHUB_REF##*/}
+ uses: docker://admiralawkbar/super-linter:${GITHUB_REF}
env:
TEST_CASE_RUN: true
From 637ba6236286a3115164f763a99fdef7652cb1ed Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 12:53:55 -0600
Subject: [PATCH 20/28] bla
---
.github/workflows/deploy-DEV.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index cfb15d4c..b57b604f 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -61,6 +61,6 @@ jobs:
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter:${GITHUB_REF}
+ uses: docker://admiralawkbar/super-linter
env:
TEST_CASE_RUN: true
From ea4780a80d3de6ac83ca6022d8475932e29f8a8a Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 13:00:03 -0600
Subject: [PATCH 21/28] here it is
---
.github/workflows/deploy-DEV.yml | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index b57b604f..54c6db0f 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -57,10 +57,17 @@ jobs:
run: printenv
shell: bash
+ - name: Extract branch name
+ shell: bash
+ run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
+
+ - name: Test
+ run: echo "${BRANCH_NAME}"
+
################################
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: docker://admiralawkbar/super-linter
+ uses: "docker://admiralawkbar/super-linter:${{BRANCH_NAME}}"
env:
TEST_CASE_RUN: true
From bdd938e9e7562914255767ba0951ff2d9bbbb049 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 13:02:24 -0600
Subject: [PATCH 22/28] branmch
---
.github/workflows/deploy-DEV.yml | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 54c6db0f..68b9a409 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -61,13 +61,10 @@ jobs:
shell: bash
run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
- - name: Test
- run: echo "${BRANCH_NAME}"
-
################################
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: "docker://admiralawkbar/super-linter:${{BRANCH_NAME}}"
+ uses: "docker://admiralawkbar/super-linter:${BRANCH_NAME}"
env:
TEST_CASE_RUN: true
From c15b7e6808ec26bd48b4b6d23e83add8bd152d50 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 14:52:18 -0600
Subject: [PATCH 23/28] another one
---
.github/workflows/deploy-DEV.yml | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 68b9a409..21a388ac 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -65,6 +65,7 @@ jobs:
# Run Linter against code base #
################################
- name: Run Test Cases
- uses: "docker://admiralawkbar/super-linter:${BRANCH_NAME}"
- env:
- TEST_CASE_RUN: true
+ shell: bash
+ run: |
+ docker pull admiralawkbar/super-linter:${BRANCH_NAME}
+ docker run -e RUN_LOCAL=true -e TEST_CASE_RUN=true -v ${GITHUB_WORKSPACE}:/tmp/lint admiralawkbar/super-linter:${BRANCH_NAME}
From c03d1094941c176bc3c4fc7fe3905adf87b4021f Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 15:20:58 -0600
Subject: [PATCH 24/28] fixed them cases
---
.automation/test/ansible/ansible_bad_1.yml | 42 +++++++++++++++++++
...github-playbook.yml => ansible_good_1.yml} | 0
.github/workflows/deploy-DEV.yml | 7 ++--
lib/linter.sh | 27 ++++++++++++
4 files changed, 72 insertions(+), 4 deletions(-)
create mode 100644 .automation/test/ansible/ansible_bad_1.yml
rename .automation/test/ansible/{github-playbook.yml => ansible_good_1.yml} (100%)
diff --git a/.automation/test/ansible/ansible_bad_1.yml b/.automation/test/ansible/ansible_bad_1.yml
new file mode 100644
index 00000000..9bae03fb
--- /dev/null
+++ b/.automation/test/ansible/ansible_bad_1.yml
@@ -0,0 +1,42 @@
+---
+###########################################
+###########################################
+#### GitHub Services-Engineering Stack ####
+#### ####
+#### GHE Primary HA backup-utils ONLY ####
+###########################################
+###########################################
+
+###############################
+# Description of the playbook #
+###############################
+# description: Builds GHE Primary, HA, and backup-utils.
+# detailed_description: Builds GHE Primary, HA, and backup-utils.
+
+######################
+## Configure GitHub ##
+######################
+- hosts: github_primary
+ vars:
+ demo_github_initial_user: "{{ hostvars['localhost'].local_user }}"
+ github_host: "{{ hostvars['github_primary'].ansible_host }}"
+ probot_server_ip: "{{ hostvars['backup-utils'].ansible_host }}"
+ roles:
+ - role: ghe-demo
+
+##########################################
+## Run ghe-config-apply for all changes ##
+##########################################
+# Due to us hot loading some data into GHE, the final
+# run of ghe-config-apply hangs and leaves the system in an odd state
+# The simplist option is to run the process
+# 1 more time at the end to solve the issue
+- hosts: github_primary
+ tasks:
+ - block:
+ - name: GHE-Config-Apply
+ include_role:
+ name: ghe-demo
+ tasks_from: ghe-config-apply.yml
+ tags:
+ - github
diff --git a/.automation/test/ansible/github-playbook.yml b/.automation/test/ansible/ansible_good_1.yml
similarity index 100%
rename from .automation/test/ansible/github-playbook.yml
rename to .automation/test/ansible/ansible_good_1.yml
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 21a388ac..54816cf7 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -53,10 +53,9 @@ jobs:
shell: bash
run: .automation/upload-docker.sh
- - name: debug
- run: printenv
- shell: bash
-
+ #######################
+ # Get the branch name #
+ #######################
- name: Extract branch name
shell: bash
run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
diff --git a/lib/linter.sh b/lib/linter.sh
index af14800a..5c50dce6 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -1317,6 +1317,16 @@ TestCodebase()
# Example: markdown_good_1.md -> good
FILE_STATUS=$(echo "$FILE_NAME" |cut -f2 -d'_')
+ #########################################################
+ # If not found, assume it should be linted successfully #
+ #########################################################
+ if [ -z "$FILE_STATUS" ]; then
+ ##################################
+ # Set to good for proper linting #
+ ##################################
+ FILE_STATUS="good"
+ fi
+
##############
# File print #
##############
@@ -1328,6 +1338,23 @@ TestCodebase()
########################
LINT_CMD=''
+ #######################################
+ # Check if docker and get folder name #
+ #######################################
+ if [[ "$FILE_TYPE" == "DOCKER" ]]; then
+ if [[ "$FILE" == *"good"* ]]; then
+ #############
+ # Good file #
+ #############
+ FILE_STATUS='good'
+ else
+ ############
+ # Bad file #
+ ############
+ FILE_STATUS='bad'
+ fi
+ fi
+
#####################
# Check for ansible #
#####################
From 124b516e6acf55efead3553ce2f2b1a395806d89 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 15:32:14 -0600
Subject: [PATCH 25/28] fix corner case
---
lib/linter.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/linter.sh b/lib/linter.sh
index 5c50dce6..352b7700 100755
--- a/lib/linter.sh
+++ b/lib/linter.sh
@@ -1320,7 +1320,7 @@ TestCodebase()
#########################################################
# If not found, assume it should be linted successfully #
#########################################################
- if [ -z "$FILE_STATUS" ]; then
+ if [ -z "$FILE_STATUS" ] || [[ "$FILE" == *"README"* ]]; then
##################################
# Set to good for proper linting #
##################################
From 8e64ae4512d8a35735813e7873d9e008515433b8 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 15:50:52 -0600
Subject: [PATCH 26/28] fix cases
---
.automation/test/ansible/ansible_bad_1.yml | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/.automation/test/ansible/ansible_bad_1.yml b/.automation/test/ansible/ansible_bad_1.yml
index 9bae03fb..ff9aa7ce 100644
--- a/.automation/test/ansible/ansible_bad_1.yml
+++ b/.automation/test/ansible/ansible_bad_1.yml
@@ -16,13 +16,12 @@
######################
## Configure GitHub ##
######################
-- hosts: github_primary
+- hosts: Yo-Mama
vars:
- demo_github_initial_user: "{{ hostvars['localhost'].local_user }}"
github_host: "{{ hostvars['github_primary'].ansible_host }}"
probot_server_ip: "{{ hostvars['backup-utils'].ansible_host }}"
roles:
- - role: ghe-demo
+ - role: ghe-initialize
##########################################
## Run ghe-config-apply for all changes ##
@@ -34,9 +33,7 @@
- hosts: github_primary
tasks:
- block:
- - name: GHE-Config-Apply
- include_role:
- name: ghe-demo
- tasks_from: ghe-config-apply.yml
+ include_role:
+ tasks_from: ghe-config-apply.yml
tags:
- github
From df4d63e909e0ae62c85932be6fa8fa0272ba4374 Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 15:51:38 -0600
Subject: [PATCH 27/28] fixed it up
---
.github/workflows/deploy-DEV.yml | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 54816cf7..813e0406 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -53,18 +53,12 @@ jobs:
shell: bash
run: .automation/upload-docker.sh
- #######################
- # Get the branch name #
- #######################
- - name: Extract branch name
- shell: bash
- run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
-
################################
# Run Linter against code base #
################################
- name: Run Test Cases
shell: bash
run: |
+ echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
docker pull admiralawkbar/super-linter:${BRANCH_NAME}
docker run -e RUN_LOCAL=true -e TEST_CASE_RUN=true -v ${GITHUB_WORKSPACE}:/tmp/lint admiralawkbar/super-linter:${BRANCH_NAME}
From b558ed7921ea9d1d7e350c9b2a5ca46cbaee248a Mon Sep 17 00:00:00 2001
From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com>
Date: Tue, 4 Feb 2020 15:58:06 -0600
Subject: [PATCH 28/28] put it back
---
.github/workflows/deploy-DEV.yml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml
index 813e0406..54816cf7 100644
--- a/.github/workflows/deploy-DEV.yml
+++ b/.github/workflows/deploy-DEV.yml
@@ -53,12 +53,18 @@ jobs:
shell: bash
run: .automation/upload-docker.sh
+ #######################
+ # Get the branch name #
+ #######################
+ - name: Extract branch name
+ shell: bash
+ run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
+
################################
# Run Linter against code base #
################################
- name: Run Test Cases
shell: bash
run: |
- echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
docker pull admiralawkbar/super-linter:${BRANCH_NAME}
docker run -e RUN_LOCAL=true -e TEST_CASE_RUN=true -v ${GITHUB_WORKSPACE}:/tmp/lint admiralawkbar/super-linter:${BRANCH_NAME}