Skip to content

Commit 8682e58

Browse files
authored
Bit of refactoring in Projects (#1105)
* fix name and id in Workspace and Project * tidy * remove log * changesets
1 parent 17e32d6 commit 8682e58

10 files changed

Lines changed: 64 additions & 81 deletions

File tree

.changeset/blue-mails-beam.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@openfn/engine-multi': patch
3+
---
4+
5+
Remove log line

.changeset/loud-cities-add.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@openfn/project': patch
3+
---
4+
5+
Internal refactor for clarity

packages/engine-multi/src/worker/thread/run.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ register({
8686
},
8787
},
8888
};
89-
logger.log(' >>', options.profile, options.profilePollInterval);
9089

9190
return execute(plan.id!, async () => {
9291
const start = Date.now();

packages/project/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@openfn/lexicon": "workspace:^",
3838
"@openfn/logger": "workspace:*",
3939
"glob": "^11.0.2",
40+
"human-id": "^4.1.1",
4041
"lodash": "^4.17.21",
4142
"lodash-es": "^4.17.21",
4243
"ohm-js": "^17.2.1",

packages/project/src/Project.ts

Lines changed: 18 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { humanId } from 'human-id';
12
import Workflow from './Workflow';
23
import * as serializers from './serialize';
34
import fromAppState, { FromAppStateConfig } from './parse/from-app-state';
@@ -19,47 +20,22 @@ type MergeOptions = {
1920
const maybeCreateWorkflow = (wf: any) =>
2021
wf instanceof Workflow ? wf : new Workflow(wf);
2122

22-
// TODO --------------
23-
// I think this needs renaming to config
24-
// and it's part of the workspace technically
25-
// I need to support custom props
26-
// When serializing, for now, we always write defaults
27-
// --------------
28-
// repo-wide options
29-
type RepoOptions = {
30-
/**default workflow root when serializing to fs (relative to openfn.yaml) */
31-
// TODO deprecate this
32-
workflowRoot?: string;
33-
34-
formats: {
35-
openfn: FileFormats;
36-
workflow: FileFormats;
37-
project: FileFormats;
38-
};
39-
};
40-
41-
// A local collection of openfn projects?
42-
// class Repo {
43-
44-
// projects: {}
45-
// }
46-
47-
// TODO maybe use an npm for this, or create util
48-
49-
// TODO this need to be controlled by the workspace
50-
5123
// A single openfn project
5224
// could be an app project or a checked out fs
5325
export class Project {
5426
// what schema version is this?
5527
// And how are we tracking this?
5628
// version;
5729

58-
/** project name */
30+
/** Human readable project name. This corresponds to the label in Lightning */
5931
name?: string;
32+
33+
/** Project id. Must be url safe. May be derived from the name. NOT a UUID */
34+
id: string;
35+
6036
description?: string;
6137

62-
// array of version shas
38+
// array of version hashes
6339
history: string[] = [];
6440

6541
workflows: Workflow[];
@@ -79,12 +55,6 @@ export class Project {
7955

8056
config: WorkspaceConfig;
8157

82-
// load a project from a state file (project.json)
83-
// or from a path (the file system)
84-
// TODO presumably we can detect a state file? Not a big deal?
85-
86-
// collections for the project
87-
// TODO to be well typed
8858
collections: any;
8959

9060
static from(
@@ -129,10 +99,16 @@ export class Project {
12999
// stuff that's external to the actual project and managed by the repo
130100

131101
// TODO maybe the constructor is (data, Workspace)
132-
constructor(data: l.Project, repoConfig: RepoOptions = {}) {
133-
this.setConfig(repoConfig);
102+
constructor(data: l.Project, config: RepoOptions = {}) {
103+
this.setConfig(config);
104+
105+
this.id =
106+
data.id ?? data.name
107+
? slugify(data.name)
108+
: humanId({ separator: '-', capitalize: false });
134109

135110
this.name = data.name;
111+
136112
this.description = data.description;
137113
this.openfn = data.openfn;
138114
this.options = data.options;
@@ -154,19 +130,12 @@ export class Project {
154130
throw new Error(`Cannot serialize ${type}`);
155131
}
156132

157-
// would like a better name for this
158-
// stamp? id? sha?
159-
// this builds a version string for the current state
160-
getVersionHash() {}
161-
162-
// what else might we need?
163-
164-
// get workflow by name or id
165-
// this is fuzzy, but is that wrong?
133+
// get workflow by name, id or uuid
166134
getWorkflow(idOrName: string) {
167135
return (
168136
this.workflows.find((wf) => wf.id == idOrName) ||
169-
this.workflows.find((wf) => wf.name === idOrName)
137+
this.workflows.find((wf) => wf.name === idOrName) ||
138+
this.workflows.find((wf) => wf.openfn?.uuid === idOrName)
170139
);
171140
}
172141

packages/project/src/Workspace.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const PROJECT_EXTENSIONS = ['.yaml', '.yml'];
1616

1717
export class Workspace {
1818
config?: WorkspaceConfig;
19-
projectMeta: ProjectMeta;
19+
activeProject: ProjectMeta;
2020

2121
private projects: Project[] = [];
2222
private projectPaths = new Map<string, string>();
@@ -26,7 +26,6 @@ export class Workspace {
2626
let context;
2727
try {
2828
const { type, content } = findWorkspaceFile(workspacePath);
29-
console.log(content);
3029
context = loadWorkspaceFile(content, type);
3130
this.isValid = true;
3231
} catch (e) {
@@ -36,7 +35,7 @@ export class Workspace {
3635
}
3736

3837
this.config = buildConfig(context.workspace);
39-
this.projectMeta = context.project;
38+
this.activeProject = context.project;
4039

4140
const projectsPath = path.join(workspacePath, this.config.dirs.projects);
4241

@@ -73,9 +72,12 @@ export class Workspace {
7372
return this.projects;
7473
}
7574

76-
// TODO clear up name/id confusion
75+
/** Get a project by its id or UUID */
7776
get(id: string) {
78-
return this.projects.find((p) => p.name === id);
77+
return (
78+
this.projects.find((p) => p.id === id) ??
79+
this.projects.find((p) => p.openfn?.uuid === id)
80+
);
7981
}
8082

8183
getProjectPath(id: string) {
@@ -84,7 +86,7 @@ export class Workspace {
8486

8587
getActiveProject() {
8688
// TODO should use id, not name
87-
return this.projects.find((p) => p.name === this.projectMeta?.name);
89+
return this.projects.find((p) => p.id === this.activeProject?.id);
8890
}
8991

9092
// TODO this needs to return default values
@@ -94,8 +96,7 @@ export class Workspace {
9496
}
9597

9698
get activeProjectId() {
97-
// TODO should return activeProject.id
98-
return this.projectMeta?.name;
99+
return this.activeProject?.id;
99100
}
100101

101102
get valid() {

packages/project/src/parse/from-fs.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const parseProject = async (options: FromFsConfig = {}) => {
5353
}
5454

5555
const proj = {
56+
name: state?.name,
5657
openfn: context.project,
5758
config: config,
5859
workflows: [],
@@ -81,7 +82,7 @@ export const parseProject = async (options: FromFsConfig = {}) => {
8182
const wfState = (state && state.getWorkflow(wf.id)) ?? {};
8283
wf.openfn = {
8384
uuid: wfState.openfn?.uuid ?? null,
84-
// TODO do we need to transfer more stuff?
85+
// TODO do we need to transfer more stuff? Options maybe?
8586
};
8687

8788
//console.log('Loading workflow at ', filePath); // TODO logger.debug

packages/project/src/util/config.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,10 @@ export const loadWorkspaceFile = (
146146
};
147147

148148
export const findWorkspaceFile = (dir: string = '.') => {
149-
console.log({ dir });
150149
let content, type;
151150
try {
152151
type = 'yaml';
153-
console.log(path.resolve(path.join(dir, 'openfn.yaml')));
154152
content = readFileSync(path.resolve(path.join(dir, 'openfn.yaml')), 'utf8');
155-
console.log({ content });
156153
} catch (e) {
157154
// Not found - try and parse as JSON
158155
try {

packages/project/test/workspace.test.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,28 @@ import test from 'ava';
55
// TODO need a test on the legacy and new yaml formats here
66
mock({
77
'/ws/openfn.yaml': jsonToYaml({
8-
name: 'some-project-name',
98
project: {
9+
id: 'project-1',
1010
uuid: '1234',
11-
name: 'some-project-name',
1211
},
13-
formats: {
14-
openfn: 'yaml',
15-
project: 'yaml',
16-
workflow: 'yaml',
17-
custom: true, // Note tha this will be excluded
12+
workspace: {
13+
formats: {
14+
openfn: 'yaml',
15+
project: 'yaml',
16+
workflow: 'yaml',
17+
custom: true, // Note that this will be excluded
18+
},
19+
// deliberately exclude dirs
20+
custom: true,
1821
},
19-
// deliberately exclude dirs
20-
custom: true,
2122
}),
2223
'/ws/.projects/staging@app.openfn.org.yaml': jsonToYaml({
23-
id: 'some-id',
24-
name: 'some-project-name',
24+
name: 'Project 1',
25+
id: '<uuid-1>',
2526
workflows: [
2627
{
27-
name: 'simple-workflow',
28-
id: 'wf-id',
28+
name: 'simple-workflow', // TODO clean up
29+
id: 'wf-id', // TODO clean up
2930
jobs: [
3031
{
3132
name: 'Transform data to FHIR standard',
@@ -97,18 +98,18 @@ test('workspace-list: list projects in the workspace', (t) => {
9798
const ws = new Workspace('/ws');
9899
t.is(ws.list().length, 1);
99100
t.deepEqual(
100-
ws.list().map((w) => w.name),
101-
['some-project-name']
101+
ws.list().map((w) => w.id),
102+
['project-1']
102103
);
103104
});
104105

105106
test('workspace-get: get projects in the workspace', (t) => {
106107
const ws = new Workspace('/ws');
107-
const found = ws.get('some-project-name');
108+
const found = ws.get('project-1');
108109
t.truthy(found);
109110
t.is(found?.workflows.length, 2);
110111
t.deepEqual(
111-
found?.workflows.map((w) => w.name),
112+
found?.workflows.map((w) => w.id),
112113
['simple-workflow', 'another-workflow']
113114
);
114115
});
@@ -131,8 +132,8 @@ test('load config', (t) => {
131132

132133
test('load project meta', (t) => {
133134
const ws = new Workspace('/ws');
134-
t.deepEqual(ws.projectMeta, {
135+
t.deepEqual(ws.activeProject, {
135136
uuid: '1234',
136-
name: 'some-project-name',
137+
id: 'project-1',
137138
});
138139
});

pnpm-lock.yaml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)