<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: OpenSCA Community</title>
    <description>The latest articles on DEV Community by OpenSCA Community (@opensca).</description>
    <link>https://dev.to/opensca</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1150469%2F0dd412ce-c52f-47fa-8cd7-0816c22eac57.png</url>
      <title>DEV Community: OpenSCA Community</title>
      <link>https://dev.to/opensca</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/opensca"/>
    <language>en</language>
    <item>
      <title>OpenSCA: Analysis of Composer Dependencies</title>
      <dc:creator>OpenSCA Community</dc:creator>
      <pubDate>Tue, 19 Sep 2023 02:46:19 +0000</pubDate>
      <link>https://dev.to/opensca/opensca-analysis-of-composer-dependencies-1go4</link>
      <guid>https://dev.to/opensca/opensca-analysis-of-composer-dependencies-1go4</guid>
      <description>&lt;p&gt;In this article, we will mainly introduce the principle of component composition parsing based on the Composer package manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Composer
&lt;/h2&gt;

&lt;p&gt;Composer is a dependency management tool for PHP.&lt;/p&gt;

&lt;p&gt;Inspired by NPM of Node.js and bundler of Ruby, the design of omposer  has many similarities with these two.&lt;/p&gt;

&lt;p&gt;The dependency management file for Composer is composer.json. Developers can specify the version range of each dependency in composer.json or use &lt;strong&gt;composer require /update /remove ${name}&lt;/strong&gt; command to manage dependencies.&lt;/p&gt;

&lt;p&gt;If there is a composer. json file in a project, you can execute the composer install command to automatically install the dependencies required for the current project and generate a composer. lock file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The complete file structure of composer. json is as follows:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{  
    "name": "cakephp/app",  
    "type": "project",  
    "license": "MIT",  
    "require": {      
          "php": "&amp;gt;=7.2",      
          "cakephp/cakephp": "^4.3",      
          "cakephp/migrations": "^3.2",      
          "cakephp/plugin-installer": "^1.3",      
          "mobiledetect/mobiledetectlib": "^2.8"  
           },  
     "require-dev": {     
           "cakephp/bake": "^2.6",      
           "cakephp/cakephp-codesniffer": "^4.5",      
           "cakephp/debug_kit": "^4.5",      
           "josegonzalez/dotenv": "^3.2",      
           "phpunit/phpunit": "~8.5.0 || ^9.3"  
           },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;strong&gt;name&lt;/strong&gt; is the project name. &lt;strong&gt;type&lt;/strong&gt; refers to the type of package, which includes four types: &lt;strong&gt;library, project, metapackage&lt;/strong&gt;, and &lt;strong&gt;composer-plugin&lt;/strong&gt; (library by default).  &lt;strong&gt;license&lt;/strong&gt; is the license declared by the project, which can be a string or an array of strings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;require-dev&lt;/strong&gt; refers to the dependency used in the development or testing environment, and &lt;strong&gt;require&lt;/strong&gt; refers to the dependency used in the production environment. The dependency is written as "name": "version", and the version can be specified as the exact version or a range.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analytical Algorithm
&lt;/h2&gt;

&lt;h3&gt;
  
  
  composer.lock
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;composer. lock&lt;/em&gt; is an automatically generated file that can accurately locate the dependencies and versions used in PHP projects, so the priority is given to analyze  the &lt;em&gt;composer. lock&lt;/em&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structure of composer.lock is as follows：&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{  
     "packages": [    
          {      
              "name": "a",      
              "version": "1.1.0",      
              "require": {          
                   "c": "1.1.*"      
                    }    
          },    
          {      
              "name": "b",      
              "version": "1.2.2",      
              "require": {          
                   "c": "^1.0.2"     
                    }    
          },    
          {       
              "name": "c",      
              "version": "1.1.2"    
                    }  
     ],  
     "packages-dev": []
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;packages&lt;/strong&gt; and &lt;strong&gt;packages-dev&lt;/strong&gt; fields contain all direct and indirect dependencies used by the project, and record the dependencies between components. &lt;strong&gt;packages&lt;/strong&gt; represent the dependencies of the production environment, and &lt;strong&gt;packages-dev&lt;/strong&gt; represent the dependencies of the development environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example：&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{  
    "name": "a",  
    "version": "1.1.0",  
    "require": {      
         "c": "1.1.*"  
     }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;● The project depends on component a  in version 1.1.0, which depends on component c  constrained to version 1.1. *.&lt;br&gt;
● Similarly, it can be seen that the project depends on component b in version 1.2.2, and this component depends on component c with a version constraint of ^ 1.0.2.&lt;br&gt;
● Moreover, neither component a nor component b is depended  by any other dependencies. So both components are direct dependencies of the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;1.1. * represents  the versions in [1.1.0, 1.2.0) &lt;/li&gt;
&lt;li&gt;^ 1.0.2 represents the versions in [1.0.2, 2.0.0) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;From this, the dependency structure of the current project can be constructed：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XMigp4bf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xi3azkdbylh6f7vk8twv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XMigp4bf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xi3azkdbylh6f7vk8twv.png" alt="Solid lines represent direct dependencies &amp;amp; dashed lines represent indirect dependencies" width="518" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZbZAbAyn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8v9zqfdf06ycwbiwz6z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZbZAbAyn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8v9zqfdf06ycwbiwz6z.png" alt="Figure: Example of composer.lock detection results" width="742" height="308"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  composer.json
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;composer.json&lt;/em&gt;  is a dependency management file managed by developers, which will be parsed when the  &lt;em&gt;composer.lock&lt;/em&gt;  file cannot be found.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;composer.json&lt;/em&gt; only contains direct dependencies. During project construction, the required indirect dependencies will be downloaded from the composer repository and built into a &lt;em&gt;composer.lock&lt;/em&gt; file. Therefore, the component dependencies of the project can be analyzed by simulating the composer construction process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structure of composer.json  is as follows：&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{  
    "name": "foo",  
    "type": "project",  
    "license": "MIT",  
    "require": {
        "a": "^1.1.0",
        "b": "^1.2.0",  
     },  
    "require-dev": {},
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;require&lt;/strong&gt; is the direct dependency actually used in the project, and &lt;strong&gt;require-dev&lt;/strong&gt; is the direct dependency used during project development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;''a'': ''^ 1.1.0'' represents component a with a dependency version constraint of ^1.1.0.&lt;br&gt;
''b'': ''^ 1.2.0'' represents component b with a dependency version constraint of ^1.2.0.&lt;/p&gt;

&lt;p&gt;At this point of analysis, we can summarize the dependency relationship as shown in the following figure：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZR86TYng--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4hwc3f1xz42eutrgi59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZR86TYng--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4hwc3f1xz42eutrgi59.png" alt="Solid lines represent direct dependencies" width="471" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Through this dependency relationship, direct dependencies and the version range of the components are visible, but the specific version of the dependency cannot be determined.&lt;/p&gt;

&lt;p&gt;In the absence of a &lt;em&gt;composer.lock&lt;/em&gt; file, in order to further obtain accurate versions of dependencies and indirect dependencies, it is necessary to download detailed information of the corresponding components from the composer repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example, the detailed information structure of component a is：&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "packages": {
    "a": [
      {
        "version": "1.0.1",
        "require": {
        "c": "^1.0.0"
        }
      }, 
      { 
         "version": "1.1.0", 
         "require": { 
         "c": "^1.1.0" 
          }      
      }    
     ]  
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;packages&lt;/strong&gt; field represents the mapping of component and version information, while the &lt;strong&gt;require&lt;/strong&gt; field represents the dependency information of the component.&lt;/p&gt;

&lt;p&gt;For this example, the constraint for component a is ^1.1.0, which requires a version in [1.1.0, 2.0.0), so version 1.1.0 is chosen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Therefore, the component dependency structure becomes：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OtbQ2Biq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6kyqsq2yfty5l3lfye3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OtbQ2Biq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6kyqsq2yfty5l3lfye3.png" alt="Image description" width="458" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By hierarchical analyzing in this way, the dependency information of the entire project can be obtained.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8R4FsSt8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2s276eacee62983ip6qh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8R4FsSt8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2s276eacee62983ip6qh.png" alt="Figure: Example of composer.json detection results" width="742" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
