From 912ceff042b6f373566c722d420b689a40f5641c Mon Sep 17 00:00:00 2001 From: Diego Calero Date: Fri, 17 Mar 2023 17:14:56 -0300 Subject: [PATCH] [#134] Fixing latest repos at home page + other little adjustments (#137) --- .github/workflows/build.yml | 4 +- .github/workflows/test.yml | 2 +- .tool-versions | 2 +- Makefile | 6 +- VERSION | 2 +- assets/js/components/OrgHeader.tsx | 2 +- assets/js/pages/org.tsx | 4 +- assets/js/pages/orgs.tsx | 2 +- assets/js/types.ts | 1 + config/config.exs | 2 +- config/dev.exs | 26 +--- config/prod.exs | 36 +----- config/test.exs | 2 +- cooperatives.yml | 118 ++++++++---------- lib/coophub/application.ex | 9 +- lib/coophub/backends/backends.ex | 6 +- lib/coophub/backends/github.ex | 8 +- lib/coophub/cache_warmer.ex | 75 ++++++----- lib/coophub/repos.ex | 2 +- lib/coophub/schemas/organization.ex | 2 + .../controllers/repo_controller.ex | 2 +- mix.exs | 2 +- .../controllers/repo_controller_test.exs | 4 + test/support/fixtures.ex | 2 + 24 files changed, 137 insertions(+), 184 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6644f9f..369c855 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: os: ['ubuntu-18.04'] otp: ['24.3.3'] elixir: ['1.14.3'] - node: ['12.22.12'] + node: ['12.8.0'] steps: - uses: actions/checkout@v2 @@ -110,6 +110,6 @@ jobs: - name: Push VERSION file uses: ad-m/github-push-action@master with: - github_token: ${{ secrets.REPO_DISPATCH_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} branch: master force: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c810862..c5c516e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest container: - image: elixir:1.12-slim + image: elixir:1.14-slim steps: - uses: actions/checkout@v2 diff --git a/.tool-versions b/.tool-versions index 01f38e7..d539df4 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -elixir 1.12.0 +elixir 1.14.3 erlang 24.3.3 nodejs 12.8.0 diff --git a/Makefile b/Makefile index 83a6365..ebdbe07 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: server release compile test dialyzer plt clean +.PHONY: server release compile test coverage dialyzer plt clean export MIX_ENV ?= dev export SECRET_KEY_BASE ?= $(shell mix phx.gen.secret) @@ -19,6 +19,10 @@ test: MIX_ENV=test test: dialyzer @mix test +coverage: MIX_ENV=test +coverage: + @mix coverage + dialyzer: MIX_ENV=dev dialyzer: @mix dialyzer --check=false diff --git a/VERSION b/VERSION index 9325c3c..2411653 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.0 \ No newline at end of file +0.5.2 \ No newline at end of file diff --git a/assets/js/components/OrgHeader.tsx b/assets/js/components/OrgHeader.tsx index 49c13a3..5454cda 100644 --- a/assets/js/components/OrgHeader.tsx +++ b/assets/js/components/OrgHeader.tsx @@ -6,7 +6,7 @@ import LanguagesProgressBar from './LanguagesProgressBar'; import CountUp from 'react-countup'; import {GoCode, GoStar} from "react-icons/all"; -const OrgHeader:React.FC<{org: Org, maxLanguages: number, starsSum: number}> = ({org, maxLanguages, reposQuantity, starsSum}) => { +const OrgHeader:React.FC<{org: Org, maxLanguages: number, starsSum: number}> = ({org, maxLanguages, starsSum}) => { const orgDate = new Date(org.created_at); const createdDate = `${orgDate.toLocaleString('en', { month: 'long' })} ${orgDate.getFullYear()}`; const location = org.yml_data.location || org.location; diff --git a/assets/js/pages/org.tsx b/assets/js/pages/org.tsx index 9f14d79..79b2f5b 100644 --- a/assets/js/pages/org.tsx +++ b/assets/js/pages/org.tsx @@ -19,10 +19,8 @@ const OrgPage: React.FC> = ({match}) => { const orgName = match.params.name; const response = useFetch(`/api/orgs/${orgName}`) as OrgResponse; const repos = useFetch(`/api/orgs/${orgName}/repos?sort=popular`) as OrgReposResponse; - const starsSum = repos.data.reduce((acc, r)=>{ - return acc + r.stargazers_count; - }, 0); const org = response.data; + const starsSum = org.star_count; const maxLanguages = 5; return <> diff --git a/assets/js/pages/orgs.tsx b/assets/js/pages/orgs.tsx index 4dcbcdf..93cfe27 100644 --- a/assets/js/pages/orgs.tsx +++ b/assets/js/pages/orgs.tsx @@ -19,7 +19,7 @@ const OrgList: React.FC = () => { {org.yml_data.name} - {org.repo_count} Repos + {org.repo_count} Repos, {org.star_count} Stars {org.yml_data.location && diff --git a/assets/js/types.ts b/assets/js/types.ts index 1a7d209..6fb7ca8 100644 --- a/assets/js/types.ts +++ b/assets/js/types.ts @@ -53,6 +53,7 @@ export type Org = { languages: Array; created_at: string; repo_count: number; + star_count: number; } export type Counters = { diff --git a/config/config.exs b/config/config.exs index 7713101..b3f4b1e 100644 --- a/config/config.exs +++ b/config/config.exs @@ -5,7 +5,7 @@ # is restricted to this project. # General application configuration -use Mix.Config +import Config # Configures the endpoint config :coophub, CoophubWeb.Endpoint, diff --git a/config/dev.exs b/config/dev.exs index c7c09a5..d5acc19 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config # For development, we disable any cache and enable # debugging and code reloading. @@ -21,30 +21,6 @@ config :coophub, CoophubWeb.Endpoint, ] ] -# ## SSL Support -# -# In order to use HTTPS in development, a self-signed -# certificate can be generated by running the following -# Mix task: -# -# mix phx.gen.cert -# -# Note that this task requires Erlang/OTP 20 or later. -# Run `mix help phx.gen.cert` for more information. -# -# The `http:` config above can be replaced with: -# -# https: [ -# port: 4001, -# cipher_suite: :strong, -# keyfile: "priv/cert/selfsigned_key.pem", -# certfile: "priv/cert/selfsigned.pem" -# ], -# -# If desired, both `http:` and `https:` keys can be -# configured to run both http and https servers on -# different ports. - # Watch static and templates for browser reloading. config :coophub, CoophubWeb.Endpoint, live_reload: [ diff --git a/config/prod.exs b/config/prod.exs index 95ae6c9..c5b8c3a 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config # For production, don't forget to configure the url host # to something meaningful, Phoenix uses this information @@ -32,37 +32,3 @@ config :coophub, # Do not print debug messages in production config :logger, level: :info - -# ## SSL Support -# -# To get SSL working, you will need to add the `https` key -# to the previous section and set your `:url` port to 443: -# -# config :coophub, CoophubWeb.Endpoint, -# ... -# url: [host: "example.com", port: 443], -# https: [ -# :inet6, -# port: 443, -# cipher_suite: :strong, -# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"), -# certfile: System.get_env("SOME_APP_SSL_CERT_PATH") -# ] -# -# The `cipher_suite` is set to `:strong` to support only the -# latest and more secure SSL ciphers. This means old browsers -# and clients may not be supported. You can set it to -# `:compatible` for wider support. -# -# `:keyfile` and `:certfile` expect an absolute path to the key -# and cert in disk or a relative path inside priv, for example -# "priv/ssl/server.key". For all supported SSL configuration -# options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1 -# -# We also recommend setting `force_ssl` in your endpoint, ensuring -# no data is ever sent via http, always redirecting to https: -# -# config :coophub, CoophubWeb.Endpoint, -# force_ssl: [hsts: true] -# -# Check `Plug.SSL` for all available options in `force_ssl`. diff --git a/config/test.exs b/config/test.exs index 889fd25..afb685b 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config # We don't run a server during test. If one is required, # you can enable the server option below. diff --git a/cooperatives.yml b/cooperatives.yml index 7bbf8d5..36798a4 100644 --- a/cooperatives.yml +++ b/cooperatives.yml @@ -2,7 +2,7 @@ fiqus: source: github login: fiqus name: Fiqus - url: https://www.fiqus.coop + url: https://fiqus.coop description: "Cooperative company specialized in software, founded in 2011." location: CABA/Villa La Angostura, Argentina @@ -173,7 +173,7 @@ outlandish: url: http://outlandish.com/ description: "Web tech co-op based in Finsbury Park, North London" location: London, UK - + facttic: source: github login: facttic @@ -301,7 +301,7 @@ nova-web-development: url: https://novawebdevelopment.org/ description: "NOVA Web Development is a democratically run, worker-owned and operated cooperative focused on developing free software tools for progressive organizations and committed to economic democracy." location: Arlington, VA, USA; Los Angeles, California, USA; Newcastle Upon Tyne, UK; Santa Ana, El Salvador - + gaia: source: gitlab login: gaia-software @@ -389,7 +389,7 @@ obran: url: https://obran.org/ description: "We believe that everyone has the freedom to own their work. We are creating a community of worker-owners to do just that." location: Baltimore, USA - + informal-systems: source: github login: informalsystems @@ -397,7 +397,7 @@ informal-systems: url: https://informal.systems/ description: "We envision an open-source ecosystem of cooperatively owned and governed, distributed organizations, running on reliable distributed systems." location: Toronto, Canada; Vienna, Austria; Lausanne, Switzerland; Berlin, Germany - + RChain: source: github login: rchain @@ -407,37 +407,37 @@ RChain: location: Incorporated in Seattle Washington, Global membership Resonate: - source: github - login: resonatecoop - name: Resonate - url: https://resonate.coop - description: "Resonate is the Stream 2 Own ethical, global music streaming co-operative. Our rewards for new artists and music are better than those from typical mass market streaming services. We are a community-led alternative that embodies cooperative values." - location: Registered in Ireland in the EU - Global Membership - + source: github + login: resonatecoop + name: Resonate + url: https://resonate.coop + description: "Resonate is the Stream 2 Own ethical, global music streaming co-operative. Our rewards for new artists and music are better than those from typical mass market streaming services. We are a community-led alternative that embodies cooperative values." + location: Registered in Ireland in the EU - Global Membership + dojo4: - source: github - login: dojo4 - name: Dojo4 - url: https://www.dojo4.com/ - description: "Dojo4 is a community-based, member-owned agency that creates positive change through technology and design." - location: Boulder, Colorado, USA - + source: github + login: dojo4 + name: Dojo4 + url: https://www.dojo4.com/ + description: "Dojo4 is a community-based, member-owned agency that creates positive change through technology and design." + location: Boulder, Colorado, USA + gemifytech: - source: github - login: gemifytech - name: Gemify - url: https://gemify.tech/ - description: "We're a worker-owned tech cooperative building affordable Platform-as-a-Service software, games, and other solutions designed to keep your needs in mind." - location: USA - + source: github + login: gemifytech + name: Gemify + url: https://gemify.tech/ + description: "We're a worker-owned tech cooperative building affordable Platform-as-a-Service software, games, and other solutions designed to keep your needs in mind." + location: USA + nimbleheroes: - source: github - login: nimbleheroes - name: Nexodus - url: https://nexod.us/ - description: "We build curated VFX production teams with the industry’s best talent & technology." - location: Cincinnati, Ohio, USA - + source: github + login: nimbleheroes + name: Nexodus + url: https://nexod.us/ + description: "We build curated VFX production teams with the industry’s best talent & technology." + location: Cincinnati, Ohio, USA + plausiblelabs: source: github login: plausiblelabs @@ -445,7 +445,7 @@ plausiblelabs: url: https://www.plausible.coop description: "Plausible Labs supports creative and scientific expression, transparent collaboration, and independent problem-solving through our products, business structure, and long-term relationships with our customers, investors, partners, and communities." location: New York and San Francisco, USA - + politics-rewired: source: github login: politics-rewired @@ -453,7 +453,7 @@ politics-rewired: url: https://www.politicsrewired.com/ description: "We are a worker-owned cooperative motivated by politics, not profits. We’re in this fight to support the campaigns, organizations, and unions doing the work to organize millions of ordinary people to create a more free and equal world." location: USA - + zinc-collective: source: github login: zinc-collective @@ -461,7 +461,7 @@ zinc-collective: url: https://www.zinc.coop/ description: "" location: USA - + soficoop: source: github login: soficoop @@ -469,7 +469,7 @@ soficoop: url: https://www.sofi.coop/ description: "Sofi is a workers cooperative of designers and developers, we focus on websites and applications that bring positive value for society and the planet." location: Jerusalem, Israel - + 24eme: source: github login: 24eme @@ -477,7 +477,7 @@ soficoop: url: https://www.24eme.fr/ description: "Governance based on trust and transparency." location: Paris, France - + atomised: source: github login: Atomised @@ -485,7 +485,7 @@ atomised: url: http://www.atomised.coop/ description: "Founded 2008." location: Cupar, Scotland - + agilecollective: source: github login: agilecollective @@ -509,7 +509,7 @@ champs-libres: url: https://www.champs-libres.coop/ description: "Logiciels libres & géographiques." location: Namur, Belgium - + CodeursEnLiberte: source: gitlab login: CodeursEnLiberte @@ -517,7 +517,7 @@ CodeursEnLiberte: url: https://xn--codeursenlibert-pnb.fr/ description: "Codeurs en Liberté brings together independent employees in the IT field." location: France - + coopiteasy: source: github login: coopiteasy @@ -525,7 +525,7 @@ coopiteasy: url: https://coopiteasy.be/ description: "Worker coop, we provide Open Source ERPs to other cooperatives." location: Brussels, Belgium - + dalibo: source: github login: dalibo @@ -533,7 +533,7 @@ dalibo: url: https://dalibo.com/ description: "Since 2005, Dalibo has made its know-how in the field of databases available to its customers and offers consulting, training and support services to businesses and institutions." location: Paris, France - + fairnesscoop: source: github login: fairnesscoop @@ -541,7 +541,7 @@ fairnesscoop: url: https://fairness.coop/ description: "Worker-owned coop with a focus on digital eco-design and software quality." location: France - + femprocomuns: source: gitlab login: femprocomuns @@ -549,7 +549,7 @@ femprocomuns: url: https://femprocomuns.coop/ description: "Strategic social tool to make common activity viable." location: Catalunia - + FikaWorks: source: github login: FikaWorks @@ -557,7 +557,7 @@ FikaWorks: url: https://fika.works/ description: "We are the next wave of Cloud Native Consultants." location: Netherlands - + gnucoop: source: github login: gnucoop @@ -573,7 +573,7 @@ GoodPraxis: url: https://goodpraxis.coop/ description: "GOOD PRAXIS is a socially aware digital studio based in London. Connecting strategic thinking with technical expertise, the way we work is sensitive to people’s needs." location: London, UK - + HappyDev: source: github login: HappyDev-team @@ -581,7 +581,7 @@ HappyDev: url: https://happy-dev.fr/ description: "The Happy Dev network brings together digital freelancers from all over France." location: France - + HappyCulture: source: github login: Happyculture @@ -589,15 +589,7 @@ HappyCulture: url: https://happyculture.coop/ description: "Webagency working to increase projects sucess rates for customers." location: France - -hostsharing: - source: github - login: hostsharing - name: Hostsharing eG - url: https://www.hostsharing.net/ - description: "Community hosting for digital sovereignty, sustainability and excellence." - location: Germany - + hostsharing: source: github login: hostsharing @@ -605,7 +597,7 @@ hostsharing: url: https://www.hostsharing.net/ description: "Community hosting for digital sovereignty, sustainability and excellence." location: Germany - + igalia: source: github login: Igalia @@ -613,7 +605,7 @@ igalia: url: https://www.igalia.com/ description: "Igalia is a Free Software consultancy with headquarters in Spain and developers all around the world." location: Spain - + kaleidos: source: github login: kaleidos @@ -637,7 +629,7 @@ Les-Tilleuls: url: https://les-tilleuls.coop/ description: "We are a tech company and a cooperative, specialized in e-commerce, web technologies and open source." location: Lille, Paris, Nantes, Lyon, France - + motion-twin: source: github login: motion-twin @@ -645,7 +637,7 @@ motion-twin: url: https://motion-twin.com/ description: "Games! Everyone at Motion Twin is an associate. We're all part owners of the company and we're all here way longer than we should be." location: Bordeaux, France - + multi-coop: source: github login: multi-coop @@ -653,7 +645,7 @@ multi-coop: url: https://www.multi.coop/ description: "The cooperative multi contibutes to develop digital commons and related services. To do so we gathered a community of profesionals aiming to keep digital industry able to respond to the public's general interest." location: France - + open-data-services: source: github login: OpenDataServices @@ -669,7 +661,7 @@ probesys: url: https://www.probesys.com/ description: "Since 2003, Probesys, IT service provider specializing in free and open source solutions, supports you in all your IT projects." location: Grenoble, France - + reinblau: source: github login: reinblau diff --git a/lib/coophub/application.ex b/lib/coophub/application.ex index 56ffe9d..8574be8 100644 --- a/lib/coophub/application.ex +++ b/lib/coophub/application.ex @@ -8,9 +8,9 @@ defmodule Coophub.Application do import Cachex.Spec require Logger - @repos_cache_name Application.get_env(:coophub, :main_cache_name) - @uris_cache_name Application.get_env(:coophub, :uris_cache_name) - @cache_interval Application.get_env(:coophub, :cache_interval) + @repos_cache_name Application.compile_env(:coophub, :main_cache_name) + @uris_cache_name Application.compile_env(:coophub, :uris_cache_name) + @cache_interval Application.compile_env(:coophub, :cache_interval) def start(_type, _args) do check_github_token() @@ -42,12 +42,15 @@ defmodule Coophub.Application do # Tell Phoenix to update the endpoint configuration # whenever the application is updated. + @spec config_change(any, any, any) :: :ok def config_change(changed, _new, removed) do CoophubWeb.Endpoint.config_change(changed, removed) :ok end + @spec env :: atom def env, do: Application.get_env(:coophub, CoophubWeb.Endpoint)[:environment] + @spec env?(atom) :: boolean def env?(environment), do: env() == environment defp main_cache_opts(:test), do: [] diff --git a/lib/coophub/backends/backends.ex b/lib/coophub/backends/backends.ex index c5d33d2..6efdad8 100644 --- a/lib/coophub/backends/backends.ex +++ b/lib/coophub/backends/backends.ex @@ -172,6 +172,9 @@ defmodule Coophub.Backends do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> {:ok, Jason.decode!(body), take_time() - start_ms} + {:ok, %HTTPoison.Response{status_code: 401}} -> + {:error, "Forbidden (bad credentials): #{url}"} + {:ok, %HTTPoison.Response{status_code: 403}} -> {:error, "Forbidden (possible API rate-limit): #{url}"} @@ -181,7 +184,8 @@ defmodule Coophub.Backends do {:error, %HTTPoison.Error{reason: reason}} -> {:error, reason} - _ -> + error -> + Logger.error("Request failed with: #{inspect(error)}") {:error, "Unexpected error: #{url}"} end end diff --git a/lib/coophub/backends/github.ex b/lib/coophub/backends/github.ex index 8349d24..98f530a 100644 --- a/lib/coophub/backends/github.ex +++ b/lib/coophub/backends/github.ex @@ -107,11 +107,15 @@ defmodule Coophub.Backends.Github do end defp headers() do - headers = [{"Accept", "application/vnd.github.mercy-preview+json"}] + headers = [ + {"Accept", "application/vnd.github+json"}, + {"X-GitHub-Api-Version", "2022-11-28"} + ] + token = System.get_env("GITHUB_OAUTH_TOKEN") if is_binary(token), - do: [{"Authorization", "token #{token}"} | headers], + do: [{"Authorization", "Bearer #{token}"} | headers], else: headers end diff --git a/lib/coophub/cache_warmer.ex b/lib/coophub/cache_warmer.ex index a0be835..0c8650d 100644 --- a/lib/coophub/cache_warmer.ex +++ b/lib/coophub/cache_warmer.ex @@ -7,19 +7,21 @@ defmodule Coophub.CacheWarmer do require Logger - @repos_cache_name Application.get_env(:coophub, :main_cache_name) - @repos_cache_interval Application.get_env(:coophub, :cache_interval) - @repos_cache_dump_file Application.get_env(:coophub, :main_cache_dump_file) + @repos_cache_name Application.compile_env(:coophub, :main_cache_name) + @repos_cache_interval Application.compile_env(:coophub, :cache_interval) + @repos_cache_dump_file Application.compile_env(:coophub, :main_cache_dump_file) @doc """ Returns the interval for this warmer. """ + @spec interval :: non_neg_integer def interval, do: :timer.minutes(@repos_cache_interval) @doc """ Executes this cache warmer. """ + @spec execute(any) :: :ignore | {:ok, list({atom, Repos.org()}), keyword} def execute(_state) do ## Delay the execution a bit to ensure Cachex is available Process.sleep(2000) @@ -58,12 +60,10 @@ defmodule Coophub.CacheWarmer do {:ok, repos, ttl: :timer.hours(24 * 365)} end - @doc """ - Given the github orgs from the yml as input, it will merge them with - the existent in the current cache (sorted by cached_at asc) and prepare - the github orgs to be requested - """ - def merge_github_orgs(github_orgs_yml) do + ## Given the github orgs from the yml as input, it will merge them with + ## the existent in the current cache (sorted by cached_at asc) and prepare + ## the github orgs to be requested + defp merge_github_orgs(github_orgs_yml) do github_orgs_yml |> Enum.map(fn {org_key, yml_data} -> case Cachex.get(@repos_cache_name, org_key) do @@ -79,17 +79,15 @@ defmodule Coophub.CacheWarmer do end) end - @doc """ - Prepare the data using a different logic by source - E.g: github will require a rate_limit handling logic - """ - def get_data("github", github_orgs) do + ## Prepare the data using a different logic by source + ## E.g: github will require a rate_limit handling logic + defp get_data("github", github_orgs) do github_orgs |> merge_github_orgs() |> get_from_github() end - def get_data(_source, orgs) do + defp get_data(_source, orgs) do Enum.map(orgs, fn {org_key, yml_data} -> case get_org(org_key, yml_data) do :error -> [] @@ -98,18 +96,17 @@ defmodule Coophub.CacheWarmer do end) end - @doc """ - Get data from Github, using the max requests per organization - Github has a rate limit policy and we use a safe way of getting - the data, rotating the organizations by last requested date - - 1 req x org details - - 1 req x org repos - - 1 req x repo lang - - 1 req x repo topics - - 202 is the worst number of requests x org in prod (depends on fetch_max_repos config) - """ - def get_from_github(orgs) do + ## Get data from Github, using the max requests per organization + ## Github has a rate limit policy and we use a safe way of getting + ## the data, rotating the organizations by last requested date + ## - 1 req x org details + ## - 1 req x org repos + ## - 1 req x repo lang + ## - 1 req x repo topics + ## - 202 is the worst number of requests x org in prod (depends on fetch_max_repos config) + defp get_from_github(orgs) do github_rate_limit = Backends.get_rate_limit("github") + Logger.info("Github request rate limit: #{inspect(github_rate_limit)}") limit = Application.get_env(:coophub, :fetch_max_repos) * 2 + 2 Enum.take(orgs, floor(github_rate_limit / limit)) @@ -121,18 +118,16 @@ defmodule Coophub.CacheWarmer do end) end - @doc """ - Group organizations by git source - %{ - "github" => %{ - "fiqus" => %{ ... } - }, - "gitlab" => %{ - "another" => %{ ... } - } - } - """ - def group_by_source(yml_orgs) do + ## Group organizations by git source + ## %{ + ## "github" => %{ + ## "fiqus" => %{ ... } + ## }, + ## "gitlab" => %{ + ## "another" => %{ ... } + ## } + ## } + defp group_by_source(yml_orgs) do Enum.reduce(yml_orgs, %{}, fn {key, yml_data}, acc -> source_coops = acc @@ -203,7 +198,8 @@ defmodule Coophub.CacheWarmer do %Organization{} = org -> %Organization{org | cached_at: DateTime.utc_now()} - _ -> + error -> + Logger.error("Couldn't get org data: #{inspect(error)}") :error end end @@ -220,6 +216,7 @@ defmodule Coophub.CacheWarmer do org |> Map.put(:repos, repos) |> Map.put(:repo_count, Enum.count(repos)) + |> Map.put(:star_count, Enum.reduce(repos, 0, &(&2 + (&1.stargazers_count || 0)))) |> put_org_languages() |> put_org_popularity() |> put_org_last_activity() diff --git a/lib/coophub/repos.ex b/lib/coophub/repos.ex index 6c9b214..d51fe58 100644 --- a/lib/coophub/repos.ex +++ b/lib/coophub/repos.ex @@ -3,7 +3,7 @@ defmodule Coophub.Repos do alias Coophub.Schemas.{Organization, Repository} - @repos_cache_name Application.get_env(:coophub, :main_cache_name) + @repos_cache_name Application.compile_env(:coophub, :main_cache_name) @forks_factor 1.7 @stargazers_factor 1.5 @open_issues_factor 0.3 diff --git a/lib/coophub/schemas/organization.ex b/lib/coophub/schemas/organization.ex index db8d631..ad39b78 100644 --- a/lib/coophub/schemas/organization.ex +++ b/lib/coophub/schemas/organization.ex @@ -25,6 +25,7 @@ defmodule Coophub.Schemas.Organization do is_verified: boolean(), repos_url: String.t(), repo_count: integer(), + star_count: integer(), popularity: float(), followers: integer(), repos: [Coophub.Schemas.Repository.t()], @@ -54,6 +55,7 @@ defmodule Coophub.Schemas.Organization do :is_verified, :repos_url, :repo_count, + :star_count, :popularity, :followers, :repos, diff --git a/lib/coophub_web/controllers/repo_controller.ex b/lib/coophub_web/controllers/repo_controller.ex index c2f3eb0..816a277 100644 --- a/lib/coophub_web/controllers/repo_controller.ex +++ b/lib/coophub_web/controllers/repo_controller.ex @@ -3,7 +3,7 @@ defmodule CoophubWeb.RepoController do require Logger - @uris_cache_name Application.get_env(:coophub, :uris_cache_name) + @uris_cache_name Application.compile_env(:coophub, :uris_cache_name) @uris_cache_success [:ok, :commit, :ignore] action_fallback(CoophubWeb.FallbackController) diff --git a/mix.exs b/mix.exs index 2061ab7..bdecae0 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule Coophub.MixProject do [ app: :coophub, version: File.read!("VERSION"), - elixir: "~> 1.12", + elixir: "~> 1.14", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix, :gettext] ++ Mix.compilers(), start_permanent: Mix.env() == :prod, diff --git a/test/coophub_web/controllers/repo_controller_test.exs b/test/coophub_web/controllers/repo_controller_test.exs index 766eeff..e9f5136 100644 --- a/test/coophub_web/controllers/repo_controller_test.exs +++ b/test/coophub_web/controllers/repo_controller_test.exs @@ -45,6 +45,8 @@ defmodule CoophubWeb.RepoControllerTest do data = get_data(conn, :org, "fiqus") assert data["id"] == 1_891_317 assert data["email"] == "info@fiqus.coop" + assert data["repo_count"] == 2 + assert data["star_count"] == 22 assert length(data["languages"]) == 5 end @@ -52,6 +54,8 @@ defmodule CoophubWeb.RepoControllerTest do data = get_data(conn, :org, "test") assert data["id"] == 123 assert data["email"] == "info@test.coop" + assert data["repo_count"] == 3 + assert data["star_count"] == 33 assert length(data["languages"]) == 4 end diff --git a/test/support/fixtures.ex b/test/support/fixtures.ex index 59ef837..25ef0df 100644 --- a/test/support/fixtures.ex +++ b/test/support/fixtures.ex @@ -19,6 +19,7 @@ defmodule CoophubWeb.Fixtures do Repos.to_struct(Organization, %{ "repos" => generate_repos(:fiqus), "repo_count" => 2, + "star_count" => 22, "languages" => generate_languages(:surgex), "login" => "fiqus", "id" => 1_891_317, @@ -54,6 +55,7 @@ defmodule CoophubWeb.Fixtures do Repos.to_struct(Organization, %{ "repos" => generate_repos(:test), "repo_count" => 3, + "star_count" => 33, "languages" => generate_languages(:testone), "login" => "test", "id" => 123,