Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Streamline Generate #15

Merged
merged 17 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ inherit_from: .rubocop_todo.yml
require: rubocop-rspec

AllCops:
TargetRubyVersion: 3.0
NewCops: enable
TargetRubyVersion: 3.1

Style/StringLiterals:
EnforcedStyle: double_quotes
Expand Down
3 changes: 2 additions & 1 deletion lib/manifold.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# frozen_string_literal: true

require "json"
require "logger"
require "pathname"
require "thor"
require "yaml"

Dir[File.join(__dir__, "manifold", "**", "*.rb")].sort.each do |file|
Dir[File.join(__dir__, "manifold", "**", "*.rb")].each do |file|
require file
end

Expand Down
44 changes: 44 additions & 0 deletions lib/manifold/api/project.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

module Manifold
module API
# Projects API
class Project
attr_reader :name, :logger, :directory

def initialize(name, logger: Logger.new($stdout), directory: Pathname.pwd.join(name))
@name = name
@logger = logger
@directory = Pathname(directory)
end

def self.create(name, directory: Pathname.pwd.join(name))
new(name, directory:).tap do |project|
[project.workspaces_directory, project.vectors_directory].each(&:mkpath)
end
end

def workspaces
@workspaces ||= workspace_directories.map { |dir| Workspace.from_directory(dir, logger:) }
end

def generate
workspaces.each(&:generate)
end

def workspaces_directory
directory.join("workspaces")
end

def vectors_directory
directory.join("vectors")
end

private

def workspace_directories
workspaces_directory.children.select(&:directory?)
end
end
end
end
6 changes: 2 additions & 4 deletions lib/manifold/project/vector.rb → lib/manifold/api/vector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class Vector
).freeze

def initialize(name, template_path: DEFAULT_TEMPLATE_PATH)
self.name = name
self.template_path = Pathname(template_path)
@name = name
@template_path = Pathname(template_path)
end

def add
Expand All @@ -22,8 +22,6 @@ def add

private

attr_writer :name, :template_path

def directory
Pathname.pwd.join("vectors")
end
Expand Down
104 changes: 104 additions & 0 deletions lib/manifold/api/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# frozen_string_literal: true

module Manifold
module API
# Encapsulates a single manifold.
class Workspace
attr_reader :name, :template_path, :logger

DEFAULT_TEMPLATE_PATH = File.expand_path(
"../templates/workspace_template.yml", __dir__
).freeze

def initialize(name, template_path: DEFAULT_TEMPLATE_PATH, logger: Logger.new($stdout))
@name = name
@template_path = template_path
@logger = logger
@vector_service = Services::VectorService.new(logger)
end

def self.from_directory(directory, logger: Logger.new($stdout))
new(directory.basename.to_s, logger:)
end

def add
[tables_directory, routines_directory].each(&:mkpath)
FileUtils.cp(template_path, manifold_path)
end

def generate
return unless manifold_exists? && any_vectors?

generate_dimensions
logger.info("Generated BigQuery dimensions table schema for workspace '#{name}'.")
end

def tables_directory
directory.join("tables")
end

def routines_directory
directory.join("routines")
end

def manifold_file
return nil unless manifold_exists?

File.new(manifold_path)
end

def manifold_exists?
manifold_path.file?
end

def manifold_path
directory.join("manifold.yml")
end

private

def directory
Pathname.pwd.join("workspaces", name)
end

def manifold_yaml
@manifold_yaml ||= YAML.safe_load_file(manifold_path)
end

def generate_dimensions
dimensions_path.write(dimensions_schema_json.concat("\n"))
end

def dimensions_schema
[
{ "type" => "STRING", "name" => "id", "mode" => "REQUIRED" },
{ "type" => "RECORD", "name" => "dimensions", "mode" => "REQUIRED",
"fields" => dimensions_fields }
]
end

def dimensions_fields
vectors.filter_map do |vector|
logger.info("Loading vector schema for '#{vector}'.")
@vector_service.load_vector_schema(vector)
end
end

def dimensions_schema_json
JSON.pretty_generate(dimensions_schema)
end

def dimensions_path
tables_directory.join("dimensions.json")
end

def any_vectors?
!(vectors.nil? || vectors.empty?)
end

def vectors
manifold_yaml["vectors"]
end
end
end
end
18 changes: 7 additions & 11 deletions lib/manifold/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@ def initialize(*args, logger: Logger.new($stdout))

self.logger = logger
logger.level = Logger::INFO

self.bq_service = Services::BigQueryService.new(logger)
end

desc "init NAME", "Generate a new umbrella project for data management"
def init(name)
Manifold::API::Project.create(name)
logger.info "Created umbrella project '#{name}' with projects and vectors directories."
logger.info "Created umbrella project '#{name}' with workspaces and vectors directories."
end

desc "vectors SUBCOMMAND ...ARGS", "Manage vectors"
Expand Down Expand Up @@ -47,14 +45,12 @@ def add(name)
logger.info "Added workspace '#{name}' with tables and routines directories."
end

desc "generate PROJECT_NAME SERVICE", "Generate services for a project"
def generate(project_name, service)
case service
when "bq"
bq_service.generate_dimensions_schema(project_name)
else
logger.error("Unsupported service: #{service}")
end
desc "generate", "Generate BigQuery schema for all workspaces in the project"
def generate
name = Pathname.pwd.basename.to_s
project = API::Project.new(name, directory: Pathname.pwd, logger:)
project.generate
logger.info "Generated BigQuery schema for all workspaces in the project."
end
end
end
33 changes: 0 additions & 33 deletions lib/manifold/project/project.rb

This file was deleted.

54 changes: 0 additions & 54 deletions lib/manifold/project/workspace.rb

This file was deleted.

61 changes: 0 additions & 61 deletions lib/manifold/services/big_query_service.rb

This file was deleted.

Loading