Introduce PipelineDescription

Add the PipelineDescription object that describes the structure of a
pipeline. This will be used by all the downstream users instead of
pipeline accessor methods via PipelineC.
This commit is contained in:
Giacomo Vercesi
2023-07-31 10:32:35 +02:00
committed by Alessandro Di Federico
parent 6b6bfd2693
commit 2a239ddf47
23 changed files with 689 additions and 25 deletions
@@ -0,0 +1,32 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: AnalysesList
doc: Data structure representing a list of analyses
type: struct
fields:
- name: Name
doc: AnalysesList's name
type: string
- name: Analyses
doc: AnalysesList's list of analyses
sequence:
type: SortedVector
elementType: AnalysisReference
key:
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/AnalysesList.h"
class pipeline::description::AnalysesList
: public pipeline::description::generated::AnalysesList {
public:
using generated::AnalysesList::AnalysesList;
};
#include "revng/Pipeline/Description/Generated/Late/AnalysesList.h"
@@ -0,0 +1,37 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: Analysis
doc: Data structure representing an analysis
type: struct
fields:
- name: Name
doc: Analysis' name
type: string
- name: ContainerInputs
doc: Analysis' container inputs
sequence:
type: SortedVector
elementType: AnalysisContainerInput
- name: Options
doc: Analysis' options
sequence:
type: SortedVector
elementType: AnalysisOption
key:
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/Analysis.h"
class pipeline::description::Analysis
: public pipeline::description::generated::Analysis {
public:
using generated::Analysis::Analysis;
};
#include "revng/Pipeline/Description/Generated/Late/Analysis.h"
@@ -0,0 +1,32 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: AnalysisContainerInput
doc: Data structure representing an analysis' container input
type: struct
fields:
- name: Name
doc: AnalysisContainerInput' name
type: string
- name: AcceptableKinds
doc: Kinds accepted by the analysis
sequence:
type: SortedVector
elementType: string
key:
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/AnalysisContainerInput.h"
class pipeline::description::AnalysisContainerInput
: public pipeline::description::generated::AnalysisContainerInput {
public:
using generated::AnalysisContainerInput::AnalysisContainerInput;
};
#include "revng/Pipeline/Description/Generated/Late/AnalysisContainerInput.h"
@@ -0,0 +1,30 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: AnalysisOption
doc: Data structure representing an analysis' container input
type: struct
fields:
- name: Name
doc: AnalysisOption' name
type: string
- name: Type
doc: Type of the option
type: string
key:
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/AnalysisOption.h"
class pipeline::description::AnalysisOption
: public pipeline::description::generated::AnalysisOption {
public:
using generated::AnalysisOption::AnalysisOption;
};
#include "revng/Pipeline/Description/Generated/Late/AnalysisOption.h"
@@ -0,0 +1,31 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: AnalysisReference
doc: A reference to an analysis
type: struct
fields:
- name: Step
doc: The step where the analysis belongs to
type: string
- name: Name
doc: The name of the analysis
type: string
key:
- Step
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/AnalysisReference.h"
class pipeline::description::AnalysisReference
: public pipeline::description::generated::AnalysisReference {
public:
using generated::AnalysisReference::AnalysisReference;
};
#include "revng/Pipeline/Description/Generated/Late/AnalysisReference.h"
@@ -0,0 +1,39 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: Artifacts
doc: Data structure representing a Artifacts
type: struct
fields:
- name: Kind
doc: Artifacts's kind
type: string
optional: true
- name: Container
doc: Artifacts's container
type: string
optional: true
- name: SingleTargetFilename
doc: The Artifacts's filename to use for a single element
type: string
optional: true
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/Artifacts.h"
class pipeline::description::Artifacts
: public pipeline::description::generated::Artifacts {
public:
using generated::Artifacts::Artifacts;
bool isValid() {
return not(this->Container().empty() or this->Kind().empty()
or this->SingleTargetFilename().empty());
}
};
#include "revng/Pipeline/Description/Generated/Late/Artifacts.h"
@@ -0,0 +1,30 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: Container
doc: Data structure representing a Container
type: struct
fields:
- name: Name
doc: Container's name
type: string
- name: MIMEType
doc: Container's mime type
type: string
key:
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/Container.h"
class pipeline::description::Container
: public pipeline::description::generated::Container {
public:
using generated::Container::Container;
};
#include "revng/Pipeline/Description/Generated/Late/Container.h"
+46
View File
@@ -0,0 +1,46 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: Kind
doc: Data structure representing a Kind
type: struct
fields:
- name: Name
doc: Kind's name
type: string
- name: Rank
doc: Kind's rank
type: string
- name: Parent
doc: The Kind's parent (if present)
type: string
optional: true
- name: DefinedLocations
doc: List of locations that the Kind provides
sequence:
type: SortedVector
elementType: string
- name: PreferredKinds
doc: >
These are the kinds that should be looked into in order to find
definitions to locations that are not present in the current document
sequence:
type: SortedVector
elementType: string
key:
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/Kind.h"
class pipeline::description::Kind
: public pipeline::description::generated::Kind {
public:
using generated::Kind::Kind;
};
#include "revng/Pipeline/Description/Generated/Late/Kind.h"
@@ -0,0 +1,50 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: PipelineDescription
doc: Data structure representing the structure of the pipeline
type: struct
fields:
- name: AnalysesLists
doc: AnalysesLists available in the pipeline
sequence:
type: SortedVector
elementType: AnalysesList
- name: Globals
doc: List of Globals
sequence:
type: SortedVector
elementType: string
- name: Kinds
doc: Kinds
sequence:
type: SortedVector
elementType: Kind
- name: Ranks
doc: Ranks
sequence:
type: SortedVector
elementType: Rank
- name: Containers
sequence:
type: SortedVector
elementType: Container
- name: Steps
sequence:
type: SortedVector
elementType: Step
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/PipelineDescription.h"
class pipeline::description::PipelineDescription
: public pipeline::description::generated::PipelineDescription {
public:
using generated::PipelineDescription::PipelineDescription;
};
#include "revng/Pipeline/Description/Generated/Late/PipelineDescription.h"
+34
View File
@@ -0,0 +1,34 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: Rank
doc: Data structure representing a Rank
type: struct
fields:
- name: Name
doc: Rank's name
type: string
- name: Depth
doc: Rank's depth
type: uint64_t
- name: Parent
doc: The Rank's parent (if present)
type: string
optional: true
key:
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/Rank.h"
class pipeline::description::Rank
: public pipeline::description::generated::Rank {
public:
using generated::Rank::Rank;
};
#include "revng/Pipeline/Description/Generated/Late/Rank.h"
+44
View File
@@ -0,0 +1,44 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
/* TUPLE-TREE-YAML
name: Step
doc: Data structure representing a Step
type: struct
fields:
- name: Name
doc: Step's name
type: string
- name: Component
doc: Step's component
type: string
optional: true
- name: Parent
doc: The Step's parent (if present)
type: string
optional: true
- name: Analyses
doc: List of Analyses that the Step provides
sequence:
type: SortedVector
elementType: Analysis
- name: Artifacts
doc: The artifacts that this step provides
type: Artifacts
optional: true
key:
- Name
TUPLE-TREE-YAML */
#include "revng/Pipeline/Description/Generated/Early/Step.h"
class pipeline::description::Step
: public pipeline::description::generated::Step {
public:
using generated::Step::Step;
};
#include "revng/Pipeline/Description/Generated/Late/Step.h"
+3
View File
@@ -15,6 +15,7 @@
#include "revng/Pipeline/AnalysesList.h"
#include "revng/Pipeline/ContainerFactorySet.h"
#include "revng/Pipeline/Description/PipelineDescription.h"
#include "revng/Pipeline/GlobalTupleTreeDiff.h"
#include "revng/Pipeline/KindsRegistry.h"
#include "revng/Pipeline/Step.h"
@@ -119,6 +120,8 @@ public:
AnalysesLists.try_emplace(Name, pipeline::AnalysesList(Name, Analyses));
}
pipeline::description::PipelineDescription description() const;
public:
/// Given a target, all occurrences of that target from every container in
/// every step will be registered in the returned invalidation map. The
+7
View File
@@ -152,6 +152,13 @@ public:
}
}
std::string getArtifactsContainerName() const {
if (!Artifacts.isValid())
return "";
else
return Artifacts.Container;
}
const ContainerSet::value_type *getArtifactsContainer() {
if (!Artifacts.isValid()) {
return nullptr;
+2
View File
@@ -44,6 +44,7 @@ private:
std::map<const pipeline::ContainerSet::value_type *,
const pipeline::TargetsList *>
ContainerToEnumeration;
std::string Description;
public:
PipelineManager(PipelineManager &&Other) = default;
@@ -194,5 +195,6 @@ public:
private:
llvm::Error produceAllPossibleTargets(bool ExpandTargets);
llvm::Error computeDescription();
};
} // namespace revng::pipes
+41
View File
@@ -8,6 +8,7 @@ revng_add_library_internal(
ContainerSet.cpp
Context.cpp
Contract.cpp
DescriptionConverter.cpp
Errors.cpp
GenericLLVMPipe.cpp
Kind.cpp
@@ -22,3 +23,43 @@ revng_add_library_internal(
GlobalsMap.cpp)
target_link_libraries(revngPipeline revngStorage revngSupport ${LLVM_LIBRARIES})
set(PIPELINEDESCRIPTION_HEADERS_DIR
"${CMAKE_SOURCE_DIR}/include/revng/Pipeline/Description")
set(PIPELINEDESCRIPTION_SCHEMA_PATH
"${CMAKE_BINARY_DIR}/pipelineDescription-schema.yml")
set(PIPELINEDESCRIPTION_JSONSCHEMA_PATH
"${CMAKE_BINARY_DIR}/pipelineDescription-jsonschema.yml")
set(PIPELINEDESCRIPTION_TYPESCRIPT_PATH
"${CMAKE_BINARY_DIR}/lib/typescript/pipeline-description.ts")
target_tuple_tree_generator(
revngPipeline
INSTALL
HEADER_DIRECTORY
Pipeline/Description
NAMESPACE
pipeline::description
SCHEMA_PATH
${PIPELINEDESCRIPTION_SCHEMA_PATH}
JSONSCHEMA_PATH
"${PIPELINEDESCRIPTION_JSONSCHEMA_PATH}"
PYTHON_PATH
"${CMAKE_BINARY_DIR}/${PYTHON_INSTALL_PATH}/revng/pipeline_description/_generated.py"
TYPESCRIPT_PATH
"${PIPELINEDESCRIPTION_TYPESCRIPT_PATH}"
ROOT_TYPE
PipelineDescription
GLOBAL_NAME
PipelineDescription
HEADERS
"${PIPELINEDESCRIPTION_HEADERS_DIR}/AnalysesList.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/AnalysisContainerInput.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/AnalysisOption.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/AnalysisReference.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/Analysis.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/Artifacts.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/Container.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/Kind.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/PipelineDescription.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/Rank.h"
"${PIPELINEDESCRIPTION_HEADERS_DIR}/Step.h")
+132
View File
@@ -0,0 +1,132 @@
/// \file DescriptionConverter.cpp
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include "revng/Pipeline/AnalysesList.h"
#include "revng/Pipeline/Analysis.h"
#include "revng/Pipeline/Description/PipelineDescription.h"
#include "revng/Pipeline/Runner.h"
#include "revng/Pipeline/Step.h"
static pipeline::description::Analysis
describe(const pipeline::AnalysisWrapper &Analysis) {
pipeline::description::Analysis Result;
Result.Name() = Analysis->getUserBoundName();
auto ContainerInputs = Analysis->getRunningContainersNames();
for (size_t I = 0; I < ContainerInputs.size(); I++) {
pipeline::description::AnalysisContainerInput Input;
Input.Name() = ContainerInputs[I];
for (auto &Kind : Analysis->getAcceptedKinds(I))
Input.AcceptableKinds().insert(Kind->name().str());
Result.ContainerInputs().insert(Input);
}
std::vector<std::string> OptionNames = Analysis->getOptionsNames();
std::vector<std::string> OptionTypes = Analysis->getOptionsTypes();
for (size_t I = 0; I < OptionNames.size(); I++)
Result.Options().insert({ OptionNames[I], OptionTypes[I] });
return Result;
}
static pipeline::description::AnalysesList
describe(const pipeline::AnalysesList &List) {
pipeline::description::AnalysesList Result;
Result.Name() = List.getName();
for (auto &Analysis : List) {
Result.Analyses().insert({ Analysis.getAnalysisName().str(),
Analysis.getStepName().str() });
}
return Result;
}
static pipeline::description::Kind describe(const pipeline::Kind &Kind) {
pipeline::description::Kind Result;
Result.Name() = Kind.name();
Result.Rank() = Kind.rank().name();
if (const pipeline::Kind *Parent = Kind.parent(); Parent != nullptr)
Result.Parent() = Parent->name();
for (const pipeline::Rank *Rank : Kind.definedLocations())
Result.DefinedLocations().insert(Rank->name().str());
for (const pipeline::Kind *PrefKind : Kind.preferredKinds())
Result.PreferredKinds().insert(PrefKind->name().str());
return Result;
}
static pipeline::description::Rank describe(const pipeline::Rank &Rank) {
pipeline::description::Rank Result;
Result.Name() = Rank.name();
if (const pipeline::Rank *Parent = Rank.parent(); Parent != nullptr)
Result.Parent() = Parent->name();
Result.Depth() = Rank.depth();
return Result;
}
static pipeline::description::Step describe(const pipeline::Step &Step) {
pipeline::description::Step Result;
Result.Name() = Step.getName();
Result.Component() = Step.getComponent().str();
if (Step.hasPredecessor())
Result.Parent() = Step.getPredecessor().getName();
for (auto &[Name, RunnerAnalysis] : Step.analyses())
Result.Analyses().insert(describe(RunnerAnalysis));
if (const pipeline::Kind *Kind = Step.getArtifactsKind(); Kind != nullptr) {
pipeline::description::Artifacts Artifacts;
Artifacts.Kind() = Kind->name();
Artifacts.Container() = Step.getArtifactsContainerName();
Artifacts.SingleTargetFilename() = Step.getArtifactsSingleTargetFilename();
Result.Artifacts() = Artifacts;
}
return Result;
}
pipeline::description::PipelineDescription
pipeline::Runner::description() const {
pipeline::description::PipelineDescription Result;
size_t ALCount = getAnalysesListCount();
for (size_t I = 0; I < ALCount; I++) {
const pipeline::AnalysesList &List = getAnalysesList(I);
Result.AnalysesLists().insert(describe(List));
}
const pipeline::GlobalsMap &GlobalsMap = getContext().getGlobals();
for (size_t I = 0; I < GlobalsMap.size(); I++)
Result.Globals().insert(GlobalsMap.getName(I).str());
for (pipeline::Kind &Kind : getKindsRegistry())
Result.Kinds().insert(describe(Kind));
for (pipeline::Rank *Rank : pipeline::Rank::getAll())
Result.Ranks().insert(describe(*Rank));
const auto &ContainerRegistry = getContainerFactorySet();
for (const auto &[Name, ContainerIdentifier] : ContainerRegistry) {
Result.Containers().insert({ Name.str(),
ContainerIdentifier.mimeType().str() });
}
for (auto &Step : *this)
Result.Steps().insert(describe(Step));
return Result;
}
+31
View File
@@ -173,6 +173,10 @@ PipelineManager::createFromMemory(llvm::ArrayRef<std::string> PipelineContent,
return MaybePipeline.takeError();
Manager.recalculateAllPossibleTargets();
if (auto Error = Manager.computeDescription(); Error)
return Error;
return std::move(Manager);
}
@@ -494,3 +498,30 @@ PipelineManager::produceTargets(const llvm::StringRef StepName,
const auto &ToFilter = Targets.at(TheContainer.second->name());
return TheContainer.second->cloneFiltered(ToFilter);
}
llvm::Error PipelineManager::computeDescription() {
using pipeline::description::PipelineDescription;
PipelineDescription Description = getRunner().description();
{
llvm::raw_string_ostream OS(this->Description);
yaml::Output YAMLOutput(OS);
YAMLOutput << Description;
}
if (StorageClient == nullptr)
return llvm::Error::success();
if (auto Error = ExecutionDirectory.create(); Error)
return Error;
constexpr auto DescriptionName = "pipeline-description.yml";
revng::FilePath DescriptionPath = ExecutionDirectory.getFile(DescriptionName);
auto MaybeWritableFile = DescriptionPath.getWritableFile();
if (!MaybeWritableFile)
return MaybeWritableFile.takeError();
MaybeWritableFile.get()->os() << this->Description;
return MaybeWritableFile.get()->commit();
}
+10 -1
View File
@@ -163,9 +163,18 @@ python_module(TARGET_NAME revng-python-daemon MODULE_FILES
${REVNG_DAEMON_MODULE_FILES})
#
# Install revng.daemon
# Install revng.support
#
set(REVNG_SUPPORT_MODULE_FILES revng/support/__init__.py revng/support/elf.py
revng/support/collect.py)
python_module(TARGET_NAME revng-python-support MODULE_FILES
${REVNG_SUPPORT_MODULE_FILES})
#
# Install revng.pipeline_description
#
set(PYTHON_PIPELINEDESCRIPTION_FILES revng/pipeline_description/__init__.py)
python_module(
TARGET_NAME python-pipeline-description MODULE_FILES
${PYTHON_PIPELINEDESCRIPTION_FILES} MODULE_GENERATED_FILES
revng/pipeline_description/_generated.py)
@@ -0,0 +1,5 @@
#
# This file is distributed under the MIT License. See LICENSE.md for details.
#
from ._generated import * # noqa: F401,F403
+28 -14
View File
@@ -17,23 +17,37 @@ add_custom_target(
"${CMAKE_BINARY_DIR}/node_build/package.json")
# Model package generation
add_custom_command(
OUTPUT "${CMAKE_BINARY_DIR}/model.ts.tgz"
"${CMAKE_BINARY_DIR}/lib/node_modules/revng-model/dist/model.js"
COMMAND
"${CMAKE_CURRENT_SOURCE_DIR}/build-model.sh" "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_BINARY_DIR}/node_build/node_modules"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
DEPENDS "${CMAKE_BINARY_DIR}/lib/typescript/model.ts")
function(typescript_module)
set(options)
set(oneValueArgs TARGET_NAME)
set(multiValueArgs)
cmake_parse_arguments(TYPESCRIPT_MODULE "${options}" "${oneValueArgs}"
"${multiValueArgs}" ${ARGN})
add_custom_target(generate-model.ts.tgz ALL
DEPENDS "${CMAKE_BINARY_DIR}/model.ts.tgz")
set(TARGET_NAME "${TYPESCRIPT_MODULE_TARGET_NAME}")
add_custom_command(
OUTPUT
"${CMAKE_BINARY_DIR}/${TARGET_NAME}.ts.tgz"
"${CMAKE_BINARY_DIR}/lib/node_modules/revng-model/dist/${TARGET_NAME}.js"
COMMAND
"${CMAKE_CURRENT_SOURCE_DIR}/build-tupletree.sh"
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_BINARY_DIR}/node_build/node_modules" "${TARGET_NAME}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
DEPENDS "${CMAKE_BINARY_DIR}/lib/typescript/${TARGET_NAME}.ts")
install(FILES "${CMAKE_BINARY_DIR}/model.ts.tgz"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/typescript")
add_custom_target("generate-${TARGET_NAME}.ts.tgz" ALL
DEPENDS "${CMAKE_BINARY_DIR}/${TARGET_NAME}.ts.tgz")
install(FILES "${CMAKE_BINARY_DIR}/model.ts.tgz"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/node_cache")
install(FILES "${CMAKE_BINARY_DIR}/${TARGET_NAME}.ts.tgz"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/typescript")
install(FILES "${CMAKE_BINARY_DIR}/${TARGET_NAME}.ts.tgz"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/node_cache")
endfunction()
typescript_module(TARGET_NAME model)
typescript_module(TARGET_NAME pipeline-description)
install(DIRECTORY "${CMAKE_BINARY_DIR}/lib/node_modules"
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
@@ -5,28 +5,29 @@
set -euo pipefail
rm -rf model.ts-package
PACKAGE_DIR="$3.ts-package"
rm -rf "$PACKAGE_DIR"
mkdir model.ts-package
BUILD_DIR="$(realpath model.ts-package)"
mkdir "$PACKAGE_DIR"
BUILD_DIR="$(realpath "$PACKAGE_DIR")"
function cleanup() {
trap - SIGINT SIGTERM ERR EXIT
rm -rf "$BUILD_DIR"
}
trap cleanup SIGINT SIGTERM ERR EXIT
cd model.ts-package
cd "$PACKAGE_DIR"
cp "$1/package-model.json" package.json
cp "$1/tsconfig-model.json" tsconfig.json
cp "$1/package-$3.json" package.json
cp "$1/tsconfig.json" tsconfig.json
cp "$1/tuple_tree.ts" tuple_tree.ts
cp ../lib/typescript/model.ts .
CHECKSUM=$(cat model.ts tuple_tree.ts | sha1sum - | cut -d' ' -f1)
cp ../lib/typescript/"$3".ts .
CHECKSUM=$(cat "$3.ts" "tuple_tree.ts" | sha1sum - | cut -d' ' -f1)
sed -i "s;##CHECKSUM##;$CHECKSUM;g" package.json
cp -rT "$2" node_modules
./node_modules/.bin/tsc -p .
npm pack --silent > /dev/null
cp revng-model-1.*.tgz ../model.ts.tgz
cp "revng-$3-1."*.tgz ../"$3".ts.tgz
cd ..
@@ -35,7 +36,7 @@ if test -e lib64/node_modules; then
exit 1
fi
npm --silent install --global --prefix=. ./model.ts.tgz
npm --silent install --global --prefix=. "./$3.ts.tgz"
# Handle npm implementations using lib64
if test -e lib64/node_modules; then
@@ -0,0 +1,14 @@
{
"license": "MIT",
"__license": "See LICENSE.md for details.",
"name": "revng-pipeline-description",
"version": "1.0.0-##CHECKSUM##",
"description": "revng pipeline-description",
"main": "dist/pipeline-description.js",
"types": "dist/pipeline-description.d.ts",
"files": ["/dist"],
"dependencies": {
"fast-equals": "^5",
"yaml": "^2"
}
}