luftfartsverket / reqstool-client

Reqstool is a tool for managing requirements with related software verification cases (aka tests) and verification results (test results)
https://luftfartsverket.github.io/reqstool-client/
MIT License
3 stars 0 forks source link

Create plugin/hook for a Typescript (npm) version of Maven Artifact Zip Directory Structure and upload to npm registry #111

Open jimisola opened 1 month ago

jimisola commented 1 month ago

In addition to providing decorators for Typescript and creating the file annotations.yml the Typescript (npm) ecosystem also needs to create a package similar to Maven Artifact Zip Directory Structure but for npm repositories.

The file structure is laid out in the documentation, but it has to be investigated on how this can be adapted to npm.

Potential options are (option 2 is the way we do with Java/Maven and seems a lot easier to implement):

Option 1. Include the Zip Archive Inside the npm Package

Here the ideal would be for a reqstool.zip to be included in the npm package but excluded from being placed in node_modules during npm nstall. Whether this can be done is unclear to me as of now and something that has to be tested.

Can you for example use: and npm install will only install files under dist?

{
  "name": "your-package",
  "version": "1.0.0",
  "files": [
    "dist/",
    "archives/reqstool.zip"
  ]
}

Option 2. Publish as a Separate npm Package (i.e. your-package-reqstool)

{
  "name": "your-package-reqstool",
  "version": "1.0.0",
  "description": "Reqstool for your package",
  "files": [
    "reqstool.zip"
  ]
}
jimisola commented 1 month ago

See here for npm hooks: https://docs.npmjs.com/cli/v10/using-npm/scripts

For option 2, ChatGPT gives a hint:

Creating a Custom npm Plugin for Secondary Package Tarball

To create a solution that operates like a Maven plugin for npm, allowing the automatic generation and publishing of a secondary package tarball (with the -reqstool suffix) during the npm publish process without relying on local scripts, you can create a custom npm package that acts as a hook or plugin. This package can be specified as a dependency in the main project.

Steps to Create a Custom npm Plugin for Your Use Case

  1. Create the Plugin Package:

    • Create a new npm package that will handle the creation and publishing of the secondary package tarball.
    • Structure it like a typical npm package, including a package.json file.
  2. Implement the Hook:

    • Use the npm publish hook to trigger the generation of the -reqstool tarball when the primary package is published.
  3. Include Logic for Tarball Creation:

    • Implement the logic to create the secondary tarball with the reqstool.zip file and publish it.
  4. Publish the Plugin:

    • Publish this package to the npm registry.
  5. Configure the Main Project:

    • In your main project, specify this custom plugin as a dependency in package.json.

Example Implementation

Step 1: Create the Plugin Package

  1. Create a new directory for your plugin and initialize it as a new npm package:

    mkdir npm-reqstool-plugin
    cd npm-reqstool-plugin
    npm init -y
  2. Install the required dependencies, such as npm and tar, for handling package operations:

    npm install npm tar
  3. Create an entry file, e.g., index.js, for your plugin.

Step 2: Implement the Hook

In your index.js, implement a function that listens for the prepublishOnly hook and generates the -reqstool tarball.

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const tar = require('tar');

// Function to create and publish the reqstool package
const createAndPublishReqstoolPackage = () => {
  const packageJson = require(path.resolve(process.cwd(), 'package.json'));
  const packageName = packageJson.name;
  const version = packageJson.version;

  // Define the reqstool package name
  const reqstoolPackageName = \`\${packageName}-reqstool\`;
  const reqstoolOutputFile = \`\${reqstoolPackageName}-\${version}.tgz\`;
  const reqstoolDir = path.join(process.cwd(), 'dist'); // Change to your actual path where reqstool.zip is located

  console.log(\`Creating \${reqstoolOutputFile}...\`);

  // Ensure reqstool.zip exists
  if (!fs.existsSync(path.join(reqstoolDir, 'reqstool.zip'))) {
    console.error('Error: reqstool.zip not found in dist directory.');
    process.exit(1);
  }

  // Create the tarball
  tar.create(
    {
      gzip: true,
      file: reqstoolOutputFile,
      cwd: reqstoolDir,
    },
    ['reqstool.zip']
  );

  console.log(\`Successfully created \${reqstoolOutputFile}\`);

  // Publish the secondary package
  execSync(\`npm publish \${reqstoolOutputFile}\`, { stdio: 'inherit' });
};

// Hook into the prepublish lifecycle
module.exports = {
  hooks: {
    prepublishOnly: createAndPublishReqstoolPackage,
  },
};

Step 3: Publish the Plugin

  1. Publish your plugin to the npm registry:

    npm publish

Step 4: Configure the Main Project

In your main project, specify the plugin as a dependency in your package.json:

{
  "dependencies": {
    "npm-reqstool-plugin": "^1.0.0"
  }
}

How It Works

Considerations

Summary

This approach provides a clean and reusable way to automate the generation and publishing of a secondary package tarball within the npm ecosystem, similar to how Maven plugins work. It keeps the implementation within a dependency, ensuring ease of use and integration in different projects.

lfvjimisola commented 1 month ago

@lfvdavid Reminder for us to update the requirements.yml with support of pypi locations.