Overview

A project - is a collection of packages, with their dependencies which could be released together as a versioned library.

Each project has a manifest file that contains the name of the project, its version, a list of dependencies with their versions, and other metadata. It is written in TOML format and has a standard name: project.toml. For any catalog asset, the system will determine if it’s part of the project by traversing its parent folder and looking for project.toml.

Its structure is described below.

The [general] section

The first section is [general].

[general]
name = "coginiti.co/foundation/retail"
description = "Provides a ready-to-use solution for retail organizations to perform data analysis on sales and customers data."
version = "1.7.5"

The only fields required by CoginitiScript are "name" and "version".

 

The name field

The project name is an identifier used to refer to the project. It is used when listed as a dependency in another project and when specifying an import path for project packages. We recommend a convention where it starts with a unique domain name to guarantee the global uniqueness of the project name and use "/" as a separator for additional namespacing.

For example, we could define a project name "coginiti.co/foundation/retail", where

  • coginiti.co - domain name of our organization
  • foundation - additional namespace we use to group all projects that relate to our foundation implementation
  • retail - the actual name of the project

When importing a package from this project we just have to add a relative path to the package after the project name. For our retail project, importing a “base/customer” package will look like the following:

#+import "coginiti.co/foundation/retail/base/customer"
                 \                                           / \                    /
                  +-------------+---------------+   +-----+----+
                                      |                                    |
                             project name              path to the package

This approach makes migration from the existing catalog easier since the import path could be preserved. For example, if you have an asset in the catalog with an import package from the “engineering/sample_data/sources” and now want to convert “sample_data” into the project, we could just give it the name "engineering/sample_data" and all the existing import paths to packages from this project will still work (assuming dependency on this project has been specified in the manifest file).

 

The version field

Specifies the version of the project. Coginiti recommends following Semantic Versioning, where the version is specified in the “major.minor.path” format. When incrementing a version user has to follow the following basic rules:

  • Increment major version when breaking changes are introduced. For example: changes to the public API.
  • Increment minor version when new features are added without breaking changes.
  • Increment path version for any bug fixes releases.

The description field

The description is a short message about the project.

The [dependencies] section

CoginitiScript project could depend on other CoginitiScript projects from @Personal, @Shared workspaces, or from the Package Hub. These dependencies are specified within [dependencies] section.

Specifying dependencies from the Package Hub (coming soon)

Package Hub is a centralized repository where CoginitiScript projects could be published. To get a dependency from the hub user should specify its name and a version.

[dependencies]
"coginiti.co/foundation/retail" = { version = "1.7.5" }

There is a possibility to always reference a latest version from the Package Hub by using “latest” value.

[dependencies]
"coginiti.co/foundation/retail" = { version = "latest" }

Specifying path dependencies

One project could depend on the other, while they still leave in your catalog. In this case, CoginitiScript allows to specify dependencies using a path from the catalog.

[dependencies]
"coginiti.co/foundation/retail" = { path = "@Personal/My Projects/retail_foundation" }
[dependencies]
"coginiti.co/foundation/retail" = { path = "@Shared/retail_analytics" }

Import paths

There are several scenarios possible about how CoginitiScript packages could be imported into the current script:

  1. Importing CoginitiScript package from the current project
  2. Importing CoginitiScript package from the project which is used as a dependency
  3. Importing CoginitiScript package from the folder in the Catalog which is not part of the project.

Importing packages from the given project

CoginitiScript always uses an absolute path when importing packages from the given project or other projects. The project name is used as a suffix in the path.

For example, given the following project structure:

- sample_data
  - sales
     - sales_header
     - sales_details
  - reports
     - summary
  - project.toml

where project.toml is defined as

[general]
name = "coginiti.co/sample_data"
version = "1.0.0"

We could import “sales” package from the “reports/summary” by specifying the project name “coginiti.co/sample_data” as a suffix and then adding a path to the sales package as “/sales”:

#+import "coginiti.co/sample_data/sales"       -- importing package from the current project

SELECT
  sh.store_key,
  SUM(sd.unit_quantity * sd.price_amount) AS sales_amount
FROM
  {{ sales.Header() }} AS sh
INNER JOIN {{ sales.Details() }} AS sd
  ON sd.sales_header_key = sh.sales_header_key
GROUP BY
  sh.store_key
;

Importing packages from the project which is used as a dependency

To import a package from another project users have to add this project as a dependency into project.toml file and then import the package from it using a project import path:

project.toml file:

[general]
name = "coginiti.co/reports"
version = "1.0.0"

[dependencies]
"coginiti.co/foundation/retail" = { path = "@Personal/My Projects/retail_foundation" }

Import example:

#+import "coginiti.co/foundation/retail/mart"  -- importing "mart" package from the "coginiti.co/foundation/retail" project

SELECT
  store_group_name,
  district_name,
  market_area_name,
  market_region_name,
  SUM(f.sales_quantity * f.gross_sales_amount) AS sales_amount
FROM
  {{ mart.FactSalesReturn() }} AS f
INNER JOIN {{ mart.BusinessUnitDimension() }} AS l
  ON f.business_unit_key = l.business_unit_key
GROUP BY
  1, 2, 3, 4

Importing package from the folder that is not part of the project

It is still possible to import a package from the catalog which is not part of the project. To do it we have to specify an absolute catalog path to the package folder. This is allowed only for scripts which are not part of the project. Within the project, it is mandatory to specify explicit dependencies to other projects and then import packages from them.

#+import "@Personal/samples/data" -- importing "data" package from the folder within Personal namespace
#+import "@Legacy/sales"          -- importing "sales" package from the folder within Legacy namespace

Import from the tab, project, or asset

We believe what works in the non-saved tab should work the same way once the tab is saved into the catalog. It means that those imports should still work within catalog assets which is part of the project or not part of the project.

Based on this statement, we could formulate the following rules for each of the scenarios:

  1. Within the project you can import the following:
    • packages from legacy namespace
    • packages from projects published to the Package Hub (including the ability to pin version)
    • packages from projects located in the Personal or Shared namespaces (using path reference in the manifest file)
    • packages from the given project
  2. Outside of the project you can import:
    • packages from personal namespace
    • packages from legacy namespace
    • packages from projects published to the Package Hub. In this case always the latest version is referenced
  3. Within the empty tab
    • packages from personal namespace
    • packages from legacy namespace
    • packages from projects published to the Package Hub. In this case always the latest version is referenced

Whether the import from legacy namespace is used outside of the legacy namespace Coginiti application will output a warning to the console saying that this way is deprecated and we gonna turn it off at some date. Users should consider removing such imports and move to the project-based imports.

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request