From d23c2e8daa92d1261a0dc59b131a475d397fc7f6 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sat, 27 Jan 2024 10:58:59 -0600 Subject: [PATCH] Adds a base model for shared behavior --- lib/linear/models/base_model.rb | 62 +++++++++++++++++++++++++++++++++ lib/linear/models/issue.rb | 51 ++++----------------------- lib/linear/models/user.rb | 21 ++++------- 3 files changed, 75 insertions(+), 59 deletions(-) create mode 100644 lib/linear/models/base_model.rb diff --git a/lib/linear/models/base_model.rb b/lib/linear/models/base_model.rb new file mode 100644 index 0000000..0f027c6 --- /dev/null +++ b/lib/linear/models/base_model.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'gqli' +require 'semantic_logger' + +module Rubyists + module Linear + # Module which provides a base model for Linear models. + class BaseModel + extend GQLi::DSL + include GQLi::DSL + include SemanticLogger::Loggable + + def self.included(klass) + klass.extend ClassMethods + end + + # Class methods for Linear models. + module ClassMethods + def allq(filter: nil, limit: 50, after: nil) # rubocop:disable Metrics/MethodLength + args = { first: limit } + args[:filter] = filter ? BASIC_FILTER.merge(filter) : BASIC_FILTER + args[:after] = after if after + query do + subject(args) do + edges do + node { ___ Base } + cursor + end + ___ Fragments::PageInfo + end + end + end + + def gql_query(filter: nil, after: nil) + Api.query(allq(filter:, after:)) + end + + def all(edges: [], moar: true, after: nil, filter: nil, max: 100) + while moar + data = gql_query(filter:, after:) + subjects = data[PLURAL] + edges += subjects[:edges] + moar = false if edges.size >= max || !subjects[:pageInfo][:hasNextPage] + after = subjects[:pageInfo][:endCursor] + end + edges.map { |edge| new edge[:node] } + end + end + + attr_reader :data + + def initialize(data) + @data = data + end + + def to_json(*_args) + data.to_json + end + end + end +end diff --git a/lib/linear/models/issue.rb b/lib/linear/models/issue.rb index e464070..0c9e0ac 100644 --- a/lib/linear/models/issue.rb +++ b/lib/linear/models/issue.rb @@ -7,65 +7,28 @@ module Rubyists module Linear L :api L :fragments + M :base_model + M :user + Issue = Class.new(BaseModel) # The Issue class represents a Linear issue. class Issue - extend GQLi::DSL - include GQLi::DSL include SemanticLogger::Loggable + PLURAL = :issues BASIC_FILTER = { completedAt: { null: true } }.freeze Base = fragment('BaseIssue', 'Issue') do id identifier title + assignee { ___ User::Base } createdAt updatedAt end - def self.allq(filter: nil, limit: 50, after: nil) # rubocop:disable Metrics/MethodLength - args = { first: limit } - args[:filter] = filter ? BASIC_FILTER.merge(filter) : BASIC_FILTER - args[:after] = after if after - query do - issues(args) do - edges do - node { ___ Base } - cursor - end - ___ Fragments::PageInfo - end - end - end - - def self.issues_query(filter: nil, after: nil) - Api.query(allq(filter:, after:)) - end - - def self.all(edges: [], moar: true, after: nil, filter: nil, max: 100) - while moar - data = issues_query(filter:, after:) - issues = data[:issues] - edges += issues[:edges] - moar = false if edges.size >= max || !issues[:pageInfo][:hasNextPage] - after = issues[:pageInfo][:endCursor] - end - edges.map { |edge| new edge[:node] } - end - - attr_reader :issue - - def initialize(issue) - @issue = issue - end - - def to_json(*_args) - issue.to_json - end - def display - format = "%-10s %s\n" - printf format, issue[:identifier], issue[:title] + format = "%-10s %s (%s)\n" + printf format, data[:identifier], data[:title], data[:assignee][:name] end end end diff --git a/lib/linear/models/user.rb b/lib/linear/models/user.rb index bd9ac68..917eb5f 100644 --- a/lib/linear/models/user.rb +++ b/lib/linear/models/user.rb @@ -6,10 +6,11 @@ module Rubyists # Namespace for Linear module Linear L :api - # The Issue class represents a Linear issue. + M :base_model + M :issue + User = Class.new(BaseModel) + # The User class represents a Linear user. class User - extend GQLi::DSL - include GQLi::DSL include SemanticLogger::Loggable Base = fragment('BaseUser', 'User') do @@ -29,7 +30,7 @@ def self.me end def issue_query(first) - id = user[:id] + id = data[:id] query do user(id:) do assignedIssues(first:, filter: { completedAt: { null: true } }) do @@ -46,19 +47,9 @@ def issues(limit: 50) end end - attr_reader :user - - def initialize(user) - @user = user - end - - def to_json(*_args) - user.to_json - end - def display format = "%-20s: %s <%s>\n" - printf format, user[:id], user[:name], user[:email] + printf format, data[:id], data[:name], data[:email] end end end