Adds chmod action to POST /projects/:id/repository/commits API
With this action the user can update the execute_filemode of a given file in the repository.
This commit is contained in:
		
							parent
							
								
									a1529944e9
								
							
						
					
					
						commit
						271776d4aa
					
				| 
						 | 
					@ -1 +1 @@
 | 
				
			||||||
0.121.0
 | 
					0.122.0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module Files
 | 
					module Files
 | 
				
			||||||
  class MultiService < Files::BaseService
 | 
					  class MultiService < Files::BaseService
 | 
				
			||||||
    UPDATE_FILE_ACTIONS = %w(update move delete).freeze
 | 
					    UPDATE_FILE_ACTIONS = %w(update move delete chmod).freeze
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_commit!
 | 
					    def create_commit!
 | 
				
			||||||
      transformer = Lfs::FileTransformer.new(project, @branch_name)
 | 
					      transformer = Lfs::FileTransformer.new(project, @branch_name)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					title: Allows to chmod file with commits API
 | 
				
			||||||
 | 
					merge_request: 21866
 | 
				
			||||||
 | 
					author: Jacopo Beschi @jacopo-beschi
 | 
				
			||||||
 | 
					type: added
 | 
				
			||||||
| 
						 | 
					@ -83,12 +83,13 @@ POST /projects/:id/repository/commits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| `actions[]` Attribute | Type | Required | Description |
 | 
					| `actions[]` Attribute | Type | Required | Description |
 | 
				
			||||||
| --------------------- | ---- | -------- | ----------- |
 | 
					| --------------------- | ---- | -------- | ----------- |
 | 
				
			||||||
| `action` | string | yes | The action to perform, `create`, `delete`, `move`, `update` |
 | 
					| `action` | string | yes | The action to perform, `create`, `delete`, `move`, `update`, `chmod`|
 | 
				
			||||||
| `file_path` | string | yes | Full path to the file. Ex. `lib/class.rb` |
 | 
					| `file_path` | string | yes | Full path to the file. Ex. `lib/class.rb` |
 | 
				
			||||||
| `previous_path` | string | no | Original full path to the file being moved. Ex. `lib/class1.rb` |
 | 
					| `previous_path` | string | no | Original full path to the file being moved. Ex. `lib/class1.rb`. Only considered for `move` action. |
 | 
				
			||||||
| `content` | string | no | File content, required for all except `delete`. Optional for `move` |
 | 
					| `content` | string | no | File content, required for all except `delete` and `chmod`. Optional for `move` |
 | 
				
			||||||
| `encoding` | string | no | `text` or `base64`. `text` is default. |
 | 
					| `encoding` | string | no | `text` or `base64`. `text` is default. |
 | 
				
			||||||
| `last_commit_id` | string | no | Last known file commit id. Will be only considered in update, move and delete actions. |
 | 
					| `last_commit_id` | string | no | Last known file commit id. Will be only considered in update, move and delete actions. |
 | 
				
			||||||
 | 
					| `execute_filemode` | boolean | no | When `true/false` enables/disables the execute flag on the file. Only considered for `chmod` action. |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
PAYLOAD=$(cat << 'JSON'
 | 
					PAYLOAD=$(cat << 'JSON'
 | 
				
			||||||
| 
						 | 
					@ -115,6 +116,11 @@ PAYLOAD=$(cat << 'JSON'
 | 
				
			||||||
      "action": "update",
 | 
					      "action": "update",
 | 
				
			||||||
      "file_path": "foo/bar5",
 | 
					      "file_path": "foo/bar5",
 | 
				
			||||||
      "content": "new content"
 | 
					      "content": "new content"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "action": "chmod",
 | 
				
			||||||
 | 
					      "file_path": "foo/bar5",
 | 
				
			||||||
 | 
					      "execute_filemode": true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,26 @@ module API
 | 
				
			||||||
      params do
 | 
					      params do
 | 
				
			||||||
        requires :branch, type: String, desc: 'Name of the branch to commit into. To create a new branch, also provide `start_branch`.', allow_blank: false
 | 
					        requires :branch, type: String, desc: 'Name of the branch to commit into. To create a new branch, also provide `start_branch`.', allow_blank: false
 | 
				
			||||||
        requires :commit_message, type: String, desc: 'Commit message'
 | 
					        requires :commit_message, type: String, desc: 'Commit message'
 | 
				
			||||||
        requires :actions, type: Array[Hash], desc: 'Actions to perform in commit'
 | 
					        requires :actions, type: Array, desc: 'Actions to perform in commit' do
 | 
				
			||||||
 | 
					          requires :action, type: String, desc: 'The action to perform, `create`, `delete`, `move`, `update`, `chmod`', values: %w[create update move delete chmod].freeze
 | 
				
			||||||
 | 
					          requires :file_path, type: String, desc: 'Full path to the file. Ex. `lib/class.rb`'
 | 
				
			||||||
 | 
					          given action: ->(action) { action == 'move' } do
 | 
				
			||||||
 | 
					            requires :previous_path, type: String, desc: 'Original full path to the file being moved. Ex. `lib/class1.rb`'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					          given action: ->(action) { %w[create move].include? action } do
 | 
				
			||||||
 | 
					            optional :content, type: String, desc: 'File content'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					          given action: ->(action) { action == 'update' } do
 | 
				
			||||||
 | 
					            requires :content, type: String, desc: 'File content'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					          optional :encoding, type: String, desc: '`text` or `base64`', default: 'text', values: %w[text base64]
 | 
				
			||||||
 | 
					          given action: ->(action) { %w[update move delete].include? action } do
 | 
				
			||||||
 | 
					            optional :last_commit_id, type: String, desc: 'Last known file commit id'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					          given action: ->(action) { action == 'chmod' } do
 | 
				
			||||||
 | 
					            requires :execute_filemode, type: Boolean, desc: 'When `true/false` enables/disables the execute flag on the file.'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
        optional :start_branch, type: String, desc: 'Name of the branch to start the new commit from'
 | 
					        optional :start_branch, type: String, desc: 'Name of the branch to start the new commit from'
 | 
				
			||||||
        optional :author_email, type: String, desc: 'Author email for commit'
 | 
					        optional :author_email, type: String, desc: 'Author email for commit'
 | 
				
			||||||
        optional :author_name, type: String, desc: 'Author name for commit'
 | 
					        optional :author_name, type: String, desc: 'Author name for commit'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -333,7 +333,8 @@ module Gitlab
 | 
				
			||||||
          action: action[:action].upcase.to_sym,
 | 
					          action: action[:action].upcase.to_sym,
 | 
				
			||||||
          file_path: encode_binary(action[:file_path]),
 | 
					          file_path: encode_binary(action[:file_path]),
 | 
				
			||||||
          previous_path: encode_binary(action[:previous_path]),
 | 
					          previous_path: encode_binary(action[:previous_path]),
 | 
				
			||||||
          base64_content: action[:encoding] == 'base64'
 | 
					          base64_content: action[:encoding] == 'base64',
 | 
				
			||||||
 | 
					          execute_filemode: !!action[:execute_filemode]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
      rescue RangeError
 | 
					      rescue RangeError
 | 
				
			||||||
        raise ArgumentError, "Unknown action '#{action[:action]}'"
 | 
					        raise ArgumentError, "Unknown action '#{action[:action]}'"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,7 @@ describe API::Commits do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe 'create' do
 | 
					    describe 'create' do
 | 
				
			||||||
      let(:message) { 'Created file' }
 | 
					      let(:message) { 'Created file' }
 | 
				
			||||||
      let!(:invalid_c_params) do
 | 
					      let(:invalid_c_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'master',
 | 
					          branch: 'master',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -251,7 +251,7 @@ describe API::Commits do
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      let!(:valid_c_params) do
 | 
					      let(:valid_c_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'master',
 | 
					          branch: 'master',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -264,7 +264,7 @@ describe API::Commits do
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      let!(:valid_utf8_c_params) do
 | 
					      let(:valid_utf8_c_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'master',
 | 
					          branch: 'master',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -315,7 +315,7 @@ describe API::Commits do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe 'delete' do
 | 
					    describe 'delete' do
 | 
				
			||||||
      let(:message) { 'Deleted file' }
 | 
					      let(:message) { 'Deleted file' }
 | 
				
			||||||
      let!(:invalid_d_params) do
 | 
					      let(:invalid_d_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'markdown',
 | 
					          branch: 'markdown',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -327,7 +327,7 @@ describe API::Commits do
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      let!(:valid_d_params) do
 | 
					      let(:valid_d_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'markdown',
 | 
					          branch: 'markdown',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -356,7 +356,7 @@ describe API::Commits do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe 'move' do
 | 
					    describe 'move' do
 | 
				
			||||||
      let(:message) { 'Moved file' }
 | 
					      let(:message) { 'Moved file' }
 | 
				
			||||||
      let!(:invalid_m_params) do
 | 
					      let(:invalid_m_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'feature',
 | 
					          branch: 'feature',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -370,7 +370,7 @@ describe API::Commits do
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      let!(:valid_m_params) do
 | 
					      let(:valid_m_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'feature',
 | 
					          branch: 'feature',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -401,7 +401,7 @@ describe API::Commits do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe 'update' do
 | 
					    describe 'update' do
 | 
				
			||||||
      let(:message) { 'Updated file' }
 | 
					      let(:message) { 'Updated file' }
 | 
				
			||||||
      let!(:invalid_u_params) do
 | 
					      let(:invalid_u_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'master',
 | 
					          branch: 'master',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -414,7 +414,7 @@ describe API::Commits do
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      let!(:valid_u_params) do
 | 
					      let(:valid_u_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'master',
 | 
					          branch: 'master',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -442,9 +442,57 @@ describe API::Commits do
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe 'chmod' do
 | 
				
			||||||
 | 
					      let(:message) { 'Chmod +x file' }
 | 
				
			||||||
 | 
					      let(:file_path) { 'files/ruby/popen.rb' }
 | 
				
			||||||
 | 
					      let(:execute_filemode) { true }
 | 
				
			||||||
 | 
					      let(:params) do
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          branch: 'master',
 | 
				
			||||||
 | 
					          commit_message: message,
 | 
				
			||||||
 | 
					          actions: [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              action: 'chmod',
 | 
				
			||||||
 | 
					              file_path: file_path,
 | 
				
			||||||
 | 
					              execute_filemode: execute_filemode
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'responds with success' do
 | 
				
			||||||
 | 
					        post api(url, user), params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(response).to have_gitlab_http_status(201)
 | 
				
			||||||
 | 
					        expect(json_response['title']).to eq(message)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when execute_filemode is false' do
 | 
				
			||||||
 | 
					        let(:execute_filemode) { false }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'responds with success' do
 | 
				
			||||||
 | 
					          post api(url, user), params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          expect(response).to have_gitlab_http_status(201)
 | 
				
			||||||
 | 
					          expect(json_response['title']).to eq(message)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context "when the file doesn't exists" do
 | 
				
			||||||
 | 
					        let(:file_path) { 'foo/bar.baz' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "responds with 400" do
 | 
				
			||||||
 | 
					          post api(url, user), params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          expect(response).to have_gitlab_http_status(400)
 | 
				
			||||||
 | 
					          expect(json_response['message']).to eq("A file with this name doesn't exist")
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe 'multiple operations' do
 | 
					    describe 'multiple operations' do
 | 
				
			||||||
      let(:message) { 'Multiple actions' }
 | 
					      let(:message) { 'Multiple actions' }
 | 
				
			||||||
      let!(:invalid_mo_params) do
 | 
					      let(:invalid_mo_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'master',
 | 
					          branch: 'master',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -468,11 +516,16 @@ describe API::Commits do
 | 
				
			||||||
              action: 'update',
 | 
					              action: 'update',
 | 
				
			||||||
              file_path: 'foo/bar.baz',
 | 
					              file_path: 'foo/bar.baz',
 | 
				
			||||||
              content: 'puts 8'
 | 
					              content: 'puts 8'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              action: 'chmod',
 | 
				
			||||||
 | 
					              file_path: 'files/ruby/popen.rb',
 | 
				
			||||||
 | 
					              execute_filemode: true
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      let!(:valid_mo_params) do
 | 
					      let(:valid_mo_params) do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          branch: 'master',
 | 
					          branch: 'master',
 | 
				
			||||||
          commit_message: message,
 | 
					          commit_message: message,
 | 
				
			||||||
| 
						 | 
					@ -496,6 +549,11 @@ describe API::Commits do
 | 
				
			||||||
              action: 'update',
 | 
					              action: 'update',
 | 
				
			||||||
              file_path: 'files/ruby/popen.rb',
 | 
					              file_path: 'files/ruby/popen.rb',
 | 
				
			||||||
              content: 'puts 8'
 | 
					              content: 'puts 8'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              action: 'chmod',
 | 
				
			||||||
 | 
					              file_path: 'files/ruby/popen.rb',
 | 
				
			||||||
 | 
					              execute_filemode: true
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ describe Files::MultiService do
 | 
				
			||||||
  let(:new_file_path) { 'files/ruby/popen.rb' }
 | 
					  let(:new_file_path) { 'files/ruby/popen.rb' }
 | 
				
			||||||
  let(:file_content) { 'New content' }
 | 
					  let(:file_content) { 'New content' }
 | 
				
			||||||
  let(:action) { 'update' }
 | 
					  let(:action) { 'update' }
 | 
				
			||||||
 | 
					  let(:commit_message) { 'Update File' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let!(:original_commit_id) do
 | 
					  let!(:original_commit_id) do
 | 
				
			||||||
    Gitlab::Git::Commit.last_for_path(project.repository, branch_name, original_file_path).sha
 | 
					    Gitlab::Git::Commit.last_for_path(project.repository, branch_name, original_file_path).sha
 | 
				
			||||||
| 
						 | 
					@ -30,7 +31,7 @@ describe Files::MultiService do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let(:commit_params) do
 | 
					  let(:commit_params) do
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      commit_message: "Update File",
 | 
					      commit_message: commit_message,
 | 
				
			||||||
      branch_name: branch_name,
 | 
					      branch_name: branch_name,
 | 
				
			||||||
      start_branch: branch_name,
 | 
					      start_branch: branch_name,
 | 
				
			||||||
      actions: actions
 | 
					      actions: actions
 | 
				
			||||||
| 
						 | 
					@ -84,6 +85,39 @@ describe Files::MultiService do
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe 'changing execute_filemode of a file' do
 | 
				
			||||||
 | 
					      let(:commit_message) { 'Chmod +x file' }
 | 
				
			||||||
 | 
					      let(:file_path) { original_file_path }
 | 
				
			||||||
 | 
					      let(:default_action) do
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          action: 'chmod',
 | 
				
			||||||
 | 
					          file_path: file_path,
 | 
				
			||||||
 | 
					          execute_filemode: true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'accepts the commit' do
 | 
				
			||||||
 | 
					        results = subject.execute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(results[:status]).to eq(:success)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'updates the execute_filemode of the file' do
 | 
				
			||||||
 | 
					        expect { subject.execute }.to change { repository.blob_at_branch(branch_name, file_path).mode }.from('100644').to('100755')
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context "when the file doesn't exists" do
 | 
				
			||||||
 | 
					        let(:file_path) { 'files/wrong_path.rb' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'rejects the commit' do
 | 
				
			||||||
 | 
					          results = subject.execute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          expect(results[:status]).to eq(:error)
 | 
				
			||||||
 | 
					          expect(results[:message]).to eq("A file with this name doesn't exist")
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'when moving a file' do
 | 
					    context 'when moving a file' do
 | 
				
			||||||
      let(:action) { 'move' }
 | 
					      let(:action) { 'move' }
 | 
				
			||||||
      let(:new_file_path) { 'files/ruby/new_popen.rb' }
 | 
					      let(:new_file_path) { 'files/ruby/new_popen.rb' }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue