Skip to content

Commit

Permalink
feat: ✨ Add yarn workspaces as project provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Hobart2967 committed Aug 14, 2024
1 parent 6615059 commit 31dfd45
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 14 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Skwid (`/skwɪd/`, like squid) is a tool wanting to be the command center of you
- [Using a self-configured list](#using-a-self-configured-list)
- [Using a 3rd-party managed project list](#using-a-3rd-party-managed-project-list)
- [Lerna](#lerna)
- [Yarn Workspaces](#yarn-workspaces)
- [Configuring skwid projects](#configuring-skwid-projects)
- [Adding variables](#adding-variables)
- [Configuring tasks](#configuring-tasks)
Expand Down Expand Up @@ -95,6 +96,18 @@ solution:
- type: lerna
```
#### Yarn Workspaces
```yaml
type: solution

solution:
name: My Software Project
sources:
- type: yarn-workspace
```
## Configuring skwid projects
**⚠️⚠️⚠️ For a Detailed documentation refer to the [Skwid Documentation](./docs/README.md)**
Expand Down
28 changes: 15 additions & 13 deletions projects/skwid/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
#!/usr/bin/env node
/// <reference path="./globals.d.ts" />
import 'reflect-metadata';
import * as path from 'path';
import * as fs from 'fs';
import * as yaml from 'yaml';

import { Container } from 'inversify';
import { Command } from 'commander';
import { InjectionTokens as GlobalInjectionTokens } from '@codewyre/skwid-contracts';
import { Command } from 'commander';
import * as fs from 'fs';
import { Container } from 'inversify';
import * as path from 'path';
import * as yaml from 'yaml';

import { SkwidTaskProcessor } from './services/skwid-task-processor';
import { CommanderFactory } from './services/commander-factory';
import { ConfigurationService } from './services/configuration.service';
import { ContextManagerService } from './services/context-manager.service';
import { Application } from './app/application';
import { InjectionTokens } from './configuration/injection-tokens.enum';
import { SkwidCommandJobHandler } from './job-handlers/skwid-command.job-handler';
import { SkwidDeclareJobHandler } from './job-handlers/skwid-declare.job-handler';
import { SkwidConditionJobHandler } from './job-handlers/skwid-condition.job-handler';
import { SkwidDeclareJobHandler } from './job-handlers/skwid-declare.job-handler';
import { SkwidRepeatJobHandler } from './job-handlers/skwid-repeat.job-handler';
import { InjectionTokens } from './configuration/injection-tokens.enum';
import { Application } from './app/application';
import { SkwidSolutionJobHandler } from './job-handlers/skwid-solution.job-handler';
import { SolutionManager } from './services/solution-manager';
import { SkwidProjectSourceProvider } from './models/skwid-project-source.provider';
import { CommanderFactory } from './services/commander-factory';
import { ConfigurationService } from './services/configuration.service';
import { ContextManagerService } from './services/context-manager.service';
import { FixedProjectProvider } from './services/fixed.project-provider';
import { LernaProjectProvider } from './services/lerna.project-provider';
import { SkwidTaskProcessor } from './services/skwid-task-processor';
import { SolutionManager } from './services/solution-manager';
import { YarnWorkspaceProjectProvider } from './services/yarn-workspace.project-provider';

function findPackageInfo(): any {
let possiblePath = __dirname;
Expand All @@ -50,6 +51,7 @@ const providers: Array<any> = [
{ provide: Command, useValue: new Command() },
{ provide: SkwidProjectSourceProvider, useClass: FixedProjectProvider },
{ provide: SkwidProjectSourceProvider, useClass: LernaProjectProvider },
{ provide: SkwidProjectSourceProvider, useClass: YarnWorkspaceProjectProvider },
{ provide: GlobalInjectionTokens.SkwidJobHandler, useClass: SkwidCommandJobHandler },
{ provide: GlobalInjectionTokens.SkwidJobHandler, useClass: SkwidDeclareJobHandler },
{ provide: GlobalInjectionTokens.SkwidJobHandler, useClass: SkwidConditionJobHandler },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum ProjectSourceType {
Lerna = 'lerna',
Fixed = 'fixed'
Fixed = 'fixed',
YarnWorkspace = 'yarn-workspace'
}
56 changes: 56 additions & 0 deletions projects/skwid/src/services/yarn-workspace.project-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { execSync } from 'child_process';
import { inject, injectable } from 'inversify';

import { InjectionTokens } from '../configuration/injection-tokens.enum';
import { ProjectSourceType } from '../models/configuration/project-source-type.enum';
import { SkwidConfiguration } from '../models/configuration/skwid-configuration.model';
import { FileSystemService } from '../models/node/file-system.service';
import { PathService } from '../models/node/path.service';
import { SkwidProjectSourceProvider } from '../models/skwid-project-source.provider';
import { SkwidProject } from '../models/skwid-project.model';
import { ConfigurationService } from './configuration.service';

interface LernaPackageInfo {
location: string;
name: string;
version: string;
private: boolean;
}

@injectable()
export class YarnWorkspaceProjectProvider extends SkwidProjectSourceProvider {
public get type(): string {
return ProjectSourceType.YarnWorkspace;
}

//#region Ctor
public constructor(
@inject(InjectionTokens.PathService) protected readonly _pathService: PathService,
@inject(InjectionTokens.FileSystemService) protected readonly _fileSystemService: FileSystemService,
@inject(ConfigurationService) protected readonly _configurationService: ConfigurationService) {
super(_pathService, _configurationService);
}
//#endregion

public async getProjects(configLocation: string, config: SkwidConfiguration): Promise<SkwidProject[]> {
const yarnBinary = 'yarn';
const packageInfos = this.loadProjectInfos(yarnBinary);

return Promise.all(
Object.values(packageInfos).map(({ location }) =>
this.parseProject(
configLocation,
location
)));
}

private loadProjectInfos(yarnBinary: string): LernaPackageInfo[] {
const lernaDeps = execSync(
`${yarnBinary} workspaces info`, {
stdio: []
})
.toString();

return JSON.parse(lernaDeps);
}
}

0 comments on commit 31dfd45

Please sign in to comment.